From c2de09f61ac36c533b6e0cb40756b3bed2128b89 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 23 Aug 2007 21:29:28 +0000 Subject: [PATCH] - Make freeldr do identity memory mapping. This simplifies a lot of things throughout the code, and finally places the kernel at the same addresses where NT kernel is located. - Fix code in ntoskrnl which was based on (wrong) assumptions. svn path=/trunk/; revision=28497 --- .../boot/freeldr/freeldr/arch/i386/loader.c | 12 +++++------ .../boot/freeldr/freeldr/include/reactos.h | 8 +------- .../boot/freeldr/freeldr/reactos/reactos.c | 4 ++-- .../boot/freeldr/freeldr/reactos/setupldr.c | 4 ++-- reactos/ntoskrnl/ke/freeldr.c | 20 +++++++++++-------- reactos/ntoskrnl/mm/mminit.c | 9 +++++++-- reactos/tools/rbuild/module.cpp | 2 +- 7 files changed, 31 insertions(+), 28 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/loader.c b/reactos/boot/freeldr/freeldr/arch/i386/loader.c index 78cbc168f36..ce7efc487a0 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/loader.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/loader.c @@ -33,8 +33,8 @@ PLOADER_MODULE CurrentModule = NULL; /* Unrelocated Kernel Base in Virtual Memory */ ULONG_PTR KernelBase; -/* Kernel Entrypoint in Physical Memory */ -ULONG_PTR KernelEntry; +/* Kernel Entrypoint in Virtual Memory */ +ULONG_PTR KernelEntryPoint; /* Page Directory and Tables for non-PAE Systems */ extern PAGE_DIRECTORY_X86 startup_pagedirectory; @@ -297,9 +297,9 @@ LdrPEGetExportByName(PVOID BaseAddress, ULONG ExportDirSize; /* HAL and NTOS use a virtual address, switch it to physical mode */ - if ((ULONG_PTR)BaseAddress & 0x80000000) + if ((ULONG_PTR)BaseAddress & KSEG0_BASE) { - BaseAddress = (PVOID)((ULONG_PTR)BaseAddress - KSEG0_BASE + 0x200000); + BaseAddress = RVA(BaseAddress, -KSEG0_BASE); } ExportDir = (PIMAGE_EXPORT_DIRECTORY) @@ -439,7 +439,7 @@ LdrPEProcessImportDirectoryEntry(PVOID DriverBase, *ImportAddressList = LdrPEGetExportByName((PVOID)LoaderModule->ModStart, pe_name->Name, pe_name->Hint); /* Fixup the address to be virtual */ - *ImportAddressList = (PVOID)((ULONG_PTR)*ImportAddressList + (KSEG0_BASE - 0x200000)); + *ImportAddressList = RVA(*ImportAddressList, KSEG0_BASE); //DbgPrint("Looked for: %s and found: %p\n", pe_name->Name, *ImportAddressList); if ((*ImportAddressList) == NULL) @@ -592,7 +592,7 @@ FrLdrMapImage(IN FILE *Image, /* Set the virtual (image) and physical (load) addresses */ LoadBase = (PVOID)NextModuleBase; - ImageBase = RVA(LoadBase , -KERNEL_BASE_PHYS + KSEG0_BASE); + ImageBase = RVA(LoadBase, KSEG0_BASE); /* Save the Image Size */ ImageSize = FsGetFileSize(Image); diff --git a/reactos/boot/freeldr/freeldr/include/reactos.h b/reactos/boot/freeldr/freeldr/include/reactos.h index 45f3dc8205e..e16e142144e 100644 --- a/reactos/boot/freeldr/freeldr/include/reactos.h +++ b/reactos/boot/freeldr/freeldr/include/reactos.h @@ -21,7 +21,7 @@ #define __REACTOS_H /* Base Addres of Kernel in Physical Memory */ -#define KERNEL_BASE_PHYS 0x200000 +#define KERNEL_BASE_PHYS 0x800000 /* Bits to shift to convert a Virtual Address into an Offset in the Page Table */ #define PFN_SHIFT 12 @@ -30,10 +30,6 @@ #define PDE_SHIFT 22 #define PDE_SHIFT_PAE 18 -/* Converts a Relative Address read from the Kernel into a Physical Address */ -#define RaToPa(p) \ - (ULONG_PTR)((ULONG_PTR)p + KERNEL_BASE_PHYS) - /* Converts a Physical Address Pointer into a Page Frame Number */ #define PaPtrToPfn(p) \ (((ULONG_PTR)&p) >> PFN_SHIFT) @@ -55,8 +51,6 @@ #define ApicPageTableIndex (APIC_BASE >> 22) #define KuserPageTableIndex (KI_USER_SHARED_DATA >> 22) -#define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) + KernelBase - typedef struct _PAGE_DIRECTORY_X86 { HARDWARE_PTE Pde[1024]; diff --git a/reactos/boot/freeldr/freeldr/reactos/reactos.c b/reactos/boot/freeldr/freeldr/reactos/reactos.c index 412ebca9fdf..9de94fd082f 100644 --- a/reactos/boot/freeldr/freeldr/reactos/reactos.c +++ b/reactos/boot/freeldr/freeldr/reactos/reactos.c @@ -36,7 +36,7 @@ CHAR szBootPath[255]; CHAR SystemRoot[255]; static CHAR szLoadingMsg[] = "Loading ReactOS..."; BOOLEAN FrLdrBootType; -extern ULONG_PTR KernelBase, KernelEntry; +extern ULONG_PTR KernelBase, KernelEntryPoint; BOOLEAN FrLdrLoadDriver(PCHAR szFileName, @@ -759,7 +759,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) /* Get the NT header, kernel base and kernel entry */ NtHeader = RtlImageNtHeader(LoadBase); KernelBase = NtHeader->OptionalHeader.ImageBase; - KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint); + KernelEntryPoint = KernelBase + NtHeader->OptionalHeader.AddressOfEntryPoint; LoaderBlock.KernelBase = KernelBase; /* diff --git a/reactos/boot/freeldr/freeldr/reactos/setupldr.c b/reactos/boot/freeldr/freeldr/reactos/setupldr.c index 21fbef8eac9..9e716264e9b 100644 --- a/reactos/boot/freeldr/freeldr/reactos/setupldr.c +++ b/reactos/boot/freeldr/freeldr/reactos/setupldr.c @@ -31,7 +31,7 @@ memory_map_t reactos_memory_map[32]; // Memory map char szBootPath[256]; char szHalName[256]; CHAR SystemRoot[255]; -extern ULONG_PTR KernelBase, KernelEntry; +extern ULONG_PTR KernelBase, KernelEntryPoint; extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos); @@ -83,7 +83,7 @@ static FrLdrLoadKernel(IN PCHAR szFileName, /* Get the NT header, kernel base and kernel entry */ NtHeader = RtlImageNtHeader(LoadBase); KernelBase = NtHeader->OptionalHeader.ImageBase; - KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint); + KernelEntryPoint = KernelBase + NtHeader->OptionalHeader.AddressOfEntryPoint; LoaderBlock.KernelBase = KernelBase; /* Update Processbar and return success */ diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 9d8bcdee27e..88d72a73a6f 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -102,7 +102,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, if (!_stricmp(DriverName, "ansi.nls")) { /* ANSI Code page */ - ModStart = (PVOID)((ULONG_PTR)ModStart + (KSEG0_BASE - 0x200000)); + ModStart = RVA(ModStart, KSEG0_BASE); LoaderBlock->NlsData->AnsiCodePageData = ModStart; /* Create an MD for it */ @@ -117,7 +117,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, else if (!_stricmp(DriverName, "oem.nls")) { /* OEM Code page */ - ModStart = (PVOID)((ULONG_PTR)ModStart + (KSEG0_BASE - 0x200000)); + ModStart = RVA(ModStart, KSEG0_BASE); LoaderBlock->NlsData->OemCodePageData = ModStart; /* Create an MD for it */ @@ -132,7 +132,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, else if (!_stricmp(DriverName, "casemap.nls")) { /* Unicode Code page */ - ModStart = (PVOID)((ULONG_PTR)ModStart + (KSEG0_BASE - 0x200000)); + ModStart = RVA(ModStart, KSEG0_BASE); LoaderBlock->NlsData->UnicodeCodePageData = ModStart; /* Create an MD for it */ @@ -150,7 +150,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, !(_stricmp(DriverName, "system.hiv"))) { /* Save registry data */ - ModStart = (PVOID)((ULONG_PTR)ModStart + (KSEG0_BASE - 0x200000)); + ModStart = RVA(ModStart, KSEG0_BASE); LoaderBlock->RegistryBase = ModStart; LoaderBlock->RegistryLength = ModSize; @@ -172,7 +172,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, !(_stricmp(DriverName, "hardware.hiv"))) { /* Create an MD for it */ - ModStart = (PVOID)((ULONG_PTR)ModStart + (KSEG0_BASE - 0x200000)); + ModStart = RVA(ModStart, KSEG0_BASE); MdEntry = &BldrMemoryDescriptors[i]; MdEntry->MemoryType = LoaderRegistryData; MdEntry->BasePage = (ULONG_PTR)ModStart >> PAGE_SHIFT; @@ -285,6 +285,11 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, LoaderBlock->Extension->MajorVersion = 5; LoaderBlock->Extension->MinorVersion = 2; + /* Save the number of pages the kernel images take */ + LoaderBlock->Extension->LoaderPagesSpanned = + MmFreeLdrLastKrnlPhysAddr - MmFreeLdrFirstKrnlPhysAddr; + LoaderBlock->Extension->LoaderPagesSpanned /= PAGE_SIZE; + /* Now setup the setup block if we have one */ if (LoaderBlock->SetupLdrBlock) { @@ -379,9 +384,8 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, ModsCount - 1]. ModEnd); MmFreeLdrFirstKrnlPhysAddr = KeRosLoaderBlock->ModsAddr[0].ModStart - - KSEG0_BASE + 0x200000; - MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress - - KSEG0_BASE + 0x200000; + KSEG0_BASE; + MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress - KSEG0_BASE; #if defined(_M_IX86) /* Set up the VDM Data */ diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 1c4b0642216..099f81f7d00 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -90,8 +90,13 @@ MmInitVirtualMemory(ULONG_PTR LastKernelAddress, MmInitMemoryAreas(); - /* Start the paged and nonpaged pool at a 4MB boundary. */ - MiNonPagedPoolStart = (PVOID)ROUND_UP((ULONG_PTR)LastKernelAddress + PAGE_SIZE, 0x400000); + /* + * FreeLDR Marks 6MB "in use" at the start of the kernel base, + * so start the non-paged pool at a boundary of 6MB from where + * the last driver was loaded. This should be the end of the + * FreeLDR-marked region. + */ + MiNonPagedPoolStart = (PVOID)ROUND_UP((ULONG_PTR)LastKernelAddress + PAGE_SIZE, 0x600000); MiNonPagedPoolLength = MM_NONPAGED_POOL_SIZE; MmPagedPoolBase = (PVOID)ROUND_UP((ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength + PAGE_SIZE, 0x400000); diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp index 060c10b1fce..910c9ef6e48 100644 --- a/reactos/tools/rbuild/module.cpp +++ b/reactos/tools/rbuild/module.cpp @@ -992,7 +992,7 @@ Module::GetDefaultModuleBaseaddress () const switch ( type ) { case Kernel: - return "0x80000000"; + return "0x80800000"; case Win32DLL: case Win32OCX: return "0x10000000";