Index: boot/freeldr/bootsect/fatx.S =================================================================== --- boot/freeldr/bootsect/fatx.S (revision 66079) +++ boot/freeldr/bootsect/fatx.S (working copy) @@ -7,6 +7,7 @@ * Timo Kreuzer */ +#define DISKREADBUFFER HEX(8E000) /* * Layout of a FAT volume: Index: boot/freeldr/freeldr/arch/i386/hardware.c =================================================================== --- boot/freeldr/freeldr/arch/i386/hardware.c (revision 66079) +++ boot/freeldr/freeldr/arch/i386/hardware.c (working copy) @@ -307,10 +307,10 @@ { NodeNumber = (UCHAR)i; - x = PnpBiosGetDeviceNode(&NodeNumber, (PVOID)DISKREADBUFFER); + x = PnpBiosGetDeviceNode(&NodeNumber, DiskReadBuffer); if (x == 0) { - DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DISKREADBUFFER; + DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DiskReadBuffer; TRACE("Node: %u Size %u (0x%x)\n", DeviceNode->Node, Index: boot/freeldr/freeldr/arch/i386/hwdisk.c =================================================================== --- boot/freeldr/freeldr/arch/i386/hwdisk.c (revision 66079) +++ boot/freeldr/freeldr/arch/i386/hwdisk.c (working copy) @@ -42,6 +42,8 @@ static CHAR Hex[] = "0123456789abcdef"; UCHAR PcBiosDiskCount = 0; CHAR PcDiskIdentifier[32][20]; +PVOID DiskReadBuffer; +SIZE_T DiskReadBufferSize; static ARC_STATUS DiskClose(ULONG FileId) @@ -119,7 +121,7 @@ ULONGLONG SectorOffset; TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize; - MaxSectors = PcDiskReadBufferSize / Context->SectorSize; + MaxSectors = DiskReadBufferSize / Context->SectorSize; SectorOffset = Context->SectorNumber + Context->SectorOffset; ret = 1; @@ -134,7 +136,7 @@ Context->DriveNumber, SectorOffset, ReadSectors, - (PVOID)DISKREADBUFFER); + DiskReadBuffer); if (!ret) break; @@ -142,7 +144,7 @@ if (Length > N) Length = N; - RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length); + RtlCopyMemory(Ptr, DiskReadBuffer, Length); Ptr += Length; N -= Length; @@ -197,14 +199,14 @@ PCHAR Identifier = PcDiskIdentifier[DriveNumber - 0x80]; /* Read the MBR */ - if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER)) + if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer)) { ERR("Reading MBR failed\n"); return; } - Buffer = (ULONG*)DISKREADBUFFER; - Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER; + Buffer = (ULONG*)DiskReadBuffer; + Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer; Signature = Mbr->Signature; TRACE("Signature: %x\n", Signature); @@ -288,13 +290,13 @@ * harddisks. So, we set the buffer to known contents first, then try to * read. If the BIOS reports success but the buffer contents haven't * changed then we fail anyway */ - memset((PVOID) DISKREADBUFFER, 0xcd, 512); - while (MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER)) + memset(DiskReadBuffer, 0xcd, 512); + while (MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer)) { Changed = FALSE; for (i = 0; ! Changed && i < 512; i++) { - Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd; + Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd; } if (! Changed) { @@ -310,7 +312,7 @@ DiskCount++; DriveNumber++; - memset((PVOID) DISKREADBUFFER, 0xcd, 512); + memset(DiskReadBuffer, 0xcd, 512); } DiskReportError(TRUE); @@ -326,13 +328,13 @@ ULONG Checksum = 0; /* Read the MBR */ - if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, (PVOID)DISKREADBUFFER)) + if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, DiskReadBuffer)) { ERR("Reading MBR failed\n"); return FALSE; } - Buffer = (ULONG*)DISKREADBUFFER; + Buffer = (ULONG*)DiskReadBuffer; /* Calculate the MBR checksum */ for (i = 0; i < 2048 / sizeof(ULONG); i++) Checksum += Buffer[i]; Index: boot/freeldr/freeldr/arch/i386/pcmem.c =================================================================== --- boot/freeldr/freeldr/arch/i386/pcmem.c (revision 66079) +++ boot/freeldr/freeldr/arch/i386/pcmem.c (working copy) @@ -29,32 +29,11 @@ #define MAX_BIOS_DESCRIPTORS 32 -#define STACK_BASE_PAGE (STACKLOW / PAGE_SIZE) -#define FREELDR_BASE_PAGE (FREELDR_BASE / PAGE_SIZE) -#define DISKBUF_BASE_PAGE (DISKREADBUFFER / PAGE_SIZE) - -#define STACK_PAGE_COUNT (FREELDR_BASE_PAGE - STACK_BASE_PAGE) -#define FREELDR_PAGE_COUNT (DISKBUF_BASE_PAGE - FREELDR_BASE_PAGE) -#define DISKBUF_PAGE_COUNT (0x10) -#define BIOSBUF_PAGE_COUNT (1) - BIOS_MEMORY_MAP PcBiosMemoryMap[MAX_BIOS_DESCRIPTORS]; ULONG PcBiosMapCount; -ULONG PcDiskReadBufferSize; -FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1] = -{ - { LoaderFirmwarePermanent, 0x00, 1 }, // realmode int vectors - { LoaderFirmwareTemporary, 0x01, STACK_BASE_PAGE - 1 }, // freeldr stack, cmdline, BIOS call buffer - { LoaderOsloaderStack, STACK_BASE_PAGE, FREELDR_BASE_PAGE - STACK_BASE_PAGE }, // prot mode stack. - { LoaderLoadedProgram, FREELDR_BASE_PAGE, FREELDR_PAGE_COUNT }, // freeldr image - { LoaderFirmwareTemporary, DISKBUF_BASE_PAGE, DISKBUF_PAGE_COUNT }, // Disk read buffer for int 13h. DISKREADBUFFER - { LoaderFirmwarePermanent, 0x9F, 0x1 }, // EBDA - { LoaderFirmwarePermanent, 0xA0, 0x50 }, // ROM / Video - { LoaderSpecialMemory, 0xF0, 0x10 }, // ROM / Video - { LoaderSpecialMemory, 0xFFF, 1 }, // unusable memory - { 0, 0, 0 }, // end of map -}; +FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1]; +ULONG PcMapCount; ULONG AddMemoryDescriptor( @@ -186,12 +165,43 @@ } static +BOOLEAN +GetEbdaLocation( + PULONG BaseAddress, + PULONG Size) +{ + REGS Regs; + + /* Get the address of the Extended BIOS Data Area (EBDA). + * Int 15h, AH=C1h + * SYSTEM - RETURN EXTENDED-BIOS DATA-AREA SEGMENT ADDRESS (PS) + * + * Return: + * CF set on error + * CF clear if successful + * ES = segment of data area + */ + Regs.x.eax = 0x0000C100; + Int386(0x15, &Regs, &Regs); + + /* If the function fails, there is no EBDA */ + if (!INT386_SUCCESS(Regs)) + { + return FALSE; + } + + /* Get Base address and (maximum) size */ + *BaseAddress = (ULONG)Regs.w.es << 4; + *Size = 0xA0000 - *BaseAddress; + return TRUE; +} + +static ULONG PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSize) { REGS Regs; - ULONG MapCount = 0; - ULONGLONG RealBaseAddress, RealSize; + ULONGLONG RealBaseAddress, EndAddress, RealSize; TYPE_OF_MEMORY MemoryType; ULONG Size; ASSERT(PcBiosMapCount == 0); @@ -202,7 +212,7 @@ bit value at address 0x413 inside the BDA, which gives us the usable size in KB */ Size = (*(PUSHORT)(ULONG_PTR)0x413) * 1024; - if (Size < DISKREADBUFFER || Size - DISKREADBUFFER < MIN_DISKREADBUFFER_SIZE) + if (Size < MEMORY_MARGIN) { FrLdrBugCheckWithMessage( MEMORY_INIT_FAILURE, @@ -212,57 +222,8 @@ "If you see this, please report to the ReactOS team!", Size); } - PcDiskReadBufferSize = (Size - DISKREADBUFFER) & ~0xfff; - if (PcDiskReadBufferSize > MAX_DISKREADBUFFER_SIZE) - { - PcDiskReadBufferSize = MAX_DISKREADBUFFER_SIZE; - } - TRACE("PcDiskReadBufferSize=0x%x\n", PcDiskReadBufferSize); - /* Get the address of the Extended BIOS Data Area (EBDA). - * Int 15h, AH=C1h - * SYSTEM - RETURN EXTENDED-BIOS DATA-AREA SEGMENT ADDRESS (PS) - * - * Return: - * CF set on error - * CF clear if successful - * ES = segment of data area - */ - Regs.x.eax = 0x0000C100; - Int386(0x15, &Regs, &Regs); - /* If the function fails, there is no EBDA */ - if (INT386_SUCCESS(Regs)) - { - /* Check if this is high enough */ - ULONG EbdaBase = (ULONG)Regs.w.es << 4; - if (EbdaBase < DISKREADBUFFER || EbdaBase - DISKREADBUFFER < MIN_DISKREADBUFFER_SIZE) - { - FrLdrBugCheckWithMessage( - MEMORY_INIT_FAILURE, - __FILE__, - __LINE__, - "The location of your EBDA is 0x%lx, which is too low!\n\n" - "If you see this, please report to the ReactOS team!", - EbdaBase); - } - if (((EbdaBase - DISKREADBUFFER) & ~0xfff) < PcDiskReadBufferSize) - { - PcDiskReadBufferSize = (EbdaBase - DISKREADBUFFER) & ~0xfff; - TRACE("After EBDA check, PcDiskReadBufferSize=0x%x\n", PcDiskReadBufferSize); - } - - /* Calculate the (max) size of the EBDA */ - Size = 0xA0000 - EbdaBase; - - /* Add the descriptor */ - MapCount = AddMemoryDescriptor(PcMemoryMap, - MAX_BIOS_DESCRIPTORS, - (EbdaBase / MM_PAGE_SIZE), - (Size / MM_PAGE_SIZE), - LoaderFirmwarePermanent); - } - /* Int 15h AX=E820h * Newer BIOSes - GET SYSTEM MEMORY MAP * @@ -322,13 +283,24 @@ { MemoryType = LoaderFree; - /* Align up base of memory area */ - RealBaseAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress & ~(MM_PAGE_SIZE - 1ULL); + /* Align up base of memory range */ + RealBaseAddress = ALIGN_UP_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress, + PAGE_SIZE); - /* Calculate the length after aligning the base */ - RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress + - PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress; - RealSize = (RealSize + MM_PAGE_SIZE - 1) & ~(MM_PAGE_SIZE - 1ULL); + /* Calculate aligned EndAddress */ + EndAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress + + PcBiosMemoryMap[PcBiosMapCount].Length; + EndAddress = ALIGN_DOWN_BY(EndAddress, PAGE_SIZE); + + /* Check if there is anything left */ + if (EndAddress <= RealBaseAddress) + { + /* This doesn't span any page, so continue with next range */ + continue; + } + + /* Calculate the length of the aligned range */ + RealSize = EndAddress - RealBaseAddress; } else { @@ -338,18 +310,20 @@ MemoryType = LoaderSpecialMemory; /* Align down base of memory area */ - RealBaseAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress & ~(MM_PAGE_SIZE - 1ULL); + RealBaseAddress = ALIGN_DOWN_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress, + PAGE_SIZE); + /* Calculate the length after aligning the base */ RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress + PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress; - RealSize = (RealSize + MM_PAGE_SIZE - 1) & ~(MM_PAGE_SIZE - 1ULL); + RealSize = ALIGN_UP_BY(RealSize, PAGE_SIZE); } /* Check if we can add this descriptor */ - if ((RealSize >= MM_PAGE_SIZE) && (MapCount < MaxMemoryMapSize)) + if ((RealSize >= MM_PAGE_SIZE) && (PcMapCount < MaxMemoryMapSize)) { /* Add the descriptor */ - MapCount = AddMemoryDescriptor(PcMemoryMap, + PcMapCount = AddMemoryDescriptor(PcMemoryMap, MAX_BIOS_DESCRIPTORS, (PFN_NUMBER)(RealBaseAddress / MM_PAGE_SIZE), (PFN_NUMBER)(RealSize / MM_PAGE_SIZE), @@ -366,13 +340,73 @@ TRACE("End Of System Memory Map!\n\n"); break; } + } + TRACE("GetBiosMemoryMap end, PcBiosMapCount = %ld\n", PcBiosMapCount); + return PcBiosMapCount; +} + +VOID +ReserveMemory( + ULONG_PTR BaseAddress, + SIZE_T Size, + TYPE_OF_MEMORY MemoryType, + PCHAR Usage) +{ + ULONG_PTR BasePage, PageCount; + ULONG i; + + BasePage = BaseAddress / PAGE_SIZE; + PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Size); + + for (i = 0; i < PcMapCount; i++) + { + /* Check for conflicting descriptor */ + if ((PcMemoryMap[i].BasePage < BasePage + PageCount) && + (PcMemoryMap[i].BasePage + PcMemoryMap[i].PageCount > BasePage)) + { + /* Check if the memory is free */ + if (PcMemoryMap[i].MemoryType != LoaderFree) + { + FrLdrBugCheckWithMessage( + MEMORY_INIT_FAILURE, + __FILE__, + __LINE__, + "Failed to reserve memory in the range 0x%Ix - 0x%Ix for %s", + BaseAddress, + Size, + Usage); + } + } } - return MapCount; + /* Add the memory descriptor */ + PcMapCount = AddMemoryDescriptor(PcMemoryMap, + MAX_BIOS_DESCRIPTORS, + BasePage, + PageCount, + MemoryType); } +VOID +SetMemory( + ULONG_PTR BaseAddress, + SIZE_T Size, + TYPE_OF_MEMORY MemoryType) +{ + ULONG_PTR BasePage, PageCount; + BasePage = BaseAddress / PAGE_SIZE; + PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Size); + + /* Add the memory descriptor */ + PcMapCount = AddMemoryDescriptor(PcMemoryMap, + MAX_BIOS_DESCRIPTORS, + BasePage, + PageCount, + MemoryType); +} + PFREELDR_MEMORY_DESCRIPTOR PcMemGetMemoryMap(ULONG *MemoryMapSize) { @@ -379,13 +413,16 @@ ULONG i, EntryCount; ULONG ExtendedMemorySizeAtOneMB; ULONG ExtendedMemorySizeAtSixteenMB; + ULONG EbdaBase, EbdaSize; + TRACE("PcMemGetMemoryMap()\n"); EntryCount = PcMemGetBiosMemoryMap(PcMemoryMap, MAX_BIOS_DESCRIPTORS); /* If the BIOS didn't provide a memory map, synthesize one */ - if (0 == EntryCount) + if (EntryCount == 0) { - GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB, &ExtendedMemorySizeAtSixteenMB); + GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB, + &ExtendedMemorySizeAtSixteenMB); /* Conventional memory */ AddMemoryDescriptor(PcMemoryMap, @@ -395,7 +432,7 @@ LoaderFree); /* Extended memory */ - EntryCount = AddMemoryDescriptor(PcMemoryMap, + PcMapCount = AddMemoryDescriptor(PcMemoryMap, MAX_BIOS_DESCRIPTORS, 1024 * 1024 / PAGE_SIZE, ExtendedMemorySizeAtOneMB * 1024 / PAGE_SIZE, @@ -404,16 +441,65 @@ if (ExtendedMemorySizeAtSixteenMB != 0) { /* Extended memory at 16MB */ - EntryCount = AddMemoryDescriptor(PcMemoryMap, + PcMapCount = AddMemoryDescriptor(PcMemoryMap, MAX_BIOS_DESCRIPTORS, 0x1000000 / PAGE_SIZE, ExtendedMemorySizeAtSixteenMB * 64 * 1024 / PAGE_SIZE, LoaderFree); } + + /* Check if we have an EBDA and get it's location */ + if (GetEbdaLocation(&EbdaBase, &EbdaSize)) + { + /* Add the descriptor */ + PcMapCount = AddMemoryDescriptor(PcMemoryMap, + MAX_BIOS_DESCRIPTORS, + (EbdaBase / PAGE_SIZE), + ADDRESS_AND_SIZE_TO_SPAN_PAGES(EbdaBase, EbdaSize), + LoaderFirmwarePermanent); + } } + /* Setup some protected ranges */ + SetMemory(0x000000, 0x01000, LoaderFirmwarePermanent); // Realmode IVT / BDA + SetMemory(0x0A0000, 0x50000, LoaderFirmwarePermanent); // Video memory + SetMemory(0x0F0000, 0x10000, LoaderSpecialMemory); // ROM + SetMemory(0xFFF000, 0x01000, LoaderSpecialMemory); // unusable memory (do we really need this?) + + /* Reserve some static ranges for freeldr */ + ReserveMemory(0x1000, STACKLOW - 0x1000, LoaderFirmwareTemporary, "BIOS area"); + ReserveMemory(STACKLOW, STACKADDR - STACKLOW, LoaderOsloaderStack, "FreeLdr stack"); + ReserveMemory(FREELDR_BASE, FrLdrImageSize, LoaderLoadedProgram, "FreeLdr image"); + + /* Default to 1 page above freeldr for the disk read buffer */ + DiskReadBuffer = (PUCHAR)ALIGN_UP_BY(FREELDR_BASE + FrLdrImageSize, PAGE_SIZE); + DiskReadBufferSize = PAGE_SIZE; + + /* Scan for free range above freeldr image */ + for (i = 0; i < PcMapCount; i++) + { + if ((PcMemoryMap[i].BasePage > (FREELDR_BASE / PAGE_SIZE)) && + (PcMemoryMap[i].MemoryType == LoaderFree)) + { + /* Use this range for the disk read buffer */ + DiskReadBuffer = (PVOID)(PcMemoryMap[i].BasePage * PAGE_SIZE); + DiskReadBufferSize = min(PcMemoryMap[i].PageCount * PAGE_SIZE, + MAX_DISKREADBUFFER_SIZE); + break; + } + } + + TRACE("DiskReadBuffer=%p, DiskReadBufferSize=%lx\n", + DiskReadBuffer, DiskReadBufferSize); + + /* Now reserve the range for the disk read buffer */ + ReserveMemory((ULONG_PTR)DiskReadBuffer, + DiskReadBufferSize, + LoaderFirmwareTemporary, + "Disk read buffer"); + TRACE("Dumping resulting memory map:\n"); - for (i = 0; i < EntryCount; i++) + for (i = 0; i < PcMapCount; i++) { TRACE("BasePage=0x%lx, PageCount=0x%lx, Type=%s\n", PcMemoryMap[i].BasePage, @@ -421,9 +507,9 @@ MmGetSystemMemoryMapTypeString(PcMemoryMap[i].MemoryType)); } - *MemoryMapSize = EntryCount; - + *MemoryMapSize = PcMapCount; return PcMemoryMap; } + /* EOF */ Index: boot/freeldr/freeldr/arch/i386/xboxhw.c =================================================================== --- boot/freeldr/freeldr/arch/i386/xboxhw.c (revision 66079) +++ boot/freeldr/freeldr/arch/i386/xboxhw.c (working copy) @@ -198,17 +198,17 @@ while (N > 0) { Length = N; - if (Length > PcDiskReadBufferSize) - Length = PcDiskReadBufferSize; + if (Length > DiskReadBufferSize) + Length = DiskReadBufferSize; Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize; ret = MachDiskReadLogicalSectors( Context->DriveNumber, Context->SectorNumber + Context->SectorOffset + i, Sectors, - (PVOID)DISKREADBUFFER); + DiskReadBuffer); if (!ret) return EIO; - RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length); + RtlCopyMemory(Ptr, DiskReadBuffer, Length); Ptr += Length; *Count += Length; N -= Length; @@ -257,14 +257,14 @@ PARTITION_TABLE_ENTRY PartitionTableEntry; /* Read the MBR */ - if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER)) + if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer)) { ERR("Reading MBR failed\n"); return; } - Buffer = (ULONG*)DISKREADBUFFER; - Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER; + Buffer = (ULONG*)DiskReadBuffer; + Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer; Signature = Mbr->Signature; TRACE("Signature: %x\n", Signature); @@ -351,13 +351,13 @@ * harddisks. So, we set the buffer to known contents first, then try to * read. If the BIOS reports success but the buffer contents haven't * changed then we fail anyway */ - memset((PVOID) DISKREADBUFFER, 0xcd, PcDiskReadBufferSize); - while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER)) + memset(DiskReadBuffer, 0xcd, DiskReadBufferSize); + while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer)) { Changed = FALSE; - for (i = 0; ! Changed && i < PcDiskReadBufferSize; i++) + for (i = 0; ! Changed && i < DiskReadBufferSize; i++) { - Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd; + Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd; } if (! Changed) { @@ -366,7 +366,7 @@ break; } DiskCount++; - memset((PVOID) DISKREADBUFFER, 0xcd, PcDiskReadBufferSize); + memset(DiskReadBuffer, 0xcd, DiskReadBufferSize); } DiskReportError(TRUE); TRACE("BIOS reports %d harddisk%s\n", Index: boot/freeldr/freeldr/cache/blocklist.c =================================================================== --- boot/freeldr/freeldr/cache/blocklist.c (revision 66079) +++ boot/freeldr/freeldr/cache/blocklist.c (working copy) @@ -119,13 +119,13 @@ } // Now try to read in the block - if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER)) + if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, DiskReadBuffer)) { FrLdrTempFree(CacheBlock->BlockData, TAG_CACHE_DATA); FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK); return NULL; } - RtlCopyMemory(CacheBlock->BlockData, (PVOID)DISKREADBUFFER, CacheDrive->BlockSize * CacheDrive->BytesPerSector); + RtlCopyMemory(CacheBlock->BlockData, DiskReadBuffer, CacheDrive->BlockSize * CacheDrive->BytesPerSector); // Add it to our list of blocks managed by the cache InsertTailList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry); Index: boot/freeldr/freeldr/debug.c =================================================================== --- boot/freeldr/freeldr/debug.c (revision 66079) +++ boot/freeldr/freeldr/debug.c (working copy) @@ -28,8 +28,8 @@ //#define DEBUG_ERR //#define DEBUG_INIFILE //#define DEBUG_REACTOS -//#define DEBUG_CUSTOM -#define DEBUG_NONE +#define DEBUG_CUSTOM +//#define DEBUG_NONE #define DBG_DEFAULT_LEVELS (ERR_LEVEL|FIXME_LEVEL) @@ -82,6 +82,8 @@ #elif defined (DEBUG_CUSTOM) DbgChannels[DPRINT_WARNING] = MAX_LEVEL; DbgChannels[DPRINT_WINDOWS] = MAX_LEVEL; + DbgChannels[DPRINT_MEMORY] = MAX_LEVEL; + //DbgChannels[DPRINT_DISK] = MAX_LEVEL; #endif if (DebugPort & RS232) Index: boot/freeldr/freeldr/disk/partition.c =================================================================== --- boot/freeldr/freeldr/disk/partition.c (revision 66079) +++ boot/freeldr/freeldr/disk/partition.c (working copy) @@ -202,11 +202,11 @@ ULONG Index; // Read master boot record - if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER)) + if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer)) { return FALSE; } - RtlCopyMemory(BootRecord, (PVOID)DISKREADBUFFER, sizeof(MASTER_BOOT_RECORD)); + RtlCopyMemory(BootRecord, DiskReadBuffer, sizeof(MASTER_BOOT_RECORD)); TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber); Index: boot/freeldr/freeldr/fs/ext2.c =================================================================== --- boot/freeldr/freeldr/fs/ext2.c (revision 66079) +++ boot/freeldr/freeldr/fs/ext2.c (working copy) @@ -569,8 +569,8 @@ //{ // return FALSE; //} - //ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, (PVOID)DISKREADBUFFER); - //RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, SectorCount * DiskGeometry.BytesPerSector); + //ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, DiskReadBuffer); + //RtlCopyMemory(Buffer, DiskReadBuffer, SectorCount * DiskGeometry.BytesPerSector); //return ReturnValue; return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer); @@ -607,11 +607,11 @@ // Now try to read the super block // If this fails then abort - if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, (PVOID)DISKREADBUFFER)) + if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, DiskReadBuffer)) { return FALSE; } - RtlCopyMemory(Ext2SuperBlock, (PVOID)((ULONG_PTR)DISKREADBUFFER + 1024), 1024); + RtlCopyMemory(Ext2SuperBlock, ((PUCHAR)DiskReadBuffer + 1024), 1024); TRACE("Dumping super block:\n"); TRACE("total_inodes: %d\n", Ext2SuperBlock->total_inodes); Index: boot/freeldr/freeldr/include/arch/arm/hardware.h =================================================================== --- boot/freeldr/freeldr/include/arch/arm/hardware.h (revision 66079) +++ boot/freeldr/freeldr/include/arch/arm/hardware.h (working copy) @@ -35,4 +35,4 @@ extern ULONG SecondLevelIcacheFillSize; extern ULONG gDiskReadBuffer, gFileSysBuffer; -#define DISKREADBUFFER gDiskReadBuffer +#define DiskReadBuffer gDiskReadBuffer Index: boot/freeldr/freeldr/include/arch/pc/machpc.h =================================================================== --- boot/freeldr/freeldr/include/arch/pc/machpc.h (revision 66079) +++ boot/freeldr/freeldr/include/arch/pc/machpc.h (working copy) @@ -63,6 +63,5 @@ extern BIOS_MEMORY_MAP PcBiosMemoryMap[]; extern ULONG PcBiosMapCount; -extern ULONG PcDiskReadBufferSize; /* EOF */ Index: boot/freeldr/freeldr/include/arch/pc/x86common.h =================================================================== --- boot/freeldr/freeldr/include/arch/pc/x86common.h (revision 66079) +++ boot/freeldr/freeldr/include/arch/pc/x86common.h (working copy) @@ -4,11 +4,11 @@ #endif /* Memory layout */ -//#ifdef _M_AMD64 +#ifdef _M_AMD64 #define PML4_ADDRESS HEX(1000) /* One page PML4 page table */ #define PDP_ADDRESS HEX(2000) /* One page PDP page table */ #define PD_ADDRESS HEX(3000) /* One page PD page table */ -//#endif +#endif #define BIOSCALLBUFFER HEX(4000) /* Buffer to store temporary data for any Int386() call */ #define STACK16ADDR HEX(6F00) /* The 16-bit stack top will be at 0000:6F00 */ #define BSS_START HEX(6F00) @@ -16,15 +16,13 @@ #define STACKADDR HEX(F000) /* The 32/64-bit stack top will be at 0000:F000, or 0xF000 */ #define FREELDR_BASE HEX(F800) #define FREELDR_PE_BASE HEX(10000) -#define DISKREADBUFFER HEX(8E000) /* Buffer to store data read in from the disk via the BIOS */ -/* 9F000- 9FFFF is reserved for the EBDA */ +#define MEMORY_MARGIN HEX(90000) /* We need this much memory */ #define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any Int386() call */ #define BIOSCALLBUFOFFSET HEX(0000) /* Buffer to store temporary data for any Int386() call */ #define BIOSCALLBUFSIZE PAGE_SIZE /* max is sizeof(VESA_SVGA_INFO) = 512 */ -#define MAX_FREELDR_PE_SIZE (DISKREADBUFFER - FREELDR_PE_BASE) -#define MIN_DISKREADBUFFER_SIZE HEX(1000) -#define MAX_DISKREADBUFFER_SIZE HEX(C000) +#define MAX_FREELDR_PE_SIZE (MEMORY_MARGIN - FREELDR_PE_BASE - PAGE_SIZE) +#define MAX_DISKREADBUFFER_SIZE HEX(10000) /* These addresses specify the realmode "BSS section" layout */ #define BSS_RealModeEntry (BSS_START + 0) Index: boot/freeldr/freeldr/include/disk.h =================================================================== --- boot/freeldr/freeldr/include/disk.h (revision 66079) +++ boot/freeldr/freeldr/include/disk.h (working copy) @@ -125,6 +125,8 @@ VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c extern UCHAR FrldrBootDrive; extern ULONG FrldrBootPartition; +extern PVOID DiskReadBuffer; +extern SIZE_T DiskReadBufferSize; BOOLEAN DiskGetBootPath(char *BootPath, unsigned Size); Index: boot/freeldr/freeldr/include/mm.h =================================================================== --- boot/freeldr/freeldr/include/mm.h (revision 66079) +++ boot/freeldr/freeldr/include/mm.h (working copy) @@ -123,6 +123,7 @@ extern PVOID FrLdrDefaultHeap; extern PVOID FrLdrTempHeap; +extern SIZE_T FrLdrImageSize; PVOID FrLdrHeapCreate( Index: boot/freeldr/freeldr/mm/meminit.c =================================================================== --- boot/freeldr/freeldr/mm/meminit.c (revision 66079) +++ boot/freeldr/freeldr/mm/meminit.c (working copy) @@ -50,6 +50,40 @@ { LoaderReserve, "Reserve" }, }; ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]); + +PCSTR +DbgGetMemoryTypeString( + TYPE_OF_MEMORY Type) +{ + ULONG i; + + for (i = 0; i < MemoryTypeCount; i++) + { + if (MemoryTypeArray[i].Type == Type) + { + return MemoryTypeArray[i].TypeString; + } + } + return MemoryTypeArray[0].TypeString; +} + +VOID +DbgDumpMemoryMap( + PFREELDR_MEMORY_DESCRIPTOR List) +{ + ULONG i; + + DbgPrint("Dumping Memory map:\n"); + for (i = 0; List[i].PageCount != 0; i++) + { + DbgPrint("%02d %08x - %08x: %s\n", + i, + List[i].BasePage * PAGE_SIZE, + (List[i].BasePage + List[i].PageCount) * PAGE_SIZE, + DbgGetMemoryTypeString(List[i].MemoryType)); + } + DbgPrint("\n"); +} #endif PVOID PageLookupTableAddress = NULL; @@ -61,6 +95,7 @@ PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap; ULONG BiosMemoryMapEntryCount; +SIZE_T FrLdrImageSize; ULONG AddMemoryDescriptor( @@ -70,78 +105,117 @@ IN PFN_NUMBER PageCount, IN TYPE_OF_MEMORY MemoryType) { - ULONG i, c; - PFN_NUMBER NextBase; - TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n", - BasePage, BasePage + PageCount, PageCount); + ULONG Index, DescriptCount; + PFN_NUMBER EndPage; + TRACE("AddMemoryDescriptor(0x%Ix, 0x%Ix, %u)\n", + BasePage, PageCount, MemoryType); - /* Scan through all existing descriptors */ - for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++) + EndPage = BasePage + PageCount; + + /* Skip over all descriptor below the new range */ + Index = 0; + while ((List[Index].PageCount != 0) && + ((List[Index].BasePage + List[Index].PageCount) <= BasePage)) { - /* Count entries completely below the new range */ - if (List[i].BasePage + List[i].PageCount <= BasePage) i++; + Index++; } - /* Check if the list is full */ - if (c >= MaxCount) return c; - - /* Is there an existing descriptor starting before the new range */ - while ((i < c) && (List[i].BasePage <= BasePage)) + /* Count the descriptors */ + DescriptCount = Index; + while (List[DescriptCount].PageCount != 0) { - /* The end of the existing one is the minimum for the new range */ - NextBase = List[i].BasePage + List[i].PageCount; - - /* Bail out, if everything is trimmed away */ - if ((BasePage + PageCount) <= NextBase) return c; - - /* Trim the naew range at the lower end */ - PageCount -= (NextBase - BasePage); - BasePage = NextBase; - - /* Go to the next entry and repeat */ - i++; + DescriptCount++; } - ASSERT(PageCount > 0); - - /* Are there still entries above? */ - if (i < c) + /* Check if the existing range conflicts with the new range */ + while ((List[Index].PageCount != 0) && + (List[Index].BasePage < EndPage)) { - /* Shift the following entries one up */ - RtlMoveMemory(&List[i+1], &List[i], (c - i) * sizeof(List[0])); + TRACE("AddMemoryDescriptor conflict @%lu: new=[%lx:%lx], existing=[%lx,%lx]\n", + Index, BasePage, PageCount, List[Index].BasePage, List[Index].PageCount); - /* Insert the new range */ - List[i].BasePage = BasePage; - List[i].PageCount = min(PageCount, List[i+1].BasePage - BasePage); - List[i].MemoryType = MemoryType; - c++; + /* + * We have 4 overlapping cases: + * + * Case (a) (b) (c) (d) + * Existing range |---| |-----| |---| |---| + * New range |---| |---| |-----| |---| + * + */ - TRACE("Inserting at i=%ld: (0x%lx:0x%lx)\n", - i, List[i].BasePage, List[i].PageCount); - - /* Check if the range was trimmed */ - if (PageCount > List[i].PageCount) + /* Check if the existing range starts before the new range (a)/(b) */ + if (List[Index].BasePage < BasePage) { - /* Recursively process the trimmed part */ - c = AddMemoryDescriptor(List, - MaxCount, - BasePage + List[i].PageCount, - PageCount - List[i].PageCount, - MemoryType); + /* Check if the existing range extends beyond the new range (b) */ + if (List[Index].BasePage + List[Index].PageCount > EndPage) + { + /* Split the descriptor */ + RtlMoveMemory(&List[Index + 1], + &List[Index], + (DescriptCount - Index) * sizeof(List[0])); + List[Index + 1].BasePage = EndPage; + List[Index + 1].PageCount = List[Index].BasePage + + List[Index].PageCount - + List[Index + 1].BasePage; + List[Index].PageCount = BasePage - List[Index].BasePage; + Index++; + DescriptCount++; + break; + } + else + { + /* Crop the existing range and continue with the next range */ + List[Index].PageCount = BasePage - List[Index].BasePage; + Index++; + } } + /* Check if the existing range is fully covered by the new range (c) */ + else if ((List[Index].BasePage + List[Index].PageCount) <= + EndPage) + { + /* Delete this descriptor */ + RtlMoveMemory(&List[Index], + &List[Index + 1], + (DescriptCount - Index) * sizeof(List[0])); + DescriptCount--; + } + /* Otherwise the existing range ends after the new range (d) */ + else + { + /* Crop the existing range at the start and bail out */ + List[Index].PageCount -= EndPage - List[Index].BasePage; + List[Index].BasePage = EndPage; + break; + } } - else + + /* Make sure we can still add a new descriptor */ + if (DescriptCount >= MaxCount) { - /* We can simply add the range here */ - TRACE("Adding i=%ld: (0x%lx:0x%lx)\n", i, BasePage, PageCount); - List[i].BasePage = BasePage; - List[i].PageCount = PageCount; - List[i].MemoryType = MemoryType; - c++; + FrLdrBugCheckWithMessage( + MEMORY_INIT_FAILURE, + __FILE__, + __LINE__, + "Ran out of static memory descriptors!"); } - /* Return the new count */ - return c; + /* Insert the new descriptor */ + if (Index < DescriptCount) + { + RtlMoveMemory(&List[Index + 1], + &List[Index], + (DescriptCount - Index) * sizeof(List[0])); + } + + List[Index].BasePage = BasePage; + List[Index].PageCount = PageCount; + List[Index].MemoryType = MemoryType; + DescriptCount++; + +#ifdef DBG + DbgDumpMemoryMap(List); +#endif + return DescriptCount; } const FREELDR_MEMORY_DESCRIPTOR* @@ -230,6 +304,9 @@ OptionalHeader->SizeOfImage, MAX_FREELDR_PE_SIZE, OptionalHeader->SectionAlignment, OptionalHeader->FileAlignment); } + + /* Calculate the full image size */ + FrLdrImageSize = (ULONG_PTR)&__ImageBase + OptionalHeader->SizeOfImage - FREELDR_BASE; } BOOLEAN MmInitializeMemoryManager(VOID)