3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: main.c,v 1.165 2003/07/06 10:25:15 hbirr Exp $
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/main.c
23 * PURPOSE: Initalizes the kernel
24 * PROGRAMMER: David Welch (welch@cwcom.net)
29 /* INCLUDES *****************************************************************/
31 #define NTOS_MODE_KERNEL
33 #include <internal/ntoskrnl.h>
34 #include <reactos/resource.h>
35 #include <internal/mm.h>
36 #include <internal/ifs.h>
37 #include <internal/module.h>
38 #include <internal/ldr.h>
39 #include <internal/ex.h>
40 #include <internal/ps.h>
41 #include <internal/ke.h>
42 #include <internal/io.h>
43 #include <internal/po.h>
44 #include <internal/cc.h>
45 #include <internal/se.h>
46 #include <internal/v86m.h>
47 #include <internal/kd.h>
48 #include <internal/trap.h>
49 #include "../dbg/kdb.h"
50 #include <internal/registry.h>
51 #include <internal/nls.h>
52 #include <reactos/bugcodes.h>
55 #include <internal/ntosdbg.h>
61 #include <internal/debug.h>
63 /* GLOBALS *******************************************************************/
65 ULONG EXPORTED NtBuildNumber
= KERNEL_VERSION_BUILD
;
66 ULONG EXPORTED NtGlobalFlag
= 0;
67 CHAR EXPORTED KeNumberProcessors
;
68 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock
;
69 ULONG EXPORTED KeDcacheFlushCount
= 0;
70 ULONG EXPORTED KeIcacheFlushCount
= 0;
71 static LOADER_MODULE KeLoaderModules
[64];
72 static UCHAR KeLoaderModuleStrings
[64][256];
73 static UCHAR KeLoaderCommandLine
[256];
74 static ADDRESS_RANGE KeMemoryMap
[64];
75 static ULONG KeMemoryMapRangeCount
;
76 static ULONG FirstKrnlPhysAddr
;
77 static ULONG LastKrnlPhysAddr
;
78 static ULONG LastKernelAddress
;
79 volatile BOOLEAN Initialized
= FALSE
;
81 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
84 /* FUNCTIONS ****************************************************************/
87 RtlpCheckFileNameExtension(PCHAR FileName
,
92 Ext
= strrchr(FileName
, '.');
95 if ((Extension
== NULL
) || (*Extension
== 0))
101 if (*Extension
!= '.')
104 if (_stricmp(Ext
, Extension
) == 0)
112 InitSystemSharedUserPage (PCSZ ParameterLine
)
114 UNICODE_STRING ArcDeviceName
;
115 UNICODE_STRING ArcName
;
116 UNICODE_STRING BootPath
;
117 UNICODE_STRING DriveDeviceName
;
118 UNICODE_STRING DriveName
;
119 WCHAR DriveNameBuffer
[20];
121 PWCHAR ArcNameBuffer
;
125 OBJECT_ATTRIBUTES ObjectAttributes
;
128 BOOLEAN BootDriveFound
;
132 * The shared user page has been zeroed-out right after creation.
133 * There is NO need to do this again.
136 SharedUserData
->NtProductType
= NtProductWinNt
;
138 BootDriveFound
= FALSE
;
141 * Retrieve the current dos system path
142 * (e.g.: C:\reactos) from the given arc path
143 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
144 * Format: "<arc_name>\<path> [options...]"
147 /* create local parameter line copy */
148 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
149 strcpy (ParamBuffer
, (char *)ParameterLine
);
150 DPRINT("%s\n", ParamBuffer
);
152 /* cut options off */
153 p
= strchr (ParamBuffer
, ' ');
158 DPRINT("%s\n", ParamBuffer
);
161 p
= strchr (ParamBuffer
, '\\');
164 DPRINT("Boot path: %s\n", p
);
165 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
170 DPRINT("Boot path: %s\n", "\\");
171 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
173 DPRINT("Arc name: %s\n", ParamBuffer
);
175 /* Only arc name left - build full arc name */
176 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
177 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", ParamBuffer
);
178 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
179 DPRINT("Arc name: %wZ\n", &ArcName
);
181 /* free ParamBuffer */
182 ExFreePool (ParamBuffer
);
184 /* allocate arc device name string */
185 ArcDeviceName
.Length
= 0;
186 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
187 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
189 InitializeObjectAttributes (&ObjectAttributes
,
195 Status
= NtOpenSymbolicLinkObject (&Handle
,
196 SYMBOLIC_LINK_ALL_ACCESS
,
198 RtlFreeUnicodeString (&ArcName
);
199 if (!NT_SUCCESS(Status
))
201 RtlFreeUnicodeString (&BootPath
);
202 RtlFreeUnicodeString (&ArcDeviceName
);
203 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
209 Status
= NtQuerySymbolicLinkObject (Handle
,
213 if (!NT_SUCCESS(Status
))
215 RtlFreeUnicodeString (&BootPath
);
216 RtlFreeUnicodeString (&ArcDeviceName
);
217 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
222 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
225 /* allocate device name string */
226 DriveDeviceName
.Length
= 0;
227 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
228 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
230 for (i
= 0; i
< 26; i
++)
232 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
233 RtlInitUnicodeString (&DriveName
,
236 InitializeObjectAttributes (&ObjectAttributes
,
242 Status
= NtOpenSymbolicLinkObject (&Handle
,
243 SYMBOLIC_LINK_ALL_ACCESS
,
245 if (!NT_SUCCESS(Status
))
247 DPRINT("Failed to open link %wZ\n",
252 Status
= NtQuerySymbolicLinkObject (Handle
,
255 if (!NT_SUCCESS(Status
))
257 DPRINT("Failed query open link %wZ\n",
261 DPRINT("Opened link: %wZ ==> %wZ\n",
262 &DriveName
, &DriveDeviceName
);
264 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
))
266 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
267 swprintf(SharedUserData
->NtSystemRoot
,
268 L
"%C:%wZ", 'A' + i
, &BootPath
);
270 BootDriveFound
= TRUE
;
276 RtlFreeUnicodeString (&BootPath
);
277 RtlFreeUnicodeString (&DriveDeviceName
);
278 RtlFreeUnicodeString (&ArcDeviceName
);
280 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData
->DosDeviceMap
);
282 if (BootDriveFound
== FALSE
)
284 DbgPrint("No system drive found!\n");
290 MiFreeBootDriverMemory(PVOID StartAddress
, ULONG Length
)
292 PHYSICAL_ADDRESS Page
;
295 for (i
= 0; i
< PAGE_ROUND_UP(Length
)/PAGE_SIZE
; i
++)
297 Page
= MmGetPhysicalAddressForProcess(NULL
, StartAddress
+ i
* PAGE_SIZE
);
298 MmDeleteVirtualMapping(NULL
, StartAddress
+ i
* PAGE_SIZE
, FALSE
, NULL
, NULL
);
299 MmDereferencePage(Page
);
304 ExpInitializeExecutive(VOID
)
306 LARGE_INTEGER Timeout
;
307 HANDLE ProcessHandle
;
309 ULONG BootDriverCount
;
321 * Fail at runtime if someone has changed various structures without
322 * updating the offsets used for the assembler code.
324 assert(FIELD_OFFSET(KTHREAD
, InitialStack
) == KTHREAD_INITIAL_STACK
);
325 assert(FIELD_OFFSET(KTHREAD
, Teb
) == KTHREAD_TEB
);
326 assert(FIELD_OFFSET(KTHREAD
, KernelStack
) == KTHREAD_KERNEL_STACK
);
327 assert(FIELD_OFFSET(KTHREAD
, ServiceTable
) == KTHREAD_SERVICE_TABLE
);
328 assert(FIELD_OFFSET(KTHREAD
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
329 assert(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
330 assert(FIELD_OFFSET(KTHREAD
, CallbackStack
) == KTHREAD_CALLBACK_STACK
);
331 assert(FIELD_OFFSET(ETHREAD
, ThreadsProcess
) == ETHREAD_THREADS_PROCESS
);
332 assert(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) ==
333 KPROCESS_DIRECTORY_TABLE_BASE
);
334 assert(FIELD_OFFSET(KTRAP_FRAME
, Reserved9
) == KTRAP_FRAME_RESERVED9
);
335 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
336 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
338 assert(FIELD_OFFSET(KPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
339 assert(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
340 assert(FIELD_OFFSET(IKPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
341 assert(FIELD_OFFSET(IKPCR
, Self
) == KPCR_SELF
);
342 assert(FIELD_OFFSET(IKPCR
, CurrentThread
) == KPCR_CURRENT_THREAD
);
346 KeLowerIrql(DISPATCH_LEVEL
);
350 p1
= (PCHAR
)KeLoaderBlock
.CommandLine
;
353 while(*p1
&& (p2
= strchr(p1
, '/')))
356 if (!_strnicmp(p2
, "MAXMEM", 6))
359 while (isspace(*p2
)) p2
++;
363 while(isspace(*p2
)) p2
++;
368 MaxMem
= MaxMem
* 10 + *p2
- '0';
378 MmInit1(FirstKrnlPhysAddr
,
381 (PADDRESS_RANGE
)&KeMemoryMap
,
382 KeMemoryMapRangeCount
,
383 MaxMem
> 8 ? MaxMem
: 4096);
385 /* Import ANSI code page table */
386 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
388 start
= KeLoaderModules
[i
].ModStart
;
389 length
= KeLoaderModules
[i
].ModEnd
- start
;
391 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
394 name
= (PCHAR
)KeLoaderModules
[i
].String
;
401 if (!_stricmp (name
, "ansi.nls"))
403 RtlpImportAnsiCodePage((PUSHORT
)start
, length
);
407 /* Import OEM code page table */
408 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
410 start
= KeLoaderModules
[i
].ModStart
;
411 length
= KeLoaderModules
[i
].ModEnd
- start
;
413 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
416 name
= (PCHAR
)KeLoaderModules
[i
].String
;
423 if (!_stricmp (name
, "oem.nls"))
425 RtlpImportOemCodePage((PUSHORT
)start
, length
);
429 /* Import Unicode casemap table */
430 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
432 start
= KeLoaderModules
[i
].ModStart
;
433 length
= KeLoaderModules
[i
].ModEnd
- start
;
435 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
438 name
= (PCHAR
)KeLoaderModules
[i
].String
;
445 if (!_stricmp (name
, "casemap.nls"))
447 RtlpImportUnicodeCasemap((PUSHORT
)start
, length
);
451 /* Create initial NLS tables */
452 RtlpCreateInitialNlsTables();
455 * Initialize the kernel debugger
457 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
462 KeLowerIrql(PASSIVE_LEVEL
);
465 KeBugCheck(SECURITY_INITIALIZATION_FAILED
);
470 KeBugCheck(SECURITY1_INITIALIZATION_FAILED
);
472 PiInitProcessManager();
476 if (KdPollBreakIn ())
478 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
482 * Display version number and copyright/warranty message
484 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
485 KERNEL_VERSION_BUILD_STR
")\n");
486 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
487 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
488 "Public License, and you\n");
489 HalDisplayString("are welcome to change it and/or distribute copies of it "
491 HalDisplayString("conditions. There is absolutely no warranty for "
494 /* Initialize all processors */
495 KeNumberProcessors
= 0;
497 while (!HalAllProcessorsStarted())
499 PVOID ProcessorStack
;
501 if (KeNumberProcessors
!= 0)
503 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
504 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
506 /* Allocate a stack for use when booting the processor */
507 /* FIXME: The nonpaged memory for the stack is not released after use */
509 ExAllocatePool(NonPagedPool
, MM_STACK_SIZE
) + MM_STACK_SIZE
;
510 Ki386InitialStackArray
[((int)KeNumberProcessors
)] =
511 (PVOID
)(ProcessorStack
- MM_STACK_SIZE
);
512 HalInitializeProcessor(KeNumberProcessors
, ProcessorStack
);
513 KeNumberProcessors
++;
516 if (KeNumberProcessors
> 1)
519 "Found %d system processors. [%lu MB Memory]\n",
521 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
526 "Found 1 system processor. [%lu MB Memory]\n",
527 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
529 HalDisplayString(str
);
532 * Initialize various critical subsystems
534 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
539 LdrInitModuleManagement();
540 CmInitializeRegistry();
545 FsRtlpInitFileLockingImplementation();
547 /* Report all resources used by hal */
548 HalReportResourceUsage();
550 /* Create the NLS section */
551 RtlpCreateNlsSection();
554 * Initalize services loaded at boot time
556 DPRINT("%d files loaded\n",KeLoaderBlock
.ModsCount
);
557 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
559 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
560 KeLoaderModules
[i
].String
,
561 KeLoaderModules
[i
].ModStart
,
562 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
565 /* Pass 1: import system hive registry chunk */
567 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
569 start
= KeLoaderModules
[i
].ModStart
;
570 length
= KeLoaderModules
[i
].ModEnd
- start
;
572 DPRINT("Module: '%s'\n", (PCHAR
)KeLoaderModules
[i
].String
);
573 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
576 name
= (PCHAR
)KeLoaderModules
[i
].String
;
583 if (!_stricmp (name
, "system") ||
584 !_stricmp (name
, "system.hiv"))
586 CPRINT("Process system hive registry chunk at %08lx\n", start
);
588 CmImportSystemHive((PCHAR
)start
, length
);
592 /* Pass 2: import hardware hive registry chunk */
593 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
595 start
= KeLoaderModules
[i
].ModStart
;
596 length
= KeLoaderModules
[i
].ModEnd
- start
;
597 name
= (PCHAR
)KeLoaderModules
[i
].String
;
598 if (!_stricmp (name
, "hardware") ||
599 !_stricmp (name
, "hardware.hiv"))
601 CPRINT("Process hardware hive registry chunk at %08lx\n", start
);
602 CmImportHardwareHive((PCHAR
)start
, length
);
606 /* Create dummy keys if no hardware hive was found */
607 CmImportHardwareHive (NULL
, 0);
609 /* Initialize volatile registry settings */
610 if (SetupBoot
== FALSE
)
612 CmInit2((PCHAR
)KeLoaderBlock
.CommandLine
);
616 * Enter the kernel debugger before starting up the boot drivers
622 IoCreateDriverList();
626 /* Pass 3: process boot loaded drivers */
628 for (i
=1; i
< KeLoaderBlock
.ModsCount
; i
++)
630 start
= KeLoaderModules
[i
].ModStart
;
631 length
= KeLoaderModules
[i
].ModEnd
- start
;
632 name
= (PCHAR
)KeLoaderModules
[i
].String
;
633 if (RtlpCheckFileNameExtension(name
, ".sys") ||
634 RtlpCheckFileNameExtension(name
, ".sym"))
636 CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n",
637 name
, start
, length
);
638 LdrInitializeBootStartDriver((PVOID
)start
, name
, length
);
640 if (RtlpCheckFileNameExtension(name
, ".sys"))
644 /* Pass 4: free memory for all boot files, except ntoskrnl.exe and hal.dll */
645 for (i
= 2; i
< KeLoaderBlock
.ModsCount
; i
++)
648 /* Do not free the memory from symbol files, if the kernel debugger is activ */
649 if (!RtlpCheckFileNameExtension(name
, ".sym"))
652 MiFreeBootDriverMemory((PVOID
)KeLoaderModules
[i
].ModStart
,
653 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
657 if (BootDriverCount
== 0)
659 DbgPrint("No boot drivers available.\n");
663 /* Create ARC names for boot devices */
666 /* Create the SystemRoot symbolic link */
667 CPRINT("CommandLine: %s\n", (PUCHAR
)KeLoaderBlock
.CommandLine
);
668 Status
= IoCreateSystemRootLink((PUCHAR
)KeLoaderBlock
.CommandLine
);
669 if (!NT_SUCCESS(Status
))
670 KeBugCheck(INACCESSIBLE_BOOT_DEVICE
);
672 #ifdef DBGPRINT_FILE_LOG
673 /* On the assumption that we can now access disks start up the debug
676 #endif /* DBGPRINT_FILE_LOG */
683 PiInitDefaultLocale();
686 * Start the motherboard enumerator (the HAL)
688 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
691 * Load boot start drivers
693 IopLoadBootStartDrivers();
696 * Load Auto configured drivers
698 LdrLoadAutoConfigDrivers();
701 IoDestroyDriverList();
704 * Assign drive letters
706 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
712 * Initialize shared user page:
713 * - set dos system path, dos device map, etc.
715 InitSystemSharedUserPage ((PUCHAR
)KeLoaderBlock
.CommandLine
);
718 * Launch initial process
720 Status
= LdrLoadInitialProcess(&ProcessHandle
,
722 if (!NT_SUCCESS(Status
))
724 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
728 * Crash the system if the initial process terminates within 5 seconds.
730 Timeout
.QuadPart
= -50000000LL;
731 Status
= NtWaitForSingleObject(ProcessHandle
,
734 if (Status
!= STATUS_TIMEOUT
)
736 KeBugCheckEx(SESSION5_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
739 NtClose(ThreadHandle
);
740 NtClose(ProcessHandle
);
742 PsTerminateSystemThread(STATUS_SUCCESS
);
747 KiSystemStartup(BOOLEAN BootProcessor
)
749 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
754 ExpInitializeExecutive();
757 /* Do application processor initialization */
758 KeApplicationProcessorInit();
759 PsApplicationProcessorInit();
760 KeLowerIrql(PASSIVE_LEVEL
);
761 PsIdleThreadMain(NULL
);
767 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
769 * FUNCTION: Called by the boot loader to start the kernel
771 * LoaderBlock = Pointer to boot parameters initialized by the boot
773 * NOTE: The boot parameters are stored in low memory which will become
774 * invalid after the memory managment is initialized so we make a local copy.
779 ULONG last_kernel_address
;
780 extern ULONG _bss_end__
;
785 /* Low level architecture specific initialization */
789 * Copy the parameters to a local buffer because lowmem will go away
791 memcpy(&KeLoaderBlock
, _LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
792 memcpy(&KeLoaderModules
[1], (PVOID
)KeLoaderBlock
.ModsAddr
,
793 sizeof(LOADER_MODULE
) * KeLoaderBlock
.ModsCount
);
794 KeLoaderBlock
.ModsCount
++;
795 KeLoaderBlock
.ModsAddr
= (ULONG
)&KeLoaderModules
;
798 * Convert a path specification in the grub format to one understood by the
799 * rest of the kernel.
801 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[0] == '(')
803 ULONG DiskNumber
= 0, PartNumber
= 0;
809 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[1] == 'h' &&
810 ((PUCHAR
)_LoaderBlock
->CommandLine
)[2] == 'd')
812 DiskNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[3] - '0';
813 PartNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[5] - '0';
815 strcpy(Temp
, &((PUCHAR
)_LoaderBlock
->CommandLine
)[7]);
816 if ((options
= strchr(Temp
, ' ')) != NULL
)
825 if ((s1
= strrchr(Temp
, '/')) != NULL
)
828 if ((s1
= strrchr(Temp
, '/')) != NULL
)
833 sprintf(KeLoaderCommandLine
,
834 "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s",
835 DiskNumber
, PartNumber
+ 1, Temp
, options
);
837 p
= KeLoaderCommandLine
;
838 while (*p
!= 0 && *p
!= ' ')
846 DPRINT1("Command Line: %s\n", KeLoaderCommandLine
);
850 strcpy(KeLoaderCommandLine
, (PUCHAR
)_LoaderBlock
->CommandLine
);
852 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
854 strcpy(KeLoaderModuleStrings
[0], "ntoskrnl.exe");
855 KeLoaderModules
[0].String
= (ULONG
)KeLoaderModuleStrings
[0];
856 KeLoaderModules
[0].ModStart
= 0xC0000000;
857 KeLoaderModules
[0].ModEnd
= PAGE_ROUND_UP((ULONG
)&_bss_end__
);
858 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
861 if ((s
= strrchr((PUCHAR
)KeLoaderModules
[i
].String
, '/')) != 0)
863 strcpy(KeLoaderModuleStrings
[i
], s
+ 1);
867 strcpy(KeLoaderModuleStrings
[i
], (PUCHAR
)KeLoaderModules
[i
].String
);
869 KeLoaderModules
[i
].ModStart
-= 0x200000;
870 KeLoaderModules
[i
].ModStart
+= 0xc0000000;
871 KeLoaderModules
[i
].ModEnd
-= 0x200000;
872 KeLoaderModules
[i
].ModEnd
+= 0xc0000000;
873 KeLoaderModules
[i
].String
= (ULONG
)KeLoaderModuleStrings
[i
];
877 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
880 HalBase
= KeLoaderModules
[1].ModStart
;
882 PAGE_ROUND_UP(KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
);
887 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)0xC0000000, &DriverSize
);
889 LdrHalBase
= (ULONG_PTR
)DriverBase
;
890 last_kernel_address
= DriverBase
+ DriverSize
;
893 * Process ntoskrnl.exe
895 LdrSafePEProcessModule((PVOID
)0xC0000000, (PVOID
)0xC0000000, (PVOID
)DriverBase
, &DriverSize
);
897 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- 0xc0000000 + 0x200000;
898 LastKrnlPhysAddr
= last_kernel_address
- 0xc0000000 + 0x200000;
899 LastKernelAddress
= last_kernel_address
;
902 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
903 KeLoaderBlock
.Flags
&= ~MB_FLAGS_MMAP_INFO
;
906 KeMemoryMapRangeCount
= 0;
907 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
909 /* We have a memory map from the nice BIOS */
910 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
912 while (i
< KeLoaderBlock
.MmapLength
)
914 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
915 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
916 sizeof(ADDRESS_RANGE
));
917 KeMemoryMapRangeCount
++;