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