Author: ion Date: Wed Feb 28 22:04:27 2007 New Revision: 25928
URL: http://svn.reactos.org/svn/reactos?rev=25928&view=rev Log: - More refactoring of FreeLDR/SetupLDR PE Loader Code to remove some hacks. - Don't double-free some entries when failing to load a boot driver. This would cause a crash when pciide couldn't load (since we don't yet import drivers in FreeLDR, and pciide needs pciidex). Thanks to encoded for reporting it. - We now free boot driver memory again since it's safe to do so again. This should reduce memory requirements even more.
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/loader.c trunk/reactos/boot/freeldr/freeldr/freeldr_main.rbuild trunk/reactos/boot/freeldr/freeldr/include/reactos.h trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c trunk/reactos/boot/freeldr/freeldr/setupldr_main.rbuild trunk/reactos/ntoskrnl/io/iomgr/driver.c trunk/reactos/ntoskrnl/mm/sysldr.c
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/loader.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/loader.c (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/loader.c Wed Feb 28 22:04:27 2007 @@ -24,42 +24,6 @@ #include <debug.h> #undef DbgPrint
-/* Base Addres of Kernel in Physical Memory */ -#define KERNEL_BASE_PHYS 0x200000 - -/* Bits to shift to convert a Virtual Address into an Offset in the Page Table */ -#define PFN_SHIFT 12 - -/* Bits to shift to convert a Virtual Address into an Offset in the Page Directory */ -#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) - -/* Converts a Physical Address into a Page Frame Number */ -#define PaToPfn(p) \ - ((p) >> PFN_SHIFT) - -#define STARTUP_BASE 0xC0000000 -#define HYPERSPACE_BASE 0xC0400000 -#define HYPERSPACE_PAE_BASE 0xC0800000 -#define APIC_BASE 0xFEC00000 -#define KPCR_BASE 0xFF000000 - -#define LowMemPageTableIndex 0 -#define StartupPageTableIndex (STARTUP_BASE >> 22) -#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 22) -#define KpcrPageTableIndex (KPCR_BASE >> 22) -#define ApicPageTableIndex (APIC_BASE >> 22) - -#define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) + KernelBase - /* Load Address of Next Module */ ULONG_PTR NextModuleBase = KERNEL_BASE_PHYS;
@@ -71,61 +35,14 @@
/* Kernel Entrypoint in Physical Memory */ ULONG_PTR KernelEntry; - -typedef struct _HARDWARE_PTE_X64 { - ULONG Valid : 1; - ULONG Write : 1; - ULONG Owner : 1; - ULONG WriteThrough : 1; - ULONG CacheDisable : 1; - ULONG Accessed : 1; - ULONG Dirty : 1; - ULONG LargePage : 1; - ULONG Global : 1; - ULONG CopyOnWrite : 1; - ULONG Prototype : 1; - ULONG reserved : 1; - ULONG PageFrameNumber : 20; - ULONG reserved2 : 31; - ULONG NoExecute : 1; -} HARDWARE_PTE_X64, *PHARDWARE_PTE_X64; - -typedef struct _PAGE_DIRECTORY_X86 { - HARDWARE_PTE Pde[1024]; -} PAGE_DIRECTORY_X86, *PPAGE_DIRECTORY_X86; - -typedef struct _PAGE_DIRECTORY_X64 { - HARDWARE_PTE_X64 Pde[2048]; -} PAGE_DIRECTORY_X64, *PPAGE_DIRECTORY_X64; - -typedef struct _PAGE_DIRECTORY_TABLE_X64 { - HARDWARE_PTE_X64 Pde[4]; -} PAGE_DIRECTORY_TABLE_X64, *PPAGE_DIRECTORY_TABLE_X64;
/* Page Directory and Tables for non-PAE Systems */ extern PAGE_DIRECTORY_X86 startup_pagedirectory; extern PAGE_DIRECTORY_X86 lowmem_pagetable; extern PAGE_DIRECTORY_X86 kernel_pagetable; extern ULONG_PTR hyperspace_pagetable; -extern ULONG_PTR _pae_pagedirtable; extern PAGE_DIRECTORY_X86 apic_pagetable; extern PAGE_DIRECTORY_X86 kpcr_pagetable; - -/* Page Directory and Tables for PAE Systems */ -extern PAGE_DIRECTORY_TABLE_X64 startup_pagedirectorytable_pae; -extern PAGE_DIRECTORY_X64 startup_pagedirectory_pae; -extern PAGE_DIRECTORY_X64 lowmem_pagetable_pae; -extern PAGE_DIRECTORY_X64 kernel_pagetable_pae; -extern ULONG_PTR hyperspace_pagetable_pae; -extern ULONG_PTR pagedirtable_pae; -extern PAGE_DIRECTORY_X64 apic_pagetable_pae; -extern PAGE_DIRECTORY_X64 kpcr_pagetable_pae; - -BOOLEAN -NTAPI -FrLdrLoadImage(IN PCHAR szFileName, - IN INT nPos, - IN BOOLEAN IsKernel);
PVOID NTAPI @@ -269,8 +186,8 @@
/* Set up Low Memory PTEs */ PageDir = (PPAGE_DIRECTORY_X86)&lowmem_pagetable; - for (i=0; i<1024; i++) { - + for (i=0; i<1024; i++) + { PageDir->Pde[i].Valid = 1; PageDir->Pde[i].Write = 1; PageDir->Pde[i].Owner = 1; @@ -279,8 +196,8 @@
/* Set up Kernel PTEs */ PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable; - for (i=0; i<1536; i++) { - + for (i=0; i<1536; i++) + { PageDir->Pde[i].Valid = 1; PageDir->Pde[i].Write = 1; PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE); @@ -658,7 +575,7 @@ return DriverSize; }
-BOOLEAN +PVOID NTAPI FrLdrMapImage(IN FILE *Image, IN PCHAR Name, @@ -713,21 +630,13 @@ //DbgPrint("Image: %s loaded at: %p\n", Name, ImageBase);
/* Load HAL if this is the kernel */ - if (ImageType == 1) - { - PIMAGE_NT_HEADERS NtHeader; - NtHeader = RtlImageNtHeader(LoadBase); - KernelBase = NtHeader->OptionalHeader.ImageBase; - KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint); - FrLdrLoadImage("hal.dll", 10, FALSE); - LoaderBlock.KernelBase = KernelBase; - } + if (ImageType == 1) FrLdrLoadImage("hal.dll", 10, FALSE);
/* Perform import fixups */ if (ImageType != 2) LdrPEFixupImports(LoadBase, Name);
- /* Return Success */ - return TRUE; + /* Return the final mapped address */ + return LoadBase; }
ULONG_PTR
Modified: trunk/reactos/boot/freeldr/freeldr/freeldr_main.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/freeld... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/freeldr_main.rbuild (original) +++ trunk/reactos/boot/freeldr/freeldr/freeldr_main.rbuild Wed Feb 28 22:04:27 2007 @@ -2,9 +2,6 @@ <include base="freeldr_main">include</include> <include base="ntoskrnl">include</include> <define name="__USE_W32API" /> -<!-- - <define name="DEBUG" /> ---> <define name="_NTHAL_" /> <compilerflag>-ffreestanding</compilerflag> <compilerflag>-fno-builtin</compilerflag>
Modified: trunk/reactos/boot/freeldr/freeldr/include/reactos.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/reactos.h (original) +++ trunk/reactos/boot/freeldr/freeldr/include/reactos.h Wed Feb 28 22:04:27 2007 @@ -20,6 +20,46 @@ #ifndef __REACTOS_H #define __REACTOS_H
+/* Base Addres of Kernel in Physical Memory */ +#define KERNEL_BASE_PHYS 0x200000 + +/* Bits to shift to convert a Virtual Address into an Offset in the Page Table */ +#define PFN_SHIFT 12 + +/* Bits to shift to convert a Virtual Address into an Offset in the Page Directory */ +#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) + +/* Converts a Physical Address into a Page Frame Number */ +#define PaToPfn(p) \ + ((p) >> PFN_SHIFT) + +#define STARTUP_BASE 0xC0000000 +#define HYPERSPACE_BASE 0xC0400000 +#define HYPERSPACE_PAE_BASE 0xC0800000 +#define APIC_BASE 0xFEC00000 +#define KPCR_BASE 0xFF000000 + +#define LowMemPageTableIndex 0 +#define StartupPageTableIndex (STARTUP_BASE >> 22) +#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 22) +#define KpcrPageTableIndex (KPCR_BASE >> 22) +#define ApicPageTableIndex (APIC_BASE >> 22) + +#define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) + KernelBase + +typedef struct _PAGE_DIRECTORY_X86 +{ + HARDWARE_PTE Pde[1024]; +} PAGE_DIRECTORY_X86, *PPAGE_DIRECTORY_X86;
/////////////////////////////////////////////////////////////////////////////////////// // @@ -66,4 +106,20 @@ VOID NTAPI FrLdrStartup(ULONG Magic); typedef VOID (FASTCALL *ASMCODE)(ULONG Magic, PROS_LOADER_PARAMETER_BLOCK LoaderBlock);
+PVOID +NTAPI +FrLdrMapImage( + IN FILE *Image, + IN PCHAR ShortName, + IN ULONG ImageType +); + +PVOID +NTAPI +FrLdrLoadImage( + IN PCHAR szFileName, + IN INT nPos, + IN ULONG ImageType +); + #endif // defined __REACTOS_H
Modified: trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/reacto... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c (original) +++ trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c Wed Feb 28 22:04:27 2007 @@ -37,16 +37,9 @@ CHAR szBootPath[255]; static CHAR szLoadingMsg[] = "Loading ReactOS..."; BOOLEAN FrLdrBootType; - -BOOLEAN -NTAPI -FrLdrMapImage( - IN FILE *Image, - IN PCHAR ShortName, - IN ULONG ImageType -); - -BOOLEAN +extern ULONG_PTR KernelBase, KernelEntry; + +PVOID NTAPI FrLdrLoadImage(IN PCHAR szFileName, IN INT nPos, @@ -55,6 +48,7 @@ PFILE FilePointer; PCHAR szShortName; CHAR szBuffer[256], szFullPath[256]; + PVOID LoadBase;
/* Check if this the HAL being loaded */ if (!_stricmp(szFileName, "hal.dll")) @@ -107,11 +101,11 @@ UiDrawStatusText(szBuffer);
/* Do the actual loading */ - FrLdrMapImage(FilePointer, szShortName, ImageType); + LoadBase = FrLdrMapImage(FilePointer, szShortName, ImageType);
/* Update Processbar and return success */ if (!FrLdrBootType) UiDrawProgressBarCenter(nPos, 100, szLoadingMsg); - return TRUE; + return LoadBase; }
static BOOLEAN @@ -497,6 +491,8 @@ CHAR szFileName[255]; CHAR MsgBuffer[256]; ULONG SectionId; + PIMAGE_NT_HEADERS NtHeader; + PVOID LoadBase;
ULONG_PTR Base; ULONG Size; @@ -682,7 +678,14 @@ }
/* Load the kernel */ - if (!FrLdrLoadImage(szKernelName, 5, 1)) return; + LoadBase = FrLdrLoadImage(szKernelName, 5, 1); + if (!LoadBase) return; + + /* Get the NT header, kernel base and kernel entry */ + NtHeader = RtlImageNtHeader(LoadBase); + KernelBase = NtHeader->OptionalHeader.ImageBase; + KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint); + LoaderBlock.KernelBase = KernelBase;
/* * Load the System hive from disk
Modified: trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/reacto... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c (original) +++ trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c Wed Feb 28 22:04:27 2007 @@ -18,7 +18,11 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define _NTSYSTEM_ #include <freeldr.h> + +#define NDEBUG +#include <debug.h>
ROS_LOADER_PARAMETER_BLOCK LoaderBlock; char reactos_kernel_cmdline[255]; // Command line passed to kernel @@ -28,16 +32,10 @@ memory_map_t reactos_memory_map[32]; // Memory map char szBootPath[256]; char szHalName[256]; +extern ULONG_PTR KernelBase, KernelEntry; +
#define USE_UI - -BOOLEAN -NTAPI -FrLdrMapImage( - IN FILE *Image, - IN PCHAR ShortName, - IN ULONG ImageType -);
BOOLEAN NTAPI @@ -47,6 +45,8 @@ PFILE FilePointer; PCHAR szShortName; CHAR szBuffer[256]; + PVOID LoadBase; + PIMAGE_NT_HEADERS NtHeader;
/* Extract Kernel filename without path */ szShortName = strrchr(szFileName, '\'); @@ -78,7 +78,13 @@ UiDrawStatusText(szBuffer);
/* Do the actual loading */ - FrLdrMapImage(FilePointer, szShortName, 1); + LoadBase = FrLdrMapImage(FilePointer, szShortName, 1); + + /* Get the NT header, kernel base and kernel entry */ + NtHeader = RtlImageNtHeader(LoadBase); + KernelBase = NtHeader->OptionalHeader.ImageBase; + KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint); + LoaderBlock.KernelBase = KernelBase;
/* Update Processbar and return success */ return TRUE;
Modified: trunk/reactos/boot/freeldr/freeldr/setupldr_main.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/setupl... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/setupldr_main.rbuild (original) +++ trunk/reactos/boot/freeldr/freeldr/setupldr_main.rbuild Wed Feb 28 22:04:27 2007 @@ -2,7 +2,7 @@ <include base="setupldr_main">include</include> <include base="ntoskrnl">include</include> <define name="__USE_W32API" /> - <compilerflag>-nostdlib</compilerflag> + <define name="_NTHAL_" /> <compilerflag>-ffreestanding</compilerflag> <compilerflag>-fno-builtin</compilerflag> <compilerflag>-fno-inline</compilerflag>
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c?... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/driver.c (original) +++ trunk/reactos/ntoskrnl/io/iomgr/driver.c Wed Feb 28 22:04:27 2007 @@ -30,15 +30,6 @@ POBJECT_TYPE IoDriverObjectType = NULL;
extern BOOLEAN ExpInTextModeSetup; - -/* DECLARATIONS ***************************************************************/ - -NTSTATUS -NTAPI -LdrTemporaryDriverHack( - PLDR_DATA_TABLE_ENTRY ModuleObject, - PUNICODE_STRING ModuleName -);
/* PRIVATE FUNCTIONS **********************************************************/
@@ -810,13 +801,7 @@ &MissingApiName, &MissingDriverName, &LoadedImports); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - ExFreePool(LdrEntry->FullDllName.Buffer); - ExFreePool(LdrEntry); - return Status; - } + if (!NT_SUCCESS(Status)) return Status;
/* Return */ *ModuleObject = LdrEntry;
Modified: trunk/reactos/ntoskrnl/mm/sysldr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/sysldr.c?rev=25... ============================================================================== --- trunk/reactos/ntoskrnl/mm/sysldr.c (original) +++ trunk/reactos/ntoskrnl/mm/sysldr.c Wed Feb 28 22:04:27 2007 @@ -21,6 +21,25 @@ extern ULONG NtGlobalFlag;
/* FUNCTIONS *****************************************************************/ + +VOID +NTAPI +MiFreeBootDriverMemory(PVOID BaseAddress, + ULONG Length) +{ + ULONG i; + + /* Loop each page */ + for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++) + { + /* Free the page */ + MmDeleteVirtualMapping(NULL, + (PVOID)((ULONG_PTR)BaseAddress + i * PAGE_SIZE), + TRUE, + NULL, + NULL); + } +}
NTSTATUS NTAPI @@ -1175,6 +1194,9 @@ LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress + NtHeader->OptionalHeader.AddressOfEntryPoint); LdrEntry->SizeOfImage = LdrEntry->SizeOfImage; + + /* Free the old copy */ + MiFreeBootDriverMemory(DllBase, LdrEntry->SizeOfImage); } }