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.161 2003/06/14 17:46:24 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
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
328 assert(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
329 assert(FIELD_OFFSET(KTHREAD
, CallbackStack
) == KTHREAD_CALLBACK_STACK
);
330 assert(FIELD_OFFSET(ETHREAD
, ThreadsProcess
) == ETHREAD_THREADS_PROCESS
);
331 assert(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) ==
332 KPROCESS_DIRECTORY_TABLE_BASE
);
333 assert(FIELD_OFFSET(KTRAP_FRAME
, Reserved9
) == KTRAP_FRAME_RESERVED9
);
334 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
335 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
337 assert(FIELD_OFFSET(KPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
338 assert(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
339 assert(FIELD_OFFSET(IKPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
340 assert(FIELD_OFFSET(IKPCR
, Self
) == KPCR_SELF
);
341 assert(FIELD_OFFSET(IKPCR
, CurrentThread
) == KPCR_CURRENT_THREAD
);
345 KeLowerIrql(DISPATCH_LEVEL
);
349 p1
= (PCHAR
)KeLoaderBlock
.CommandLine
;
352 while(*p1
&& (p2
= strchr(p1
, '/')))
355 if (!_strnicmp(p2
, "MAXMEM", 6))
358 while (isspace(*p2
)) p2
++;
362 while(isspace(*p2
)) p2
++;
367 MaxMem
= MaxMem
* 10 + *p2
- '0';
377 MmInit1(FirstKrnlPhysAddr
,
380 (PADDRESS_RANGE
)&KeMemoryMap
,
381 KeMemoryMapRangeCount
,
382 MaxMem
> 8 ? MaxMem
: 4096);
384 /* Import ANSI code page table */
385 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
387 start
= KeLoaderModules
[i
].ModStart
;
388 length
= KeLoaderModules
[i
].ModEnd
- start
;
390 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
393 name
= (PCHAR
)KeLoaderModules
[i
].String
;
400 if (!_stricmp (name
, "ansi.nls"))
402 RtlpImportAnsiCodePage((PUSHORT
)start
, length
);
406 /* Import OEM code page table */
407 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
409 start
= KeLoaderModules
[i
].ModStart
;
410 length
= KeLoaderModules
[i
].ModEnd
- start
;
412 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
415 name
= (PCHAR
)KeLoaderModules
[i
].String
;
422 if (!_stricmp (name
, "oem.nls"))
424 RtlpImportOemCodePage((PUSHORT
)start
, length
);
428 /* Import Unicode casemap table */
429 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
431 start
= KeLoaderModules
[i
].ModStart
;
432 length
= KeLoaderModules
[i
].ModEnd
- start
;
434 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
437 name
= (PCHAR
)KeLoaderModules
[i
].String
;
444 if (!_stricmp (name
, "casemap.nls"))
446 RtlpImportUnicodeCasemap((PUSHORT
)start
, length
);
450 /* Create initial NLS tables */
451 RtlpCreateInitialNlsTables();
454 * Initialize the kernel debugger
456 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
461 KeLowerIrql(PASSIVE_LEVEL
);
464 KeBugCheck(SECURITY_INITIALIZATION_FAILED
);
469 KeBugCheck(SECURITY1_INITIALIZATION_FAILED
);
471 PiInitProcessManager();
475 if (KdPollBreakIn ())
477 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
481 * Display version number and copyright/warranty message
483 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
484 KERNEL_VERSION_BUILD_STR
")\n");
485 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
486 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
487 "Public License, and you\n");
488 HalDisplayString("are welcome to change it and/or distribute copies of it "
490 HalDisplayString("conditions. There is absolutely no warranty for "
493 /* Initialize all processors */
494 KeNumberProcessors
= 0;
496 while (!HalAllProcessorsStarted())
498 PVOID ProcessorStack
;
500 if (KeNumberProcessors
!= 0)
502 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
503 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
505 /* Allocate a stack for use when booting the processor */
506 /* FIXME: The nonpaged memory for the stack is not released after use */
508 ExAllocatePool(NonPagedPool
, MM_STACK_SIZE
) + MM_STACK_SIZE
;
509 Ki386InitialStackArray
[((int)KeNumberProcessors
)] =
510 (PVOID
)(ProcessorStack
- MM_STACK_SIZE
);
511 HalInitializeProcessor(KeNumberProcessors
, ProcessorStack
);
512 KeNumberProcessors
++;
515 if (KeNumberProcessors
> 1)
518 "Found %d system processors. [%lu MB Memory]\n",
520 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
525 "Found 1 system processor. [%lu MB Memory]\n",
526 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
528 HalDisplayString(str
);
531 * Initialize various critical subsystems
533 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
538 LdrInitModuleManagement();
539 CmInitializeRegistry();
544 FsRtlpInitFileLockingImplementation();
546 /* Report all resources used by hal */
547 HalReportResourceUsage();
549 /* Create the NLS section */
550 RtlpCreateNlsSection();
553 * Initalize services loaded at boot time
555 DPRINT("%d files loaded\n",KeLoaderBlock
.ModsCount
);
556 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
558 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
559 KeLoaderModules
[i
].String
,
560 KeLoaderModules
[i
].ModStart
,
561 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
564 /* Pass 1: import system hive registry chunk */
566 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
568 start
= KeLoaderModules
[i
].ModStart
;
569 length
= KeLoaderModules
[i
].ModEnd
- start
;
571 DPRINT("Module: '%s'\n", (PCHAR
)KeLoaderModules
[i
].String
);
572 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
575 name
= (PCHAR
)KeLoaderModules
[i
].String
;
582 if (!_stricmp (name
, "system") ||
583 !_stricmp (name
, "system.hiv"))
585 CPRINT("Process system hive registry chunk at %08lx\n", start
);
587 CmImportSystemHive((PCHAR
)start
, length
);
591 /* Pass 2: import hardware hive registry chunk */
592 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
594 start
= KeLoaderModules
[i
].ModStart
;
595 length
= KeLoaderModules
[i
].ModEnd
- start
;
596 name
= (PCHAR
)KeLoaderModules
[i
].String
;
597 if (!_stricmp (name
, "hardware") ||
598 !_stricmp (name
, "hardware.hiv"))
600 CPRINT("Process hardware hive registry chunk at %08lx\n", start
);
601 CmImportHardwareHive((PCHAR
)start
, length
);
605 /* Create dummy keys if no hardware hive was found */
606 CmImportHardwareHive (NULL
, 0);
608 /* Initialize volatile registry settings */
609 if (SetupBoot
== FALSE
)
611 CmInit2((PCHAR
)KeLoaderBlock
.CommandLine
);
615 * Enter the kernel debugger before starting up the boot drivers
621 IoCreateDriverList();
625 /* Pass 3: process boot loaded drivers */
627 for (i
=1; i
< KeLoaderBlock
.ModsCount
; i
++)
629 start
= KeLoaderModules
[i
].ModStart
;
630 length
= KeLoaderModules
[i
].ModEnd
- start
;
631 name
= (PCHAR
)KeLoaderModules
[i
].String
;
632 if (RtlpCheckFileNameExtension(name
, ".sys") ||
633 RtlpCheckFileNameExtension(name
, ".sym"))
635 CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n",
636 name
, start
, length
);
637 LdrInitializeBootStartDriver((PVOID
)start
, name
, length
);
639 if (RtlpCheckFileNameExtension(name
, ".sys"))
643 /* Pass 4: free memory for all boot files, except ntoskrnl.exe and hal.dll */
644 for (i
= 2; i
< KeLoaderBlock
.ModsCount
; i
++)
646 MiFreeBootDriverMemory((PVOID
)KeLoaderModules
[i
].ModStart
,
647 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
650 if (BootDriverCount
== 0)
652 DbgPrint("No boot drivers available.\n");
656 /* Create ARC names for boot devices */
659 /* Create the SystemRoot symbolic link */
660 CPRINT("CommandLine: %s\n", (PUCHAR
)KeLoaderBlock
.CommandLine
);
661 Status
= IoCreateSystemRootLink((PUCHAR
)KeLoaderBlock
.CommandLine
);
662 if (!NT_SUCCESS(Status
))
663 KeBugCheck(INACCESSIBLE_BOOT_DEVICE
);
665 #ifdef DBGPRINT_FILE_LOG
666 /* On the assumption that we can now access disks start up the debug
669 #endif /* DBGPRINT_FILE_LOG */
676 PiInitDefaultLocale();
679 * Start the motherboard enumerator (the HAL)
681 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
684 * Load boot start drivers
686 IopLoadBootStartDrivers();
689 * Load Auto configured drivers
691 LdrLoadAutoConfigDrivers();
694 IoDestroyDriverList();
697 * Assign drive letters
699 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
705 * Initialize shared user page:
706 * - set dos system path, dos device map, etc.
708 InitSystemSharedUserPage ((PUCHAR
)KeLoaderBlock
.CommandLine
);
711 * Launch initial process
713 Status
= LdrLoadInitialProcess(&ProcessHandle
,
715 if (!NT_SUCCESS(Status
))
717 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
721 * Crash the system if the initial process terminates within 5 seconds.
723 Timeout
.QuadPart
= -50000000LL;
724 Status
= NtWaitForSingleObject(ProcessHandle
,
727 if (Status
!= STATUS_TIMEOUT
)
729 KeBugCheckEx(SESSION5_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
732 NtClose(ThreadHandle
);
733 NtClose(ProcessHandle
);
735 PsTerminateSystemThread(STATUS_SUCCESS
);
740 KiSystemStartup(BOOLEAN BootProcessor
)
742 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
747 ExpInitializeExecutive();
750 /* Do application processor initialization */
751 KeApplicationProcessorInit();
752 PsApplicationProcessorInit();
753 KeLowerIrql(PASSIVE_LEVEL
);
754 PsIdleThreadMain(NULL
);
760 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
762 * FUNCTION: Called by the boot loader to start the kernel
764 * LoaderBlock = Pointer to boot parameters initialized by the boot
766 * NOTE: The boot parameters are stored in low memory which will become
767 * invalid after the memory managment is initialized so we make a local copy.
772 ULONG last_kernel_address
;
773 extern ULONG _bss_end__
;
778 /* Low level architecture specific initialization */
782 * Copy the parameters to a local buffer because lowmem will go away
784 memcpy(&KeLoaderBlock
, _LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
785 memcpy(&KeLoaderModules
[1], (PVOID
)KeLoaderBlock
.ModsAddr
,
786 sizeof(LOADER_MODULE
) * KeLoaderBlock
.ModsCount
);
787 KeLoaderBlock
.ModsCount
++;
788 KeLoaderBlock
.ModsAddr
= (ULONG
)&KeLoaderModules
;
791 * Convert a path specification in the grub format to one understood by the
792 * rest of the kernel.
794 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[0] == '(')
796 ULONG DiskNumber
= 0, PartNumber
= 0;
802 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[1] == 'h' &&
803 ((PUCHAR
)_LoaderBlock
->CommandLine
)[2] == 'd')
805 DiskNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[3] - '0';
806 PartNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[5] - '0';
808 strcpy(Temp
, &((PUCHAR
)_LoaderBlock
->CommandLine
)[7]);
809 if ((options
= strchr(Temp
, ' ')) != NULL
)
818 if ((s1
= strrchr(Temp
, '/')) != NULL
)
821 if ((s1
= strrchr(Temp
, '/')) != NULL
)
826 sprintf(KeLoaderCommandLine
,
827 "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s",
828 DiskNumber
, PartNumber
+ 1, Temp
, options
);
830 p
= KeLoaderCommandLine
;
831 while (*p
!= 0 && *p
!= ' ')
839 DPRINT1("Command Line: %s\n", KeLoaderCommandLine
);
843 strcpy(KeLoaderCommandLine
, (PUCHAR
)_LoaderBlock
->CommandLine
);
845 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
847 strcpy(KeLoaderModuleStrings
[0], "ntoskrnl.exe");
848 KeLoaderModules
[0].String
= (ULONG
)KeLoaderModuleStrings
[0];
849 KeLoaderModules
[0].ModStart
= 0xC0000000;
850 KeLoaderModules
[0].ModEnd
= PAGE_ROUND_UP((ULONG
)&_bss_end__
);
851 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
854 if ((s
= strrchr((PUCHAR
)KeLoaderModules
[i
].String
, '/')) != 0)
856 strcpy(KeLoaderModuleStrings
[i
], s
+ 1);
860 strcpy(KeLoaderModuleStrings
[i
], (PUCHAR
)KeLoaderModules
[i
].String
);
862 KeLoaderModules
[i
].ModStart
-= 0x200000;
863 KeLoaderModules
[i
].ModStart
+= 0xc0000000;
864 KeLoaderModules
[i
].ModEnd
-= 0x200000;
865 KeLoaderModules
[i
].ModEnd
+= 0xc0000000;
866 KeLoaderModules
[i
].String
= (ULONG
)KeLoaderModuleStrings
[i
];
870 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
873 HalBase
= KeLoaderModules
[1].ModStart
;
875 PAGE_ROUND_UP(KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
);
880 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)0xC0000000, &DriverSize
);
882 LdrHalBase
= (ULONG_PTR
)DriverBase
;
883 last_kernel_address
= DriverBase
+ DriverSize
;
886 * Process ntoskrnl.exe
888 LdrSafePEProcessModule((PVOID
)0xC0000000, (PVOID
)0xC0000000, (PVOID
)DriverBase
, &DriverSize
);
890 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- 0xc0000000 + 0x200000;
891 LastKrnlPhysAddr
= last_kernel_address
- 0xc0000000 + 0x200000;
892 LastKernelAddress
= last_kernel_address
;
895 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
896 KeLoaderBlock
.Flags
&= ~MB_FLAGS_MMAP_INFO
;
899 KeMemoryMapRangeCount
= 0;
900 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
902 /* We have a memory map from the nice BIOS */
903 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
905 while (i
< KeLoaderBlock
.MmapLength
)
907 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
908 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
909 sizeof(ADDRESS_RANGE
));
910 KeMemoryMapRangeCount
++;