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.179 2003/12/14 18:16:18 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/nls.h>
51 #include <reactos/bugcodes.h>
52 #include <ntos/bootvid.h>
53 #include <napi/core.h>
56 #include <internal/ntosdbg.h>
62 #include <internal/debug.h>
64 /* GLOBALS *******************************************************************/
66 ULONG EXPORTED NtBuildNumber
= KERNEL_VERSION_BUILD
;
67 ULONG EXPORTED NtGlobalFlag
= 0;
68 CHAR EXPORTED KeNumberProcessors
;
69 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock
;
70 ULONG EXPORTED KeDcacheFlushCount
= 0;
71 ULONG EXPORTED KeIcacheFlushCount
= 0;
72 static LOADER_MODULE KeLoaderModules
[64];
73 static UCHAR KeLoaderModuleStrings
[64][256];
74 static UCHAR KeLoaderCommandLine
[256];
75 static ADDRESS_RANGE KeMemoryMap
[64];
76 static ULONG KeMemoryMapRangeCount
;
77 static ULONG FirstKrnlPhysAddr
;
78 static ULONG LastKrnlPhysAddr
;
79 static ULONG LastKernelAddress
;
80 volatile BOOLEAN Initialized
= FALSE
;
81 extern ULONG MmCoreDumpType
;
83 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
86 /* FUNCTIONS ****************************************************************/
88 static VOID INIT_FUNCTION
89 InitSystemSharedUserPage (PCSZ ParameterLine
)
91 UNICODE_STRING ArcDeviceName
;
92 UNICODE_STRING ArcName
;
93 UNICODE_STRING BootPath
;
94 UNICODE_STRING DriveDeviceName
;
95 UNICODE_STRING DriveName
;
96 WCHAR DriveNameBuffer
[20];
102 OBJECT_ATTRIBUTES ObjectAttributes
;
105 BOOLEAN BootDriveFound
;
109 * The shared user page has been zeroed-out right after creation.
110 * There is NO need to do this again.
113 SharedUserData
->NtProductType
= NtProductWinNt
;
115 BootDriveFound
= FALSE
;
118 * Retrieve the current dos system path
119 * (e.g.: C:\reactos) from the given arc path
120 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
121 * Format: "<arc_name>\<path> [options...]"
124 /* create local parameter line copy */
125 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
126 strcpy (ParamBuffer
, (char *)ParameterLine
);
127 DPRINT("%s\n", ParamBuffer
);
129 /* cut options off */
130 p
= strchr (ParamBuffer
, ' ');
135 DPRINT("%s\n", ParamBuffer
);
138 p
= strchr (ParamBuffer
, '\\');
141 DPRINT("Boot path: %s\n", p
);
142 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
147 DPRINT("Boot path: %s\n", "\\");
148 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
150 DPRINT("Arc name: %s\n", ParamBuffer
);
152 /* Only arc name left - build full arc name */
153 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
154 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", ParamBuffer
);
155 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
156 DPRINT("Arc name: %wZ\n", &ArcName
);
158 /* free ParamBuffer */
159 ExFreePool (ParamBuffer
);
161 /* allocate arc device name string */
162 ArcDeviceName
.Length
= 0;
163 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
164 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
166 InitializeObjectAttributes (&ObjectAttributes
,
172 Status
= NtOpenSymbolicLinkObject (&Handle
,
173 SYMBOLIC_LINK_ALL_ACCESS
,
175 RtlFreeUnicodeString (&ArcName
);
176 if (!NT_SUCCESS(Status
))
178 RtlFreeUnicodeString (&BootPath
);
179 RtlFreeUnicodeString (&ArcDeviceName
);
180 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
186 Status
= NtQuerySymbolicLinkObject (Handle
,
190 if (!NT_SUCCESS(Status
))
192 RtlFreeUnicodeString (&BootPath
);
193 RtlFreeUnicodeString (&ArcDeviceName
);
194 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
199 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
202 /* allocate device name string */
203 DriveDeviceName
.Length
= 0;
204 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
205 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
207 for (i
= 0; i
< 26; i
++)
209 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
210 RtlInitUnicodeString (&DriveName
,
213 InitializeObjectAttributes (&ObjectAttributes
,
219 Status
= NtOpenSymbolicLinkObject (&Handle
,
220 SYMBOLIC_LINK_ALL_ACCESS
,
222 if (!NT_SUCCESS(Status
))
224 DPRINT("Failed to open link %wZ\n",
229 Status
= NtQuerySymbolicLinkObject (Handle
,
232 if (!NT_SUCCESS(Status
))
234 DPRINT("Failed query open link %wZ\n",
238 DPRINT("Opened link: %wZ ==> %wZ\n",
239 &DriveName
, &DriveDeviceName
);
241 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
))
243 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
244 swprintf(SharedUserData
->NtSystemRoot
,
245 L
"%C:%wZ", 'A' + i
, &BootPath
);
247 BootDriveFound
= TRUE
;
253 RtlFreeUnicodeString (&BootPath
);
254 RtlFreeUnicodeString (&DriveDeviceName
);
255 RtlFreeUnicodeString (&ArcDeviceName
);
257 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData
->DosDeviceMap
);
259 if (BootDriveFound
== FALSE
)
261 DbgPrint("No system drive found!\n");
267 ExpInitializeExecutive(VOID
)
269 LARGE_INTEGER Timeout
;
270 HANDLE ProcessHandle
;
281 BOOLEAN NoBootScreen
= FALSE
;
283 HANDLE InitDoneEventHandle
;
284 OBJECT_ATTRIBUTES ObjectAttributes
;
287 * Fail at runtime if someone has changed various structures without
288 * updating the offsets used for the assembler code.
290 assert(FIELD_OFFSET(KTHREAD
, InitialStack
) == KTHREAD_INITIAL_STACK
);
291 assert(FIELD_OFFSET(KTHREAD
, Teb
) == KTHREAD_TEB
);
292 assert(FIELD_OFFSET(KTHREAD
, KernelStack
) == KTHREAD_KERNEL_STACK
);
293 assert(FIELD_OFFSET(KTHREAD
, ServiceTable
) == KTHREAD_SERVICE_TABLE
);
294 assert(FIELD_OFFSET(KTHREAD
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
295 assert(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
296 assert(FIELD_OFFSET(KTHREAD
, CallbackStack
) == KTHREAD_CALLBACK_STACK
);
297 assert(FIELD_OFFSET(ETHREAD
, ThreadsProcess
) == ETHREAD_THREADS_PROCESS
);
298 assert(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) ==
299 KPROCESS_DIRECTORY_TABLE_BASE
);
300 assert(FIELD_OFFSET(KPROCESS
, IopmOffset
) == KPROCESS_IOPM_OFFSET
);
301 assert(FIELD_OFFSET(KPROCESS
, LdtDescriptor
) == KPROCESS_LDT_DESCRIPTOR0
);
302 assert(FIELD_OFFSET(KTRAP_FRAME
, Reserved9
) == KTRAP_FRAME_RESERVED9
);
303 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
304 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
306 assert(FIELD_OFFSET(KPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
307 assert(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
308 assert(FIELD_OFFSET(IKPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
309 assert(FIELD_OFFSET(IKPCR
, Self
) == KPCR_SELF
);
310 assert(FIELD_OFFSET(IKPCR
, CurrentThread
) == KPCR_CURRENT_THREAD
);
314 KeLowerIrql(DISPATCH_LEVEL
);
318 p1
= (PCHAR
)KeLoaderBlock
.CommandLine
;
321 while(*p1
&& (p2
= strchr(p1
, '/')))
324 if (!_strnicmp(p2
, "MAXMEM", 6))
327 while (isspace(*p2
)) p2
++;
331 while(isspace(*p2
)) p2
++;
336 MaxMem
= MaxMem
* 10 + *p2
- '0';
343 else if (!_strnicmp(p2
, "NOBOOTSCREEN", 12))
348 else if (!_strnicmp(p2
, "CRASHDUMP", 9))
354 if (!_strnicmp(p2
, "FULL", 4))
356 MmCoreDumpType
= MM_CORE_DUMP_TYPE_FULL
;
360 MmCoreDumpType
= MM_CORE_DUMP_TYPE_NONE
;
367 MmInit1(FirstKrnlPhysAddr
,
370 (PADDRESS_RANGE
)&KeMemoryMap
,
371 KeMemoryMapRangeCount
,
372 MaxMem
> 8 ? MaxMem
: 4096);
374 /* Import ANSI code page table */
375 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
377 start
= KeLoaderModules
[i
].ModStart
;
378 length
= KeLoaderModules
[i
].ModEnd
- start
;
380 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
383 name
= (PCHAR
)KeLoaderModules
[i
].String
;
390 if (!_stricmp (name
, "ansi.nls"))
392 RtlpImportAnsiCodePage((PUSHORT
)start
, length
);
396 /* Import OEM code page table */
397 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
399 start
= KeLoaderModules
[i
].ModStart
;
400 length
= KeLoaderModules
[i
].ModEnd
- start
;
402 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
405 name
= (PCHAR
)KeLoaderModules
[i
].String
;
412 if (!_stricmp (name
, "oem.nls"))
414 RtlpImportOemCodePage((PUSHORT
)start
, length
);
418 /* Import Unicode casemap table */
419 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
421 start
= KeLoaderModules
[i
].ModStart
;
422 length
= KeLoaderModules
[i
].ModEnd
- start
;
424 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
427 name
= (PCHAR
)KeLoaderModules
[i
].String
;
434 if (!_stricmp (name
, "casemap.nls"))
436 RtlpImportUnicodeCasemap((PUSHORT
)start
, length
);
440 /* Create initial NLS tables */
441 RtlpCreateInitialNlsTables();
444 * Initialize the kernel debugger
446 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
450 KeLowerIrql(PASSIVE_LEVEL
);
453 KEBUGCHECK(SECURITY_INITIALIZATION_FAILED
);
460 KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED
);
462 PiInitProcessManager();
464 if (KdPollBreakIn ())
466 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
469 /* Initialize all processors */
470 KeNumberProcessors
= 0;
472 while (!HalAllProcessorsStarted())
474 PVOID ProcessorStack
;
476 if (KeNumberProcessors
!= 0)
478 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
479 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
481 /* Allocate a stack for use when booting the processor */
482 /* FIXME: The nonpaged memory for the stack is not released after use */
484 ExAllocatePool(NonPagedPool
, MM_STACK_SIZE
) + MM_STACK_SIZE
;
485 Ki386InitialStackArray
[((int)KeNumberProcessors
)] =
486 (PVOID
)(ProcessorStack
- MM_STACK_SIZE
);
487 HalInitializeProcessor(KeNumberProcessors
, ProcessorStack
);
488 KeNumberProcessors
++;
492 * Initialize various critical subsystems
494 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
500 LdrInitModuleManagement();
501 CmInitializeRegistry();
506 FsRtlpInitFileLockingImplementation();
508 /* Report all resources used by hal */
509 HalReportResourceUsage();
512 * Clear the screen to blue
514 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
517 * Display version number and copyright/warranty message
519 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
520 KERNEL_VERSION_BUILD_STR
")\n");
521 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
522 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
523 "Public License, and you\n");
524 HalDisplayString("are welcome to change it and/or distribute copies of it "
526 HalDisplayString("conditions. There is absolutely no warranty for "
529 if (KeNumberProcessors
> 1)
532 "Found %d system processors. [%lu MB Memory]\n",
534 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
539 "Found 1 system processor. [%lu MB Memory]\n",
540 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
542 HalDisplayString(str
);
547 /* Create the NLS section */
548 RtlpCreateNlsSection();
551 * Initalize services loaded at boot time
553 DPRINT("%d files loaded\n",KeLoaderBlock
.ModsCount
);
554 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
556 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
557 KeLoaderModules
[i
].String
,
558 KeLoaderModules
[i
].ModStart
,
559 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
562 /* Pass 1: import system hive registry chunk */
564 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
566 start
= KeLoaderModules
[i
].ModStart
;
567 length
= KeLoaderModules
[i
].ModEnd
- start
;
569 DPRINT("Module: '%s'\n", (PCHAR
)KeLoaderModules
[i
].String
);
570 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
573 name
= (PCHAR
)KeLoaderModules
[i
].String
;
580 if (!_stricmp (name
, "system") ||
581 !_stricmp (name
, "system.hiv"))
583 CPRINT("Process system hive registry chunk at %08lx\n", start
);
585 CmImportSystemHive((PCHAR
)start
, length
);
589 /* Pass 2: import hardware hive registry chunk */
590 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
592 start
= KeLoaderModules
[i
].ModStart
;
593 length
= KeLoaderModules
[i
].ModEnd
- start
;
594 name
= (PCHAR
)KeLoaderModules
[i
].String
;
595 if (!_stricmp (name
, "hardware") ||
596 !_stricmp (name
, "hardware.hiv"))
598 CPRINT("Process hardware hive registry chunk at %08lx\n", start
);
599 CmImportHardwareHive((PCHAR
)start
, length
);
603 /* Create dummy keys if no hardware hive was found */
604 CmImportHardwareHive (NULL
, 0);
606 /* Initialize volatile registry settings */
607 if (SetupBoot
== FALSE
)
609 CmInit2((PCHAR
)KeLoaderBlock
.CommandLine
);
613 * Enter the kernel debugger before starting up the boot drivers
619 IoCreateDriverList();
624 * Load boot start drivers
626 IopInitializeBootDrivers();
628 /* Display the boot screen image if not disabled */
631 InbvEnableBootDriver(TRUE
);
634 /* Create ARC names for boot devices */
637 /* Create the SystemRoot symbolic link */
638 CPRINT("CommandLine: %s\n", (PUCHAR
)KeLoaderBlock
.CommandLine
);
639 Status
= IoCreateSystemRootLink((PUCHAR
)KeLoaderBlock
.CommandLine
);
640 if (!NT_SUCCESS(Status
))
641 KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE
);
643 #ifdef DBGPRINT_FILE_LOG
644 /* On the assumption that we can now access disks start up the debug
647 #endif /* DBGPRINT_FILE_LOG */
653 PiInitDefaultLocale();
656 * Load services for devices found by PnP manager
658 IopInitializePnpServices(IopRootDeviceNode
, FALSE
);
661 * Load system start drivers
663 IopInitializeSystemDrivers();
665 IoDestroyDriverList();
668 * Assign drive letters
670 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
676 * Initialize shared user page:
677 * - set dos system path, dos device map, etc.
679 InitSystemSharedUserPage ((PUCHAR
)KeLoaderBlock
.CommandLine
);
681 /* Create 'ReactOSInitDone' event */
682 RtlInitUnicodeString(&Name
, L
"\\ReactOSInitDone");
683 InitializeObjectAttributes(&ObjectAttributes
,
688 Status
= NtCreateEvent(&InitDoneEventHandle
,
691 FALSE
, /* Synchronization event */
692 FALSE
); /* Not signalled */
693 if (!NT_SUCCESS(Status
))
695 DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status
);
696 InitDoneEventHandle
= INVALID_HANDLE_VALUE
;
700 * Launch initial process
702 Status
= LdrLoadInitialProcess(&ProcessHandle
,
704 if (!NT_SUCCESS(Status
))
706 KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
709 if (InitDoneEventHandle
!= INVALID_HANDLE_VALUE
)
711 HANDLE Handles
[2]; /* Init event, Initial process */
713 Handles
[0] = InitDoneEventHandle
;
714 Handles
[1] = ProcessHandle
;
716 /* Wait for the system to be initialized */
717 Timeout
.QuadPart
= -1200000000LL; /* 120 second timeout */
718 Status
= NtWaitForMultipleObjects(((LONG
) sizeof(Handles
) / sizeof(HANDLE
)),
721 FALSE
, /* Non-alertable */
723 if (!NT_SUCCESS(Status
))
725 DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status
);
727 else if (Status
== STATUS_TIMEOUT
)
729 DPRINT1("WARNING: System not initialized after 120 seconds.\n");
731 else if (Status
== STATUS_WAIT_0
+ 1)
734 * Crash the system if the initial process was terminated.
736 KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
741 InbvEnableBootDriver(FALSE
);
744 NtSetEvent(InitDoneEventHandle
, NULL
);
746 NtClose(InitDoneEventHandle
);
750 /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
753 InbvEnableBootDriver(FALSE
);
757 * Crash the system if the initial process terminates within 5 seconds.
759 Timeout
.QuadPart
= -50000000LL;
760 Status
= NtWaitForSingleObject(ProcessHandle
,
763 if (Status
!= STATUS_TIMEOUT
)
765 KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
769 NtClose(ThreadHandle
);
770 NtClose(ProcessHandle
);
775 KiSystemStartup(BOOLEAN BootProcessor
)
777 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
781 ExpInitializeExecutive();
784 PsTerminateSystemThread(STATUS_SUCCESS
);
787 /* Do application processor initialization */
788 KeApplicationProcessorInit();
789 PsApplicationProcessorInit();
790 KeLowerIrql(PASSIVE_LEVEL
);
791 PsIdleThreadMain(NULL
);
798 * INIT_FUNCTION is temporary disabled, because if ntoskrnl is compiled with
799 * higher optimisation levels, gcc puts directly some code from KiSystemStartup
800 * into _main. This code frees the memory from the init section (_main) and
801 * that does crash reactos.
803 VOID
/*INIT_FUNCTION*/
804 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
806 * FUNCTION: Called by the boot loader to start the kernel
808 * LoaderBlock = Pointer to boot parameters initialized by the boot
810 * NOTE: The boot parameters are stored in low memory which will become
811 * invalid after the memory managment is initialized so we make a local copy.
816 ULONG last_kernel_address
;
817 extern ULONG _bss_end__
;
822 /* Low level architecture specific initialization */
826 * Copy the parameters to a local buffer because lowmem will go away
828 memcpy(&KeLoaderBlock
, _LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
829 memcpy(&KeLoaderModules
[1], (PVOID
)KeLoaderBlock
.ModsAddr
,
830 sizeof(LOADER_MODULE
) * KeLoaderBlock
.ModsCount
);
831 KeLoaderBlock
.ModsCount
++;
832 KeLoaderBlock
.ModsAddr
= (ULONG
)&KeLoaderModules
;
835 * Convert a path specification in the grub format to one understood by the
836 * rest of the kernel.
838 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[0] == '(')
840 ULONG DiskNumber
= 0, PartNumber
= 0;
846 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[1] == 'h' &&
847 ((PUCHAR
)_LoaderBlock
->CommandLine
)[2] == 'd')
849 DiskNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[3] - '0';
850 PartNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[5] - '0';
852 strcpy(Temp
, &((PUCHAR
)_LoaderBlock
->CommandLine
)[7]);
853 if ((options
= strchr(Temp
, ' ')) != NULL
)
862 if ((s1
= strrchr(Temp
, '/')) != NULL
)
865 if ((s1
= strrchr(Temp
, '/')) != NULL
)
870 sprintf(KeLoaderCommandLine
,
871 "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s",
872 DiskNumber
, PartNumber
+ 1, Temp
, options
);
874 p
= KeLoaderCommandLine
;
875 while (*p
!= 0 && *p
!= ' ')
883 DPRINT1("Command Line: %s\n", KeLoaderCommandLine
);
887 strcpy(KeLoaderCommandLine
, (PUCHAR
)_LoaderBlock
->CommandLine
);
889 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
891 strcpy(KeLoaderModuleStrings
[0], "ntoskrnl.exe");
892 KeLoaderModules
[0].String
= (ULONG
)KeLoaderModuleStrings
[0];
893 KeLoaderModules
[0].ModStart
= 0xC0000000;
894 KeLoaderModules
[0].ModEnd
= PAGE_ROUND_UP((ULONG
)&_bss_end__
);
895 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
898 if ((s
= strrchr((PUCHAR
)KeLoaderModules
[i
].String
, '/')) != 0)
900 strcpy(KeLoaderModuleStrings
[i
], s
+ 1);
904 strcpy(KeLoaderModuleStrings
[i
], (PUCHAR
)KeLoaderModules
[i
].String
);
906 KeLoaderModules
[i
].ModStart
-= 0x200000;
907 KeLoaderModules
[i
].ModStart
+= 0xc0000000;
908 KeLoaderModules
[i
].ModEnd
-= 0x200000;
909 KeLoaderModules
[i
].ModEnd
+= 0xc0000000;
910 KeLoaderModules
[i
].String
= (ULONG
)KeLoaderModuleStrings
[i
];
914 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
917 HalBase
= KeLoaderModules
[1].ModStart
;
919 PAGE_ROUND_UP(KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
);
924 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)0xC0000000, &DriverSize
);
926 LdrHalBase
= (ULONG_PTR
)DriverBase
;
927 last_kernel_address
= DriverBase
+ DriverSize
;
930 * Process ntoskrnl.exe
932 LdrSafePEProcessModule((PVOID
)0xC0000000, (PVOID
)0xC0000000, (PVOID
)DriverBase
, &DriverSize
);
934 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- 0xc0000000 + 0x200000;
935 LastKrnlPhysAddr
= last_kernel_address
- 0xc0000000 + 0x200000;
936 LastKernelAddress
= last_kernel_address
;
939 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
940 KeLoaderBlock
.Flags
&= ~MB_FLAGS_MMAP_INFO
;
943 KeMemoryMapRangeCount
= 0;
944 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
946 /* We have a memory map from the nice BIOS */
947 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
949 while (i
< KeLoaderBlock
.MmapLength
)
951 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
952 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
953 sizeof(ADDRESS_RANGE
));
954 KeMemoryMapRangeCount
++;