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.129 2002/07/17 21:04:55 dwelch 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 #include <ddk/ntddk.h>
32 #include <internal/ntoskrnl.h>
33 #include <reactos/resource.h>
34 #include <internal/mm.h>
35 #include <internal/module.h>
36 #include <internal/ldr.h>
37 #include <internal/ex.h>
38 #include <internal/ps.h>
39 #include <internal/ke.h>
40 #include <internal/io.h>
41 #include <internal/po.h>
42 #include <internal/cc.h>
43 #include <internal/se.h>
44 #include <internal/v86m.h>
45 #include <internal/kd.h>
46 #include <internal/trap.h>
47 #include "../dbg/kdb.h"
48 #include <internal/registry.h>
49 #include <reactos/bugcodes.h>
52 #include <internal/ntosdbg.h>
58 #include <internal/debug.h>
60 /* GLOBALS *******************************************************************/
62 ULONG EXPORTED NtBuildNumber
= KERNEL_VERSION_BUILD
;
63 ULONG EXPORTED NtGlobalFlag
= 0;
64 CHAR EXPORTED KeNumberProcessors
;
65 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock
;
66 static LOADER_MODULE KeLoaderModules
[64];
67 static UCHAR KeLoaderModuleStrings
[64][256];
68 static UCHAR KeLoaderCommandLine
[256];
69 static ADDRESS_RANGE KeMemoryMap
[64];
70 static ULONG KeMemoryMapRangeCount
;
71 static ULONG FirstKrnlPhysAddr
;
72 static ULONG LastKrnlPhysAddr
;
73 static ULONG LastKernelAddress
;
74 volatile BOOLEAN Initialized
= FALSE
;
76 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
79 /* FUNCTIONS ****************************************************************/
82 RtlpCheckFileNameExtension(PCHAR FileName
,
87 Ext
= strrchr(FileName
, '.');
88 if ((Extension
== NULL
) || (*Extension
== 0))
95 if (*Extension
!= '.')
98 if (_stricmp(Ext
, Extension
) == 0)
106 InitSystemSharedUserPage (PCSZ ParameterLine
)
108 UNICODE_STRING ArcDeviceName
;
109 UNICODE_STRING ArcName
;
110 UNICODE_STRING BootPath
;
111 UNICODE_STRING DriveDeviceName
;
112 UNICODE_STRING DriveName
;
113 WCHAR DriveNameBuffer
[20];
115 PWCHAR ArcNameBuffer
;
119 OBJECT_ATTRIBUTES ObjectAttributes
;
122 BOOLEAN BootDriveFound
;
126 * The shared user page has been zeroed-out right after creation.
127 * There is NO need to do this again.
130 SharedUserData
->NtProductType
= NtProductWinNt
;
132 BootDriveFound
= FALSE
;
135 * Retrieve the current dos system path
136 * (e.g.: C:\reactos) from the given arc path
137 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
138 * Format: "<arc_name>\<path> [options...]"
141 /* create local parameter line copy */
142 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
143 strcpy (ParamBuffer
, (char *)ParameterLine
);
144 DPRINT("%s\n", ParamBuffer
);
146 /* cut options off */
147 p
= strchr (ParamBuffer
, ' ');
152 DPRINT("%s\n", ParamBuffer
);
155 p
= strchr (ParamBuffer
, '\\');
158 DPRINT("Boot path: %s\n", p
);
159 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
164 DPRINT("Boot path: %s\n", "\\");
165 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
167 DPRINT("Arc name: %s\n", ParamBuffer
);
169 /* Only arc name left - build full arc name */
170 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
171 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", ParamBuffer
);
172 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
173 DPRINT("Arc name: %wZ\n", &ArcName
);
175 /* free ParamBuffer */
176 ExFreePool (ParamBuffer
);
178 /* allocate arc device name string */
179 ArcDeviceName
.Length
= 0;
180 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
181 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
183 InitializeObjectAttributes (&ObjectAttributes
,
189 Status
= NtOpenSymbolicLinkObject (&Handle
,
190 SYMBOLIC_LINK_ALL_ACCESS
,
192 RtlFreeUnicodeString (&ArcName
);
193 if (!NT_SUCCESS(Status
))
195 RtlFreeUnicodeString (&BootPath
);
196 RtlFreeUnicodeString (&ArcDeviceName
);
197 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
203 Status
= NtQuerySymbolicLinkObject (Handle
,
207 if (!NT_SUCCESS(Status
))
209 RtlFreeUnicodeString (&BootPath
);
210 RtlFreeUnicodeString (&ArcDeviceName
);
211 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
216 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
219 /* allocate device name string */
220 DriveDeviceName
.Length
= 0;
221 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
222 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
224 for (i
= 0; i
< 26; i
++)
226 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
227 RtlInitUnicodeString (&DriveName
,
230 InitializeObjectAttributes (&ObjectAttributes
,
236 Status
= NtOpenSymbolicLinkObject (&Handle
,
237 SYMBOLIC_LINK_ALL_ACCESS
,
239 if (!NT_SUCCESS(Status
))
241 DPRINT("Failed to open link %wZ\n",
246 Status
= NtQuerySymbolicLinkObject (Handle
,
249 if (!NT_SUCCESS(Status
))
251 DPRINT("Failed query open link %wZ\n",
255 DPRINT("Opened link: %wZ ==> %wZ\n",
256 &DriveName
, &DriveDeviceName
);
258 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
))
260 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
261 swprintf(SharedUserData
->NtSystemRoot
,
262 L
"%C:%wZ", 'A' + i
, &BootPath
);
264 BootDriveFound
= TRUE
;
270 RtlFreeUnicodeString (&BootPath
);
271 RtlFreeUnicodeString (&DriveDeviceName
);
272 RtlFreeUnicodeString (&ArcDeviceName
);
274 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData
->DosDeviceMap
);
276 if (BootDriveFound
== FALSE
)
278 DbgPrint("No system drive found!\n");
285 VOID
DumpBIOSMemoryMap(VOID
)
289 DbgPrint("Dumping BIOS memory map:\n");
290 DbgPrint("Memory map base: %d\n", KeLoaderBlock
.MmapAddr
);
291 DbgPrint("Memory map size: %d\n", KeLoaderBlock
.MmapLength
);
292 DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount
);
293 for (i
= 0; i
< KeMemoryMapRangeCount
; i
++)
295 DbgPrint("Range: Base (%08X) Length (%08X) Type (%02X)\n",
296 KeMemoryMap
[i
].BaseAddrLow
,
297 KeMemoryMap
[i
].LengthLow
,
298 KeMemoryMap
[i
].Type
);
308 static ULONG Scratch
;
310 EXCEPTION_DISPOSITION
311 ExpUnhandledException1(
312 PEXCEPTION_RECORD ExceptionRecord
,
313 PEXCEPTION_REGISTRATION ExceptionRegistration
,
315 PVOID DispatcherContext
)
317 DbgPrint("ExpUnhandledException1() called\n");
318 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord
);
319 DbgPrint(" Flags 0x%X\n", ExceptionRecord
->ExceptionFlags
);
320 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration
);
321 DbgPrint("Context 0x%X\n", Context
);
322 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext
);
324 Context
->Eax
= (ULONG
)&Scratch
;
326 return ExceptionContinueExecution
;
330 EXCEPTION_DISPOSITION
331 ExpUnhandledException2(
332 PEXCEPTION_RECORD ExceptionRecord
,
333 PEXCEPTION_REGISTRATION ExceptionRegistration
,
335 PVOID DispatcherContext
)
337 DbgPrint("ExpUnhandledException2() called\n");
338 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord
);
339 DbgPrint(" Flags 0x%X\n", ExceptionRecord
->ExceptionFlags
);
340 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration
);
341 DbgPrint("Context 0x%X\n", Context
);
342 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext
);
345 Context
->Eax
= (ULONG
)&Scratch
;
347 return ExceptionContinueExecution
;
351 return ExceptionContinueSearch
;
358 // Put in mingw headers
362 PEXCEPTION_REGISTRATION RegistrationFrame
,
368 PVOID RegistrationFrame
);
370 extern EXCEPTION_DISPOSITION
373 PEXCEPTION_RECORD ExceptionRecord
,
374 PEXCEPTION_REGISTRATION RegistrationFrame
,
376 PVOID DispatcherContext
);
378 extern EXCEPTION_DISPOSITION
381 PEXCEPTION_RECORD ExceptionRecord
,
382 PEXCEPTION_REGISTRATION RegistrationFrame
,
384 PVOID DispatcherContext
);
388 PRTL_EXCEPTION_REGISTRATION
393 __asm__("movl %%ebp, %0\n\t" : "=a" (Value
));
395 return((PRTL_EXCEPTION_REGISTRATION
)Value
) - 1;
399 PRTL_EXCEPTION_REGISTRATION TestER
;
400 SCOPETABLE_ENTRY ScopeTable
;
401 PEXCEPTION_REGISTRATION OSPtr
;
404 DWORD CDECL
SEHFilterRoutine(VOID
)
406 DbgPrint("Within filter routine.\n");
407 return EXCEPTION_EXECUTE_HANDLER
;
408 //return EXCEPTION_CONTINUE_EXECUTION;
411 VOID CDECL
SEHHandlerRoutine(VOID
)
413 DbgPrint("Within exception handler.\n");
414 DbgPrint("System halted.\n");
421 RTL_EXCEPTION_REGISTRATION ER
;
422 LPEXCEPTION_POINTERS ExceptionPointers
;
423 PVOID StandardESPInFrame
;
425 __asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame
));
426 DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame
);
428 ExceptionPointers
= NULL
;
430 ER
.OS
.handler
= _except_handler3
;
431 __asm__ ("movl %%fs:0,%%eax;" : "=a" (ER
.OS
.prev
));
432 DbgPrint("ER.OS.prev: 0x%X\n", ER
.OS
.prev
);
434 ER
.ScopeTable
= &ScopeTable
;
435 DbgPrint("ER.ScopeTable: 0x%X\n", ER
.ScopeTable
);
437 __asm__ ("movl %%ebp,%%eax;" : "=a" (ER
.Ebp
));
438 DbgPrint("ER.Ebp: 0x%X\n", ER
.Ebp
);
440 ScopeTable
.PreviousTryLevel
= -1;
441 ScopeTable
.FilterRoutine
= SEHFilterRoutine
;
442 DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable
.FilterRoutine
);
443 ScopeTable
.HandlerRoutine
= SEHHandlerRoutine
;
444 DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable
.HandlerRoutine
);
448 DbgPrint("OSPtr: 0x%X\n", OSPtr
);
450 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr
));
452 /*__try1(__except_handler3)*/ if(1) {
453 ER
.TryLevel
= 0; // Entered first try... block
455 DbgPrint("Within guarded section.\n");
456 x
= (PULONG
)0xf2000000; *x
= 0;
457 DbgPrint("After exception.\n");
458 } /* __except1 */ if(0) {
461 DbgPrint("After exception2.\n");
463 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER
.OS
.prev
));
464 //KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
466 DbgPrint("Exiting.\n");
472 ExpInitializeExecutive(VOID
)
474 ULONG BootDriverCount
;
483 * Fail at runtime if someone has changed various structures without
484 * updating the offsets used for the assembler code.
486 assert(FIELD_OFFSET(KTHREAD
, InitialStack
) == KTHREAD_INITIAL_STACK
);
487 assert(FIELD_OFFSET(KTHREAD
, Teb
) == KTHREAD_TEB
);
488 assert(FIELD_OFFSET(KTHREAD
, KernelStack
) == KTHREAD_KERNEL_STACK
);
489 assert(FIELD_OFFSET(KTHREAD
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
490 assert(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
491 assert(FIELD_OFFSET(KTHREAD
, CallbackStack
) == KTHREAD_CALLBACK_STACK
);
492 assert(FIELD_OFFSET(ETHREAD
, ThreadsProcess
) == ETHREAD_THREADS_PROCESS
);
493 assert(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) ==
494 KPROCESS_DIRECTORY_TABLE_BASE
);
495 assert(FIELD_OFFSET(KTRAP_FRAME
, Reserved9
) == KTRAP_FRAME_RESERVED9
);
496 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
497 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
499 assert(FIELD_OFFSET(KPCR
, ExceptionList
) == KPCR_EXCEPTION_LIST
);
500 assert(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
501 assert(FIELD_OFFSET(KPCR
, CurrentThread
) == KPCR_CURRENT_THREAD
);
505 KeLowerIrql(DISPATCH_LEVEL
);
509 MmInit1(FirstKrnlPhysAddr
,
512 (PADDRESS_RANGE
)&KeMemoryMap
,
513 KeMemoryMapRangeCount
);
515 /* create default nls tables */
519 * Initialize the kernel debugger
521 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
526 KeLowerIrql(PASSIVE_LEVEL
);
529 KeBugCheck(SECURITY_INITIALIZATION_FAILED
);
534 KeBugCheck(SECURITY1_INITIALIZATION_FAILED
);
536 PiInitProcessManager();
540 if (KdPollBreakIn ())
542 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
546 * Display version number and copyright/warranty message
548 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
549 KERNEL_VERSION_BUILD_STR
")\n");
550 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
551 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
552 "Public License, and you\n");
553 HalDisplayString("are welcome to change it and/or distribute copies of it "
555 HalDisplayString("conditions. There is absolutely no warranty for "
558 /* Initialize all processors */
559 KeNumberProcessors
= 0;
561 while (!HalAllProcessorsStarted())
563 PVOID ProcessorStack
;
565 if (KeNumberProcessors
!= 0)
567 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
568 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
570 /* Allocate a stack for use when booting the processor */
571 /* FIXME: The nonpaged memory for the stack is not released after use */
573 ExAllocatePool(NonPagedPool
, MM_STACK_SIZE
) + MM_STACK_SIZE
;
574 Ki386InitialStackArray
[((int)KeNumberProcessors
)] =
575 (PVOID
)(ProcessorStack
- MM_STACK_SIZE
);
576 HalInitializeProcessor(KeNumberProcessors
, ProcessorStack
);
577 KeNumberProcessors
++;
580 if (KeNumberProcessors
> 1)
583 "Found %d system processors. [%lu MB Memory]\n",
585 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
590 "Found 1 system processor. [%lu MB Memory]\n",
591 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
593 HalDisplayString(str
);
596 * Initialize various critical subsystems
598 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
603 LdrInitModuleManagement();
604 CmInitializeRegistry();
610 /* Report all resources used by hal */
611 HalReportResourceUsage();
614 * Initalize services loaded at boot time
617 DPRINT("%d files loaded\n",KeLoaderBlock
.ModsCount
);
618 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
620 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
621 KeLoaderModules
[i
].String
,
622 KeLoaderModules
[i
].ModStart
,
623 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
626 /* Pass 1: load nls files */
627 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
629 name
= (PCHAR
)KeLoaderModules
[i
].String
;
630 if (RtlpCheckFileNameExtension(name
, ".nls"))
637 name
= (PCHAR
)KeLoaderModules
[i
+1].String
;
638 if (RtlpCheckFileNameExtension(name
, ".nls"))
640 Mod2Start
= (ULONG
)KeLoaderModules
[i
+1].ModStart
;
641 Mod2End
= (ULONG
)KeLoaderModules
[i
+1].ModEnd
;
643 name
= (PCHAR
)KeLoaderModules
[i
+2].String
;
644 if (RtlpCheckFileNameExtension(name
, ".nls"))
646 Mod3Start
= (ULONG
)KeLoaderModules
[i
+2].ModStart
;
647 Mod3End
= (ULONG
)KeLoaderModules
[i
+2].ModEnd
;
651 /* Initialize nls sections */
652 RtlpInitNlsSections((ULONG
)KeLoaderModules
[i
].ModStart
,
653 (ULONG
)KeLoaderModules
[i
].ModEnd
,
662 /* Pass 2: load registry chunks passed in */
663 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
665 start
= KeLoaderModules
[i
].ModStart
;
666 length
= KeLoaderModules
[i
].ModEnd
- start
;
667 name
= (PCHAR
)KeLoaderModules
[i
].String
;
668 if (RtlpCheckFileNameExtension(name
, "") ||
669 RtlpCheckFileNameExtension(name
, ".hiv"))
671 CPRINT("Process registry chunk at %08lx\n", start
);
672 CmImportHive((PCHAR
)start
, length
);
676 /* Initialize volatile registry settings */
677 CmInit2((PCHAR
)KeLoaderBlock
.CommandLine
);
680 * Enter the kernel debugger before starting up the boot drivers
686 IoCreateDriverList();
688 /* Pass 3: process boot loaded drivers */
690 for (i
=1; i
< KeLoaderBlock
.ModsCount
; i
++)
692 start
= KeLoaderModules
[i
].ModStart
;
693 length
= KeLoaderModules
[i
].ModEnd
- start
;
694 name
= (PCHAR
)KeLoaderModules
[i
].String
;
695 if (RtlpCheckFileNameExtension(name
, ".sys") ||
696 RtlpCheckFileNameExtension(name
, ".sym"))
698 CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n",
699 name
, start
, length
);
700 LdrInitializeBootStartDriver((PVOID
)start
, name
, length
);
702 if (RtlpCheckFileNameExtension(name
, ".sys"))
706 if (BootDriverCount
== 0)
708 DbgPrint("No boot drivers available.\n");
712 /* Create ARC names for boot devices */
715 /* Create the SystemRoot symbolic link */
716 CPRINT("CommandLine: %s\n", (PUCHAR
)KeLoaderBlock
.CommandLine
);
717 Status
= IoCreateSystemRootLink((PUCHAR
)KeLoaderBlock
.CommandLine
);
718 if (!NT_SUCCESS(Status
))
719 KeBugCheck(INACCESSIBLE_BOOT_DEVICE
);
721 #ifdef DBGPRINT_FILE_LOG
722 /* On the assumption that we can now access disks start up the debug
725 #endif /* DBGPRINT_FILE_LOG */
728 PiInitDefaultLocale();
731 * Start the motherboard enumerator (the HAL)
733 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
736 * Load boot start drivers
738 IopLoadBootStartDrivers();
741 * Load Auto configured drivers
743 LdrLoadAutoConfigDrivers();
746 IoDestroyDriverList();
749 * Assign drive letters
751 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
757 * Initialize shared user page:
758 * - set dos system path, dos device map, etc.
760 InitSystemSharedUserPage ((PUCHAR
)KeLoaderBlock
.CommandLine
);
763 * Launch initial process
765 LdrLoadInitialProcess();
767 PsTerminateSystemThread(STATUS_SUCCESS
);
772 KiSystemStartup(BOOLEAN BootProcessor
)
774 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
779 ExpInitializeExecutive();
782 /* Do application processor initialization */
783 KeApplicationProcessorInit();
784 PsApplicationProcessorInit();
785 KeLowerIrql(PASSIVE_LEVEL
);
786 PsIdleThreadMain(NULL
);
792 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
794 * FUNCTION: Called by the boot loader to start the kernel
796 * LoaderBlock = Pointer to boot parameters initialized by the boot
798 * NOTE: The boot parameters are stored in low memory which will become
799 * invalid after the memory managment is initialized so we make a local copy.
804 ULONG last_kernel_address
;
805 extern ULONG _bss_end__
;
810 /* Low level architecture specific initialization */
814 * Copy the parameters to a local buffer because lowmem will go away
816 memcpy(&KeLoaderBlock
, _LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
817 memcpy(&KeLoaderModules
[1], (PVOID
)KeLoaderBlock
.ModsAddr
,
818 sizeof(LOADER_MODULE
) * KeLoaderBlock
.ModsCount
);
819 KeLoaderBlock
.ModsCount
++;
820 KeLoaderBlock
.ModsAddr
= (ULONG
)&KeLoaderModules
;
822 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[0] == '(')
824 ULONG DiskNumber
, PartNumber
;
830 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[1] == 'h' &&
831 ((PUCHAR
)_LoaderBlock
->CommandLine
)[2] == 'd')
833 DiskNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[3] - '0';
834 PartNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[5] - '0';
836 strcpy(Temp
, &((PUCHAR
)_LoaderBlock
->CommandLine
)[7]);
837 if ((options
= strchr(Temp
, ' ')) != NULL
)
846 if ((s1
= strrchr(Temp
, '/')) != NULL
)
849 if ((s1
= strrchr(Temp
, '/')) != NULL
)
854 sprintf(KeLoaderCommandLine
,
855 "multi(0)disk(0)rdisk(%ld)partition(%ld)%s %s",
856 DiskNumber
, PartNumber
+ 1, Temp
, options
);
858 p
= KeLoaderCommandLine
;
859 while (*p
!= 0 && *p
!= ' ')
867 DPRINT1("Command Line: %s\n", KeLoaderCommandLine
);
871 strcpy(KeLoaderCommandLine
, (PUCHAR
)_LoaderBlock
->CommandLine
);
873 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
875 strcpy(KeLoaderModuleStrings
[0], "ntoskrnl.exe");
876 KeLoaderModules
[0].String
= (ULONG
)KeLoaderModuleStrings
[0];
877 KeLoaderModules
[0].ModStart
= 0xC0000000;
878 KeLoaderModules
[0].ModEnd
= PAGE_ROUND_UP((ULONG
)&_bss_end__
);
879 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
881 strcpy(KeLoaderModuleStrings
[i
], (PUCHAR
)KeLoaderModules
[i
].String
);
882 KeLoaderModules
[i
].ModStart
-= 0x200000;
883 KeLoaderModules
[i
].ModStart
+= 0xc0000000;
884 KeLoaderModules
[i
].ModEnd
-= 0x200000;
885 KeLoaderModules
[i
].ModEnd
+= 0xc0000000;
886 KeLoaderModules
[i
].String
= (ULONG
)KeLoaderModuleStrings
[i
];
890 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
893 HalBase
= KeLoaderModules
[1].ModStart
;
895 PAGE_ROUND_UP(KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
);
900 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)0xC0000000, &DriverSize
);
902 LdrHalBase
= (ULONG_PTR
)DriverBase
;
903 last_kernel_address
= DriverBase
+ DriverSize
;
906 * Process ntoskrnl.exe
908 LdrSafePEProcessModule((PVOID
)0xC0000000, (PVOID
)0xC0000000, (PVOID
)DriverBase
, &DriverSize
);
910 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- 0xc0000000 + 0x200000;
911 LastKrnlPhysAddr
= last_kernel_address
- 0xc0000000 + 0x200000;
912 LastKernelAddress
= last_kernel_address
;
915 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
916 KeLoaderBlock
.Flags
&= ~MB_FLAGS_MMAP_INFO
;
919 KeMemoryMapRangeCount
= 0;
920 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
922 /* We have a memory map from the nice BIOS */
923 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
925 while (i
< KeLoaderBlock
.MmapLength
)
927 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
928 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
929 sizeof(ADDRESS_RANGE
));
930 KeMemoryMapRangeCount
++;