Author: tkreuzer Date: Sun Jan 25 23:24:27 2015 New Revision: 66087
URL: http://svn.reactos.org/svn/reactos?rev=66087&view=rev Log: [FREELDR] Make the DiskReadBuffer location and size dynamic. Should fix a number of issues with non-standard BIOSes. Many thanks to jeditobe for his help with testing/debugging of this issue. CORE-8899 #resolve CORE-9031 #resolve
Modified: trunk/reactos/boot/freeldr/bootsect/fatx.S trunk/reactos/boot/freeldr/freeldr/arch/i386/hardware.c trunk/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c trunk/reactos/boot/freeldr/freeldr/cache/blocklist.c trunk/reactos/boot/freeldr/freeldr/disk/partition.c trunk/reactos/boot/freeldr/freeldr/fs/ext2.c trunk/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h trunk/reactos/boot/freeldr/freeldr/include/disk.h trunk/reactos/boot/freeldr/freeldr/include/mm.h trunk/reactos/boot/freeldr/freeldr/mm/meminit.c
Modified: trunk/reactos/boot/freeldr/bootsect/fatx.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/bootsect/fatx.... ============================================================================== --- trunk/reactos/boot/freeldr/bootsect/fatx.S [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/bootsect/fatx.S [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -7,6 +7,7 @@ * Timo Kreuzer */
+#define DISKREADBUFFER HEX(8E000)
/* * Layout of a FAT volume:
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/hardware.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/hardware.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/hardware.c [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -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,
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -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];
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -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,38 +165,12 @@ }
static -ULONG -PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSize) +BOOLEAN +GetEbdaLocation( + PULONG BaseAddress, + PULONG Size) { REGS Regs; - ULONG MapCount = 0; - ULONGLONG RealBaseAddress, RealSize; - TYPE_OF_MEMORY MemoryType; - ULONG Size; - ASSERT(PcBiosMapCount == 0); - - TRACE("GetBiosMemoryMap()\n"); - - /* Make sure the usable memory is large enough. To do this we check the 16 - 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) - { - FrLdrBugCheckWithMessage( - MEMORY_INIT_FAILURE, - __FILE__, - __LINE__, - "The BIOS reported a usable memory range up to 0x%x, which is too small!\n\n" - "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 @@ -232,36 +185,44 @@ 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); - } + 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; + ULONGLONG RealBaseAddress, EndAddress, RealSize; + TYPE_OF_MEMORY MemoryType; + ULONG Size; + ASSERT(PcBiosMapCount == 0); + + TRACE("GetBiosMemoryMap()\n"); + + /* Make sure the usable memory is large enough. To do this we check the 16 + bit value at address 0x413 inside the BDA, which gives us the usable size + in KB */ + Size = (*(PUSHORT)(ULONG_PTR)0x413) * 1024; + if (Size < MEMORY_MARGIN) + { + FrLdrBugCheckWithMessage( + MEMORY_INIT_FAILURE, + __FILE__, + __LINE__, + "The BIOS reported a usable memory range up to 0x%x, which is too small!\n\n" + "If you see this, please report to the ReactOS team!", + Size); + } +
/* 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); - - /* 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); + /* Align up base of memory range */ + RealBaseAddress = ALIGN_UP_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress, + PAGE_SIZE); + + /* 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,12 +340,72 @@ TRACE("End Of System Memory Map!\n\n"); break; } - - } - - return MapCount; -} - + } + + 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); + } + } + } + + /* 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) - { - GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB, &ExtendedMemorySizeAtSixteenMB); + if (EntryCount == 0) + { + 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 */
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -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",
Modified: trunk/reactos/boot/freeldr/freeldr/cache/blocklist.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/cache/... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/cache/blocklist.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/cache/blocklist.c [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -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);
Modified: trunk/reactos/boot/freeldr/freeldr/disk/partition.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/disk/p... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/disk/partition.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/disk/partition.c [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -202,11 +202,11 @@ ULONG Index;
// Read master boot record - if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER)) - { - return FALSE; - } - RtlCopyMemory(BootRecord, (PVOID)DISKREADBUFFER, sizeof(MASTER_BOOT_RECORD)); + if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer)) + { + return FALSE; + } + RtlCopyMemory(BootRecord, DiskReadBuffer, sizeof(MASTER_BOOT_RECORD));
TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber);
Modified: trunk/reactos/boot/freeldr/freeldr/fs/ext2.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/fs/ext... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/fs/ext2.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/fs/ext2.c [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -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)) - { - return FALSE; - } - RtlCopyMemory(Ext2SuperBlock, (PVOID)((ULONG_PTR)DISKREADBUFFER + 1024), 1024); + if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, DiskReadBuffer)) + { + return FALSE; + } + RtlCopyMemory(Ext2SuperBlock, ((PUCHAR)DiskReadBuffer + 1024), 1024);
TRACE("Dumping super block:\n"); TRACE("total_inodes: %d\n", Ext2SuperBlock->total_inodes);
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/include/arch/arm/hardware.h [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -35,4 +35,4 @@ extern ULONG SecondLevelIcacheFillSize;
extern ULONG gDiskReadBuffer, gFileSysBuffer; -#define DISKREADBUFFER gDiskReadBuffer +#define DiskReadBuffer gDiskReadBuffer
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -63,6 +63,5 @@
extern BIOS_MEMORY_MAP PcBiosMemoryMap[]; extern ULONG PcBiosMapCount; -extern ULONG PcDiskReadBufferSize;
/* EOF */
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -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)
Modified: trunk/reactos/boot/freeldr/freeldr/include/disk.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/disk.h [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/include/disk.h [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -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);
Modified: trunk/reactos/boot/freeldr/freeldr/include/mm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/mm.h [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/include/mm.h [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -123,6 +123,7 @@
extern PVOID FrLdrDefaultHeap; extern PVOID FrLdrTempHeap; +extern SIZE_T FrLdrImageSize;
PVOID FrLdrHeapCreate(
Modified: trunk/reactos/boot/freeldr/freeldr/mm/meminit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/mm/mem... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] Sun Jan 25 23:24:27 2015 @@ -23,6 +23,17 @@
DBG_DEFAULT_CHANNEL(MEMORY);
+PVOID PageLookupTableAddress = NULL; +PFN_NUMBER TotalPagesInLookupTable = 0; +PFN_NUMBER FreePagesInLookupTable = 0; +PFN_NUMBER LastFreePageHint = 0; +PFN_NUMBER MmLowestPhysicalPage = 0xFFFFFFFF; +PFN_NUMBER MmHighestPhysicalPage = 0; + +PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap; +ULONG BiosMemoryMapEntryCount; +SIZE_T FrLdrImageSize; + #if DBG typedef struct { @@ -50,17 +61,42 @@ { LoaderReserve, "Reserve" }, }; ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]); + +PCSTR +MmGetSystemMemoryMapTypeString( + TYPE_OF_MEMORY Type) +{ + ULONG Index; + + for (Index = 1; Index < MemoryTypeCount; Index++) + { + if (MemoryTypeArray[Index].Type == Type) + { + return MemoryTypeArray[Index].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, + MmGetSystemMemoryMapTypeString(List[i].MemoryType)); + } + DbgPrint("\n"); +} #endif - -PVOID PageLookupTableAddress = NULL; -PFN_NUMBER TotalPagesInLookupTable = 0; -PFN_NUMBER FreePagesInLookupTable = 0; -PFN_NUMBER LastFreePageHint = 0; -PFN_NUMBER MmLowestPhysicalPage = 0xFFFFFFFF; -PFN_NUMBER MmHighestPhysicalPage = 0; - -PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap; -ULONG BiosMemoryMapEntryCount;
ULONG AddMemoryDescriptor( @@ -70,78 +106,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); - - /* Scan through all existing descriptors */ - for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++) - { - /* Count entries completely below the new range */ - if (List[i].BasePage + List[i].PageCount <= BasePage) i++; - } - - /* 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)) - { - /* 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++; - } - - ASSERT(PageCount > 0); - - /* Are there still entries above? */ - if (i < c) - { - /* Shift the following entries one up */ - RtlMoveMemory(&List[i+1], &List[i], (c - i) * sizeof(List[0])); - - /* Insert the new range */ - List[i].BasePage = BasePage; - List[i].PageCount = min(PageCount, List[i+1].BasePage - BasePage); - List[i].MemoryType = MemoryType; - c++; - - 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) - { - /* Recursively process the trimmed part */ - c = AddMemoryDescriptor(List, - MaxCount, - BasePage + List[i].PageCount, - PageCount - List[i].PageCount, - MemoryType); - } - } - else - { - /* 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++; - } - - /* Return the new count */ - return c; + ULONG Index, DescriptCount; + PFN_NUMBER EndPage; + TRACE("AddMemoryDescriptor(0x%Ix, 0x%Ix, %u)\n", + BasePage, PageCount, MemoryType); + + 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)) + { + Index++; + } + + /* Count the descriptors */ + DescriptCount = Index; + while (List[DescriptCount].PageCount != 0) + { + DescriptCount++; + } + + /* Check if the existing range conflicts with the new range */ + while ((List[Index].PageCount != 0) && + (List[Index].BasePage < EndPage)) + { + TRACE("AddMemoryDescriptor conflict @%lu: new=[%lx:%lx], existing=[%lx,%lx]\n", + Index, BasePage, PageCount, List[Index].BasePage, List[Index].PageCount); + + /* + * We have 4 overlapping cases: + * + * Case (a) (b) (c) (d) + * Existing range |---| |-----| |---| |---| + * New range |---| |---| |-----| |---| + * + */ + + /* Check if the existing range starts before the new range (a)/(b) */ + if (List[Index].BasePage < BasePage) + { + /* 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; + } + } + + /* Make sure we can still add a new descriptor */ + if (DescriptCount >= MaxCount) + { + FrLdrBugCheckWithMessage( + MEMORY_INIT_FAILURE, + __FILE__, + __LINE__, + "Ran out of static memory descriptors!"); + } + + /* 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 +305,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) @@ -287,22 +365,6 @@ return TRUE; }
-#if DBG -PCSTR MmGetSystemMemoryMapTypeString(TYPE_OF_MEMORY Type) -{ - ULONG Index; - - for (Index=1; Index<MemoryTypeCount; Index++) - { - if (MemoryTypeArray[Index].Type == Type) - { - return MemoryTypeArray[Index].TypeString; - } - } - - return MemoryTypeArray[0].TypeString; -} -#endif
PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address) {