Updated NLS function signature.
[reactos.git] / reactos / ntoskrnl / ke / main.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /* $Id: main.c,v 1.155 2003/05/16 17:35:12 ekohl Exp $
20 *
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/main.c
23 * PURPOSE: Initalizes the kernel
24 * PROGRAMMER: David Welch (welch@cwcom.net)
25 * UPDATE HISTORY:
26 * 28/05/98: Created
27 */
28
29 /* INCLUDES *****************************************************************/
30
31 #include <ddk/ntddk.h>
32 #include <internal/ntoskrnl.h>
33 #include <reactos/resource.h>
34 #include <internal/mm.h>
35 #include <internal/ifs.h>
36 #include <internal/module.h>
37 #include <internal/ldr.h>
38 #include <internal/ex.h>
39 #include <internal/ps.h>
40 #include <internal/ke.h>
41 #include <internal/io.h>
42 #include <internal/po.h>
43 #include <internal/cc.h>
44 #include <internal/se.h>
45 #include <internal/v86m.h>
46 #include <internal/kd.h>
47 #include <internal/trap.h>
48 #include "../dbg/kdb.h"
49 #include <internal/registry.h>
50 #include <internal/nls.h>
51 #include <reactos/bugcodes.h>
52
53 #ifdef HALDBG
54 #include <internal/ntosdbg.h>
55 #else
56 #define ps(args...)
57 #endif
58
59 #define NDEBUG
60 #include <internal/debug.h>
61
62 /* GLOBALS *******************************************************************/
63
64 ULONG EXPORTED NtBuildNumber = KERNEL_VERSION_BUILD;
65 ULONG EXPORTED NtGlobalFlag = 0;
66 CHAR EXPORTED KeNumberProcessors;
67 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock;
68 ULONG EXPORTED KeDcacheFlushCount = 0;
69 ULONG EXPORTED KeIcacheFlushCount = 0;
70 static LOADER_MODULE KeLoaderModules[64];
71 static UCHAR KeLoaderModuleStrings[64][256];
72 static UCHAR KeLoaderCommandLine[256];
73 static ADDRESS_RANGE KeMemoryMap[64];
74 static ULONG KeMemoryMapRangeCount;
75 static ULONG FirstKrnlPhysAddr;
76 static ULONG LastKrnlPhysAddr;
77 static ULONG LastKernelAddress;
78 volatile BOOLEAN Initialized = FALSE;
79
80 extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
81
82
83 /* FUNCTIONS ****************************************************************/
84
85 static BOOLEAN
86 RtlpCheckFileNameExtension(PCHAR FileName,
87 PCHAR Extension)
88 {
89 PCHAR Ext;
90
91 Ext = strrchr(FileName, '.');
92 if (Ext == NULL)
93 {
94 if ((Extension == NULL) || (*Extension == 0))
95 return TRUE;
96 else
97 return FALSE;
98 }
99
100 if (*Extension != '.')
101 Ext++;
102
103 if (_stricmp(Ext, Extension) == 0)
104 return TRUE;
105 else
106 return FALSE;
107 }
108
109
110 static VOID
111 InitSystemSharedUserPage (PCSZ ParameterLine)
112 {
113 UNICODE_STRING ArcDeviceName;
114 UNICODE_STRING ArcName;
115 UNICODE_STRING BootPath;
116 UNICODE_STRING DriveDeviceName;
117 UNICODE_STRING DriveName;
118 WCHAR DriveNameBuffer[20];
119 PCHAR ParamBuffer;
120 PWCHAR ArcNameBuffer;
121 PCHAR p;
122 NTSTATUS Status;
123 ULONG Length;
124 OBJECT_ATTRIBUTES ObjectAttributes;
125 HANDLE Handle;
126 ULONG i;
127 BOOLEAN BootDriveFound;
128
129 /*
130 * NOTE:
131 * The shared user page has been zeroed-out right after creation.
132 * There is NO need to do this again.
133 */
134
135 SharedUserData->NtProductType = NtProductWinNt;
136
137 BootDriveFound = FALSE;
138
139 /*
140 * Retrieve the current dos system path
141 * (e.g.: C:\reactos) from the given arc path
142 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
143 * Format: "<arc_name>\<path> [options...]"
144 */
145
146 /* create local parameter line copy */
147 ParamBuffer = ExAllocatePool (PagedPool, 256);
148 strcpy (ParamBuffer, (char *)ParameterLine);
149 DPRINT("%s\n", ParamBuffer);
150
151 /* cut options off */
152 p = strchr (ParamBuffer, ' ');
153 if (p)
154 {
155 *p = 0;
156 }
157 DPRINT("%s\n", ParamBuffer);
158
159 /* extract path */
160 p = strchr (ParamBuffer, '\\');
161 if (p)
162 {
163 DPRINT("Boot path: %s\n", p);
164 RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
165 *p = 0;
166 }
167 else
168 {
169 DPRINT("Boot path: %s\n", "\\");
170 RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
171 }
172 DPRINT("Arc name: %s\n", ParamBuffer);
173
174 /* Only arc name left - build full arc name */
175 ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
176 swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
177 RtlInitUnicodeString (&ArcName, ArcNameBuffer);
178 DPRINT("Arc name: %wZ\n", &ArcName);
179
180 /* free ParamBuffer */
181 ExFreePool (ParamBuffer);
182
183 /* allocate arc device name string */
184 ArcDeviceName.Length = 0;
185 ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
186 ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
187
188 InitializeObjectAttributes (&ObjectAttributes,
189 &ArcName,
190 OBJ_OPENLINK,
191 NULL,
192 NULL);
193
194 Status = NtOpenSymbolicLinkObject (&Handle,
195 SYMBOLIC_LINK_ALL_ACCESS,
196 &ObjectAttributes);
197 RtlFreeUnicodeString (&ArcName);
198 if (!NT_SUCCESS(Status))
199 {
200 RtlFreeUnicodeString (&BootPath);
201 RtlFreeUnicodeString (&ArcDeviceName);
202 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
203 Status);
204
205 KeBugCheck (0x0);
206 }
207
208 Status = NtQuerySymbolicLinkObject (Handle,
209 &ArcDeviceName,
210 &Length);
211 NtClose (Handle);
212 if (!NT_SUCCESS(Status))
213 {
214 RtlFreeUnicodeString (&BootPath);
215 RtlFreeUnicodeString (&ArcDeviceName);
216 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
217 Status);
218
219 KeBugCheck (0x0);
220 }
221 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
222
223
224 /* allocate device name string */
225 DriveDeviceName.Length = 0;
226 DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
227 DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
228
229 for (i = 0; i < 26; i++)
230 {
231 swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
232 RtlInitUnicodeString (&DriveName,
233 DriveNameBuffer);
234
235 InitializeObjectAttributes (&ObjectAttributes,
236 &DriveName,
237 OBJ_OPENLINK,
238 NULL,
239 NULL);
240
241 Status = NtOpenSymbolicLinkObject (&Handle,
242 SYMBOLIC_LINK_ALL_ACCESS,
243 &ObjectAttributes);
244 if (!NT_SUCCESS(Status))
245 {
246 DPRINT("Failed to open link %wZ\n",
247 &DriveName);
248 continue;
249 }
250
251 Status = NtQuerySymbolicLinkObject (Handle,
252 &DriveDeviceName,
253 &Length);
254 if (!NT_SUCCESS(Status))
255 {
256 DPRINT("Failed query open link %wZ\n",
257 &DriveName);
258 continue;
259 }
260 DPRINT("Opened link: %wZ ==> %wZ\n",
261 &DriveName, &DriveDeviceName);
262
263 if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
264 {
265 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
266 swprintf(SharedUserData->NtSystemRoot,
267 L"%C:%wZ", 'A' + i, &BootPath);
268
269 BootDriveFound = TRUE;
270 }
271
272 NtClose (Handle);
273 }
274
275 RtlFreeUnicodeString (&BootPath);
276 RtlFreeUnicodeString (&DriveDeviceName);
277 RtlFreeUnicodeString (&ArcDeviceName);
278
279 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData->DosDeviceMap);
280
281 if (BootDriveFound == FALSE)
282 {
283 DbgPrint("No system drive found!\n");
284 KeBugCheck (0x0);
285 }
286 }
287
288
289 VOID
290 ExpInitializeExecutive(VOID)
291 {
292 LARGE_INTEGER Timeout;
293 HANDLE ProcessHandle;
294 HANDLE ThreadHandle;
295 ULONG BootDriverCount;
296 ULONG i;
297 ULONG start;
298 ULONG length;
299 PCHAR name;
300 CHAR str[50];
301 NTSTATUS Status;
302 BOOLEAN SetupBoot;
303
304 /*
305 * Fail at runtime if someone has changed various structures without
306 * updating the offsets used for the assembler code.
307 */
308 assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
309 assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
310 assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
311 assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
312 assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
313 assert(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
314 assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
315 assert(FIELD_OFFSET(KPROCESS, DirectoryTableBase) ==
316 KPROCESS_DIRECTORY_TABLE_BASE);
317 assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
318 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
319 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
320
321 assert(FIELD_OFFSET(KPCR, ExceptionList) == KPCR_EXCEPTION_LIST);
322 assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
323 assert(FIELD_OFFSET(KPCR, CurrentThread) == KPCR_CURRENT_THREAD);
324
325 LdrInit1();
326
327 KeLowerIrql(DISPATCH_LEVEL);
328
329 NtEarlyInitVdm();
330
331 MmInit1(FirstKrnlPhysAddr,
332 LastKrnlPhysAddr,
333 LastKernelAddress,
334 (PADDRESS_RANGE)&KeMemoryMap,
335 KeMemoryMapRangeCount);
336
337 /* Create default nls tables */
338 RtlpCreateDefaultNlsTables();
339
340 /*
341 * Initialize the kernel debugger
342 */
343 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
344
345 MmInit2();
346 KeInit2();
347
348 KeLowerIrql(PASSIVE_LEVEL);
349
350 if (!SeInit1())
351 KeBugCheck(SECURITY_INITIALIZATION_FAILED);
352
353 ObInit();
354
355 if (!SeInit2())
356 KeBugCheck(SECURITY1_INITIALIZATION_FAILED);
357
358 PiInitProcessManager();
359
360 KdInit1();
361
362 if (KdPollBreakIn ())
363 {
364 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
365 }
366
367 /*
368 * Display version number and copyright/warranty message
369 */
370 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
371 KERNEL_VERSION_BUILD_STR")\n");
372 HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
373 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
374 "Public License, and you\n");
375 HalDisplayString("are welcome to change it and/or distribute copies of it "
376 "under certain\n");
377 HalDisplayString("conditions. There is absolutely no warranty for "
378 "ReactOS.\n\n");
379
380 /* Initialize all processors */
381 KeNumberProcessors = 0;
382
383 while (!HalAllProcessorsStarted())
384 {
385 PVOID ProcessorStack;
386
387 if (KeNumberProcessors != 0)
388 {
389 KePrepareForApplicationProcessorInit(KeNumberProcessors);
390 PsPrepareForApplicationProcessorInit(KeNumberProcessors);
391 }
392 /* Allocate a stack for use when booting the processor */
393 /* FIXME: The nonpaged memory for the stack is not released after use */
394 ProcessorStack =
395 ExAllocatePool(NonPagedPool, MM_STACK_SIZE) + MM_STACK_SIZE;
396 Ki386InitialStackArray[((int)KeNumberProcessors)] =
397 (PVOID)(ProcessorStack - MM_STACK_SIZE);
398 HalInitializeProcessor(KeNumberProcessors, ProcessorStack);
399 KeNumberProcessors++;
400 }
401
402 if (KeNumberProcessors > 1)
403 {
404 sprintf(str,
405 "Found %d system processors. [%lu MB Memory]\n",
406 KeNumberProcessors,
407 (KeLoaderBlock.MemHigher + 1088)/ 1024);
408 }
409 else
410 {
411 sprintf(str,
412 "Found 1 system processor. [%lu MB Memory]\n",
413 (KeLoaderBlock.MemHigher + 1088)/ 1024);
414 }
415 HalDisplayString(str);
416
417 /*
418 * Initialize various critical subsystems
419 */
420 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
421
422 ExInit();
423 IoInit();
424 PoInit();
425 LdrInitModuleManagement();
426 CmInitializeRegistry();
427 NtInit();
428 MmInit3();
429 CcInit();
430 KdInit2();
431 FsRtlpInitFileLockingImplementation();
432
433 /* Report all resources used by hal */
434 HalReportResourceUsage();
435
436 /*
437 * Initalize services loaded at boot time
438 */
439 DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
440 for (i=0; i < KeLoaderBlock.ModsCount; i++)
441 {
442 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
443 KeLoaderModules[i].String,
444 KeLoaderModules[i].ModStart,
445 KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
446 }
447
448
449 /* Pass 2: import system hive registry chunk */
450 SetupBoot = TRUE;
451 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
452 {
453 start = KeLoaderModules[i].ModStart;
454 length = KeLoaderModules[i].ModEnd - start;
455
456 DPRINT("Module: '%s'\n", (PCHAR)KeLoaderModules[i].String);
457 name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
458 if (name == NULL)
459 {
460 name = (PCHAR)KeLoaderModules[i].String;
461 }
462 else
463 {
464 name++;
465 }
466
467 if (!_stricmp (name, "system") ||
468 !_stricmp (name, "system.hiv"))
469 {
470 CPRINT("Process system hive registry chunk at %08lx\n", start);
471 SetupBoot = FALSE;
472 CmImportSystemHive((PCHAR)start, length);
473 }
474 }
475
476 /* Pass 3: import hardware hive registry chunk */
477 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
478 {
479 start = KeLoaderModules[i].ModStart;
480 length = KeLoaderModules[i].ModEnd - start;
481 name = (PCHAR)KeLoaderModules[i].String;
482 if (!_stricmp (name, "hardware") ||
483 !_stricmp (name, "hardware.hiv"))
484 {
485 CPRINT("Process hardware hive registry chunk at %08lx\n", start);
486 CmImportHardwareHive((PCHAR)start, length);
487 }
488 }
489
490 /* Create dummy keys if no hardware hive was found */
491 CmImportHardwareHive (NULL, 0);
492
493
494 /* Initialize volatile registry settings */
495 if (SetupBoot == FALSE)
496 {
497 CmInit2((PCHAR)KeLoaderBlock.CommandLine);
498 }
499
500 /*
501 * Enter the kernel debugger before starting up the boot drivers
502 */
503 #ifdef KDBG
504 KdbEnter();
505 #endif /* KDBG */
506
507 IoCreateDriverList();
508
509 IoInit2();
510
511 /* Pass 4: process boot loaded drivers */
512 BootDriverCount = 0;
513 for (i=1; i < KeLoaderBlock.ModsCount; i++)
514 {
515 start = KeLoaderModules[i].ModStart;
516 length = KeLoaderModules[i].ModEnd - start;
517 name = (PCHAR)KeLoaderModules[i].String;
518 if (RtlpCheckFileNameExtension(name, ".sys") ||
519 RtlpCheckFileNameExtension(name, ".sym"))
520 {
521 CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n",
522 name, start, length);
523 LdrInitializeBootStartDriver((PVOID)start, name, length);
524 }
525 if (RtlpCheckFileNameExtension(name, ".sys"))
526 BootDriverCount++;
527 }
528
529 if (BootDriverCount == 0)
530 {
531 DbgPrint("No boot drivers available.\n");
532 KeBugCheck(0);
533 }
534
535 /* Create ARC names for boot devices */
536 IoCreateArcNames();
537
538 /* Create the SystemRoot symbolic link */
539 CPRINT("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
540 Status = IoCreateSystemRootLink((PUCHAR)KeLoaderBlock.CommandLine);
541 if (!NT_SUCCESS(Status))
542 KeBugCheck(INACCESSIBLE_BOOT_DEVICE);
543
544 #ifdef DBGPRINT_FILE_LOG
545 /* On the assumption that we can now access disks start up the debug
546 logger thread */
547 DebugLogInit2();
548 #endif /* DBGPRINT_FILE_LOG */
549
550 #ifdef KDBG
551 KdbInitProfiling2();
552 #endif /* KDBG */
553
554
555 PiInitDefaultLocale();
556
557 /*
558 * Start the motherboard enumerator (the HAL)
559 */
560 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
561 #if 0
562 /*
563 * Load boot start drivers
564 */
565 IopLoadBootStartDrivers();
566 #else
567 /*
568 * Load Auto configured drivers
569 */
570 LdrLoadAutoConfigDrivers();
571 #endif
572
573 IoDestroyDriverList();
574
575 /*
576 * Assign drive letters
577 */
578 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
579 NULL,
580 NULL,
581 NULL);
582
583 /*
584 * Initialize shared user page:
585 * - set dos system path, dos device map, etc.
586 */
587 InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
588
589 /*
590 * Launch initial process
591 */
592 Status = LdrLoadInitialProcess(&ProcessHandle,
593 &ThreadHandle);
594 if (!NT_SUCCESS(Status))
595 {
596 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
597 }
598
599 /*
600 * Crash the system if the initial process terminates within 5 seconds.
601 */
602 Timeout.QuadPart = -50000000LL;
603 Status = NtWaitForSingleObject(ProcessHandle,
604 FALSE,
605 &Timeout);
606 if (Status != STATUS_TIMEOUT)
607 {
608 KeBugCheckEx(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
609 }
610
611 NtClose(ThreadHandle);
612 NtClose(ProcessHandle);
613
614 PsTerminateSystemThread(STATUS_SUCCESS);
615 }
616
617
618 VOID
619 KiSystemStartup(BOOLEAN BootProcessor)
620 {
621 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
622
623 if (BootProcessor)
624 {
625 /* Never returns */
626 ExpInitializeExecutive();
627 KeBugCheck(0);
628 }
629 /* Do application processor initialization */
630 KeApplicationProcessorInit();
631 PsApplicationProcessorInit();
632 KeLowerIrql(PASSIVE_LEVEL);
633 PsIdleThreadMain(NULL);
634 KeBugCheck(0);
635 for(;;);
636 }
637
638 VOID
639 _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
640 /*
641 * FUNCTION: Called by the boot loader to start the kernel
642 * ARGUMENTS:
643 * LoaderBlock = Pointer to boot parameters initialized by the boot
644 * loader
645 * NOTE: The boot parameters are stored in low memory which will become
646 * invalid after the memory managment is initialized so we make a local copy.
647 */
648 {
649 ULONG i;
650 ULONG size;
651 ULONG last_kernel_address;
652 extern ULONG _bss_end__;
653 ULONG HalBase;
654 ULONG DriverBase;
655 ULONG DriverSize;
656
657 /* Low level architecture specific initialization */
658 KeInit1();
659
660 /*
661 * Copy the parameters to a local buffer because lowmem will go away
662 */
663 memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
664 memcpy(&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
665 sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
666 KeLoaderBlock.ModsCount++;
667 KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
668
669 /*
670 * Convert a path specification in the grub format to one understood by the
671 * rest of the kernel.
672 */
673 if (((PUCHAR)_LoaderBlock->CommandLine)[0] == '(')
674 {
675 ULONG DiskNumber = 0, PartNumber = 0;
676 PCH p;
677 CHAR Temp[256];
678 PCH options;
679 PCH s1;
680
681 if (((PUCHAR)_LoaderBlock->CommandLine)[1] == 'h' &&
682 ((PUCHAR)_LoaderBlock->CommandLine)[2] == 'd')
683 {
684 DiskNumber = ((PUCHAR)_LoaderBlock->CommandLine)[3] - '0';
685 PartNumber = ((PUCHAR)_LoaderBlock->CommandLine)[5] - '0';
686 }
687 strcpy(Temp, &((PUCHAR)_LoaderBlock->CommandLine)[7]);
688 if ((options = strchr(Temp, ' ')) != NULL)
689 {
690 *options = 0;
691 options++;
692 }
693 else
694 {
695 options = "";
696 }
697 if ((s1 = strrchr(Temp, '/')) != NULL)
698 {
699 *s1 = 0;
700 if ((s1 = strrchr(Temp, '/')) != NULL)
701 {
702 *s1 = 0;
703 }
704 }
705 sprintf(KeLoaderCommandLine,
706 "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s",
707 DiskNumber, PartNumber + 1, Temp, options);
708
709 p = KeLoaderCommandLine;
710 while (*p != 0 && *p != ' ')
711 {
712 if ((*p) == '/')
713 {
714 (*p) = '\\';
715 }
716 p++;
717 }
718 DPRINT1("Command Line: %s\n", KeLoaderCommandLine);
719 }
720 else
721 {
722 strcpy(KeLoaderCommandLine, (PUCHAR)_LoaderBlock->CommandLine);
723 }
724 KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
725
726 strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
727 KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
728 KeLoaderModules[0].ModStart = 0xC0000000;
729 KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
730 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
731 {
732 CHAR* s;
733 if ((s = strrchr((PUCHAR)KeLoaderModules[i].String, '/')) != 0)
734 {
735 strcpy(KeLoaderModuleStrings[i], s + 1);
736 }
737 else
738 {
739 strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
740 }
741 KeLoaderModules[i].ModStart -= 0x200000;
742 KeLoaderModules[i].ModStart += 0xc0000000;
743 KeLoaderModules[i].ModEnd -= 0x200000;
744 KeLoaderModules[i].ModEnd += 0xc0000000;
745 KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
746 }
747
748 #ifdef HAL_DBG
749 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
750 #endif
751
752 HalBase = KeLoaderModules[1].ModStart;
753 DriverBase =
754 PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
755
756 /*
757 * Process hal.dll
758 */
759 LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)0xC0000000, &DriverSize);
760
761 LdrHalBase = (ULONG_PTR)DriverBase;
762 last_kernel_address = DriverBase + DriverSize;
763
764 /*
765 * Process ntoskrnl.exe
766 */
767 LdrSafePEProcessModule((PVOID)0xC0000000, (PVOID)0xC0000000, (PVOID)DriverBase, &DriverSize);
768
769 FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000;
770 LastKrnlPhysAddr = last_kernel_address - 0xc0000000 + 0x200000;
771 LastKernelAddress = last_kernel_address;
772
773 #ifndef ACPI
774 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
775 KeLoaderBlock.Flags &= ~MB_FLAGS_MMAP_INFO;
776 #endif
777
778 KeMemoryMapRangeCount = 0;
779 if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO)
780 {
781 /* We have a memory map from the nice BIOS */
782 size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
783 i = 0;
784 while (i < KeLoaderBlock.MmapLength)
785 {
786 memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
787 (PVOID)(KeLoaderBlock.MmapAddr + i),
788 sizeof(ADDRESS_RANGE));
789 KeMemoryMapRangeCount++;
790 i += size;
791 }
792 }
793
794 KiSystemStartup(1);
795 }
796
797 /* EOF */
798