Added PnP and Power stubs
[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.88 2001/04/16 00:48:04 chorns 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/config.h>
33 #include <internal/ntoskrnl.h>
34 #include <reactos/resource.h>
35 #include <internal/mm.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 <napi/shared_data.h>
43 #include <internal/v86m.h>
44 #include <internal/kd.h>
45 #include <internal/trap.h>
46 #include <internal/config.h>
47 #include "../dbg/kdb.h"
48
49 #define NDEBUG
50 #include <internal/debug.h>
51
52 /* GLOBALS *******************************************************************/
53
54 ULONG EXPORTED NtBuildNumber = KERNEL_VERSION_BUILD;
55 ULONG EXPORTED NtGlobalFlag = 0;
56 CHAR EXPORTED KeNumberProcessors;
57 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock;
58 static LOADER_MODULE KeLoaderModules[64];
59 static UCHAR KeLoaderModuleStrings[64][256];
60 static UCHAR KeLoaderCommandLine[256];
61 static ULONG FirstKrnlPhysAddr;
62 static ULONG LastKrnlPhysAddr;
63 static ULONG LastKernelAddress;
64 volatile BOOLEAN Initialized = FALSE;
65
66 /* FUNCTIONS ****************************************************************/
67
68 static VOID
69 CreateSystemRootLink (PCSZ ParameterLine)
70 {
71 UNICODE_STRING LinkName;
72 UNICODE_STRING DeviceName;
73 UNICODE_STRING ArcName;
74 UNICODE_STRING BootPath;
75 PCHAR ParamBuffer;
76 PWCHAR ArcNameBuffer;
77 PCHAR p;
78 NTSTATUS Status;
79 ULONG Length;
80 OBJECT_ATTRIBUTES ObjectAttributes;
81 HANDLE Handle;
82
83 /* create local parameter line copy */
84 ParamBuffer = ExAllocatePool (PagedPool, 256);
85 strcpy (ParamBuffer, (char *)ParameterLine);
86
87 DPRINT("%s\n", ParamBuffer);
88 /* Format: <arc_name>\<path> [options...] */
89
90 /* cut options off */
91 p = strchr (ParamBuffer, ' ');
92 if (p)
93 *p = 0;
94 DPRINT("%s\n", ParamBuffer);
95
96 /* extract path */
97 p = strchr (ParamBuffer, '\\');
98 if (p)
99 {
100 DPRINT("Boot path: %s\n", p);
101 RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
102 *p = 0;
103 }
104 else
105 {
106 DPRINT("Boot path: %s\n", "\\");
107 RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
108 }
109 DPRINT("Arc name: %s\n", ParamBuffer);
110
111 /* Only arc name left - build full arc name */
112 ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
113 swprintf (ArcNameBuffer,
114 L"\\ArcName\\%S", ParamBuffer);
115 RtlInitUnicodeString (&ArcName, ArcNameBuffer);
116 DPRINT1("Arc name: %wZ\n", &ArcName);
117
118 /* free ParamBuffer */
119 ExFreePool (ParamBuffer);
120
121 /* allocate device name string */
122 DeviceName.Length = 0;
123 DeviceName.MaximumLength = 256 * sizeof(WCHAR);
124 DeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
125
126 InitializeObjectAttributes (&ObjectAttributes,
127 &ArcName,
128 0,
129 NULL,
130 NULL);
131
132 Status = NtOpenSymbolicLinkObject (&Handle,
133 SYMBOLIC_LINK_ALL_ACCESS,
134 &ObjectAttributes);
135 if (!NT_SUCCESS(Status))
136 {
137 RtlFreeUnicodeString (&BootPath);
138 RtlFreeUnicodeString (&DeviceName);
139 DbgPrint("NtOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
140 &ArcName,
141 Status);
142 RtlFreeUnicodeString (&ArcName);
143
144 KeBugCheck (0x0);
145 }
146 RtlFreeUnicodeString (&ArcName);
147
148 Status = NtQuerySymbolicLinkObject (Handle,
149 &DeviceName,
150 &Length);
151 NtClose (Handle);
152 if (!NT_SUCCESS(Status))
153 {
154 RtlFreeUnicodeString (&BootPath);
155 RtlFreeUnicodeString (&DeviceName);
156 DbgPrint("NtQuerySymbolicObject() failed (Status %x)\n",
157 Status);
158
159 KeBugCheck (0x0);
160 }
161 DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName);
162
163 RtlAppendUnicodeStringToString (&DeviceName,
164 &BootPath);
165
166 RtlFreeUnicodeString (&BootPath);
167 DPRINT("DeviceName: %wZ\n", &DeviceName);
168
169 /* create the '\SystemRoot' link */
170 RtlInitUnicodeString (&LinkName,
171 L"\\SystemRoot");
172
173 Status = IoCreateSymbolicLink (&LinkName,
174 &DeviceName);
175 RtlFreeUnicodeString (&DeviceName);
176 if (!NT_SUCCESS(Status))
177 {
178 DbgPrint("IoCreateSymbolicLink() failed (Status %x)\n",
179 Status);
180
181 KeBugCheck (0x0);
182 }
183
184 /* Check if '\SystemRoot'(LinkName) can be opened, otherwise crash it! */
185 InitializeObjectAttributes (&ObjectAttributes,
186 &LinkName,
187 0,
188 NULL,
189 NULL);
190
191 Status = NtOpenSymbolicLinkObject (&Handle,
192 SYMBOLIC_LINK_ALL_ACCESS,
193 &ObjectAttributes);
194 if (!NT_SUCCESS(Status))
195 {
196 DbgPrint("NtOpenSymbolicLinkObject() failed to open '\\SystemRoot' (Status %x)\n",
197 Status);
198 KeBugCheck (0x0);
199 }
200 NtClose(Handle);
201 }
202
203
204 static VOID
205 InitSystemSharedUserPage (PCSZ ParameterLine)
206 {
207 PKUSER_SHARED_DATA SharedPage;
208
209 UNICODE_STRING ArcDeviceName;
210 UNICODE_STRING ArcName;
211 UNICODE_STRING BootPath;
212 UNICODE_STRING DriveDeviceName;
213 UNICODE_STRING DriveName;
214 WCHAR DriveNameBuffer[20];
215 PCHAR ParamBuffer;
216 PWCHAR ArcNameBuffer;
217 PCHAR p;
218 NTSTATUS Status;
219 ULONG Length;
220 OBJECT_ATTRIBUTES ObjectAttributes;
221 HANDLE Handle;
222 ULONG i;
223 BOOLEAN BootDriveFound;
224
225 SharedPage = (PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE;
226 SharedPage->DosDeviceMap = 0;
227 SharedPage->NtProductType = NtProductWinNt;
228 for (i = 0; i < 32; i++)
229 {
230 SharedPage->DosDeviceDriveType[i] = 0;
231 }
232
233 BootDriveFound = FALSE;
234
235 /*
236 * Retrieve the current dos system path
237 * (e.g.: C:\reactos) from the given arc path
238 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
239 * Format: "<arc_name>\<path> [options...]"
240 */
241
242 /* create local parameter line copy */
243 ParamBuffer = ExAllocatePool (PagedPool, 256);
244 strcpy (ParamBuffer, (char *)ParameterLine);
245 DPRINT("%s\n", ParamBuffer);
246
247 /* cut options off */
248 p = strchr (ParamBuffer, ' ');
249 if (p)
250 {
251 *p = 0;
252 }
253 DPRINT("%s\n", ParamBuffer);
254
255 /* extract path */
256 p = strchr (ParamBuffer, '\\');
257 if (p)
258 {
259 DPRINT("Boot path: %s\n", p);
260 RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
261 *p = 0;
262 }
263 else
264 {
265 DPRINT("Boot path: %s\n", "\\");
266 RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
267 }
268 DPRINT("Arc name: %s\n", ParamBuffer);
269
270 /* Only arc name left - build full arc name */
271 ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
272 swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
273 RtlInitUnicodeString (&ArcName, ArcNameBuffer);
274 DPRINT("Arc name: %wZ\n", &ArcName);
275
276 /* free ParamBuffer */
277 ExFreePool (ParamBuffer);
278
279 /* allocate arc device name string */
280 ArcDeviceName.Length = 0;
281 ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
282 ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
283
284 InitializeObjectAttributes (&ObjectAttributes,
285 &ArcName,
286 0,
287 NULL,
288 NULL);
289
290 Status = NtOpenSymbolicLinkObject (&Handle,
291 SYMBOLIC_LINK_ALL_ACCESS,
292 &ObjectAttributes);
293 RtlFreeUnicodeString (&ArcName);
294 if (!NT_SUCCESS(Status))
295 {
296 RtlFreeUnicodeString (&BootPath);
297 RtlFreeUnicodeString (&ArcDeviceName);
298 DbgPrint("NtOpenSymbolicLinkObject() failed (Status %x)\n",
299 Status);
300
301 KeBugCheck (0x0);
302 }
303
304 Status = NtQuerySymbolicLinkObject (Handle,
305 &ArcDeviceName,
306 &Length);
307 NtClose (Handle);
308 if (!NT_SUCCESS(Status))
309 {
310 RtlFreeUnicodeString (&BootPath);
311 RtlFreeUnicodeString (&ArcDeviceName);
312 DbgPrint("NtQuerySymbolicObject() failed (Status %x)\n",
313 Status);
314
315 KeBugCheck (0x0);
316 }
317 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
318
319
320 /* allocate device name string */
321 DriveDeviceName.Length = 0;
322 DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
323 DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
324
325 for (i = 0; i < 26; i++)
326 {
327 swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
328 RtlInitUnicodeString (&DriveName,
329 DriveNameBuffer);
330
331 InitializeObjectAttributes (&ObjectAttributes,
332 &DriveName,
333 0,
334 NULL,
335 NULL);
336
337 Status = NtOpenSymbolicLinkObject (&Handle,
338 SYMBOLIC_LINK_ALL_ACCESS,
339 &ObjectAttributes);
340 if (!NT_SUCCESS(Status))
341 {
342 DPRINT("Failed to open link %wZ\n",
343 &DriveName);
344 continue;
345 }
346
347 Status = NtQuerySymbolicLinkObject (Handle,
348 &DriveDeviceName,
349 &Length);
350 if (!NT_SUCCESS(Status))
351 {
352 DPRINT("Failed query open link %wZ\n",
353 &DriveName);
354 continue;
355 }
356 DPRINT("Opened link: %wZ ==> %wZ\n",
357 &DriveName, &DriveDeviceName);
358
359 if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
360 {
361 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
362 swprintf (SharedPage->NtSystemRoot,
363 L"%C:%wZ", 'A' + i, &BootPath);
364
365 BootDriveFound = TRUE;
366 }
367
368 NtClose (Handle);
369
370 /* set bit in dos drives bitmap (drive available) */
371 SharedPage->DosDeviceMap |= (1<<i);
372 }
373
374 RtlFreeUnicodeString (&BootPath);
375 RtlFreeUnicodeString (&DriveDeviceName);
376 RtlFreeUnicodeString (&ArcDeviceName);
377
378 DPRINT("DosDeviceMap: 0x%x\n", SharedPage->DosDeviceMap);
379
380 if (BootDriveFound == FALSE)
381 {
382 DbgPrint("No system drive found!\n");
383 KeBugCheck (0x0);
384 }
385 }
386 #if 0
387 VOID
388 TestV86Mode(VOID)
389 {
390 ULONG i;
391 extern UCHAR OrigIVT[1024];
392 KV86M_REGISTERS regs;
393 NTSTATUS Status;
394 struct vesa_info* vi;
395
396 for (i = 0; i < (640 / 4); i++)
397 {
398 MmCreateVirtualMapping(NULL,
399 (PVOID)(i * 4096),
400 PAGE_EXECUTE_READWRITE,
401 (ULONG)MmAllocPage(0));
402 }
403 for (; i < (1024 / 4); i++)
404 {
405 MmCreateVirtualMapping(NULL,
406 (PVOID)(i * 4096),
407 PAGE_EXECUTE_READ,
408 i * 4096);
409 }
410 vi = (struct vesa_info*)0x20000;
411 vi->Signature[0] = 'V';
412 vi->Signature[1] = 'B';
413 vi->Signature[2] = 'E';
414 vi->Signature[3] = '2';
415 memset(&regs, 0, sizeof(regs));
416 regs.Eax = 0x4F00;
417 regs.Es = 0x2000;
418 regs.Edi = 0x0;
419 memcpy((PVOID)0x0, OrigIVT, 1024);
420 Status = Ke386CallBios(0x10, &regs);
421 DbgPrint("Finished (Status %x, CS:EIP %x:%x)\n", Status, regs.Cs,
422 regs.Eip);
423 DbgPrint("Eax %x\n", regs.Eax);
424 DbgPrint("Signature %.4s\n", vi->Signature);
425 DbgPrint("TotalVideoMemory %dKB\n", vi->TotalVideoMemory * 64);
426 }
427 #endif
428
429 VOID
430 ExpInitializeExecutive(VOID)
431 {
432 /*
433 * Initialization phase 0
434 */
435 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
436
437 /* Execute executive initialization code on bootstrap processor only */
438 if (!Initialized)
439 {
440 Initialized = TRUE;
441 DPRINT("Phase 0 initialization started...\n");
442
443 /*
444 * Fail at runtime if someone has changed various structures without
445 * updating the offsets used for the assembler code.
446 */
447 assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
448 assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
449 assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
450 assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
451 assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
452 assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
453 assert(FIELD_OFFSET(KPROCESS, PageTableDirectory) ==
454 KPROCESS_PAGE_TABLE_DIRECTORY);
455 assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
456 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
457 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
458
459 assert(FIELD_OFFSET(KPCR, ExceptionList) == KPCR_EXCEPTION_LIST);
460 assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
461 assert(FIELD_OFFSET(KPCR, CurrentThread) == KPCR_CURRENT_THREAD);
462
463 LdrInit1();
464
465 KeLowerIrql(DISPATCH_LEVEL);
466
467 NtEarlyInitVdm();
468
469 MmInit1(FirstKrnlPhysAddr, LastKrnlPhysAddr, LastKernelAddress);
470
471 /*
472 * Initialize the kernel debugger
473 */
474 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
475 if (KdPollBreakIn ())
476 {
477 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
478 }
479
480 MmInit2();
481 KeInit2();
482
483 {
484 char tmpbuf[80];
485 sprintf(tmpbuf,"System with %d/%d MB memory\n",
486 (unsigned int)(KeLoaderBlock.MemLower)/1024,
487 (unsigned int)(KeLoaderBlock.MemHigher)/1024);
488 HalDisplayString(tmpbuf);
489 }
490
491 KeLowerIrql(PASSIVE_LEVEL);
492
493 ObInit();
494 PiInitProcessManager();
495
496 /*
497 * Allow interrupts
498 */
499 __asm__ ("sti\n\t");
500
501 #ifdef MP
502 //Phase1Initialization(NULL);
503 #endif
504 }
505 }
506
507 VOID
508 KiSystemStartup(VOID)
509 {
510 ExpInitializeExecutive();
511
512 for (;;)
513 {
514 NtYieldExecution();
515 }
516 }
517
518 /* Initialization phase 1 */
519 VOID Phase1Initialization(PVOID Context)
520 {
521 ULONG i;
522 ULONG start;
523 PCHAR name;
524 CHAR str[50];
525
526 DPRINT("Initialization phase 1 started...\n");
527
528 /*
529 * Display version number and copyright/warranty message
530 */
531 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
532 KERNEL_VERSION_BUILD_STR")\n");
533 HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
534 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
535 "Public License, and you\n");
536 HalDisplayString("are welcome to change it and/or distribute copies of it "
537 "under certain\n");
538 HalDisplayString("conditions. There is absolutely no warranty for ReactOS.\n");
539
540 /* Initialize all processors */
541 KeNumberProcessors = 0;
542
543 while (!HalAllProcessorsStarted())
544 {
545 HalInitializeProcessor(
546 KeNumberProcessors);
547 KeNumberProcessors++;
548 }
549
550 if (KeNumberProcessors > 1)
551 {
552 sprintf(str, "Found %d system processors.\n",
553 KeNumberProcessors);
554 }
555 else
556 {
557 strcpy(str, "Found 1 system processor.\n");
558 }
559 HalDisplayString(str);
560
561 #ifdef MP
562
563 DbgPrint("BSP halted\n");
564 for (;;);
565
566 #endif /* MP */
567
568 /*
569 * Initialize various critical subsystems
570 */
571 HalInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
572
573 ExInit();
574 IoInit();
575 LdrInitModuleManagement();
576 CmInitializeRegistry();
577 NtInit();
578 MmInit3();
579
580 /* Report all resources used by hal */
581 HalReportResourceUsage ();
582
583 /*
584 * Enter the kernel debugger before starting up the boot drivers
585 */
586 #ifdef KDBG
587 KdbEnter();
588 #endif /* KDBG */
589
590 /*
591 * Initalize services loaded at boot time
592 */
593 DPRINT1("%d files loaded\n",KeLoaderBlock.ModsCount);
594 for (i=0; i < KeLoaderBlock.ModsCount; i++)
595 {
596 DPRINT1("module: %s\n", KeLoaderModules[i].String);
597 }
598
599 /* Pass 1: load registry chunks passed in */
600 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
601 {
602 start = KeLoaderModules[i].ModStart;
603 if (strcmp ((PCHAR) start, "REGEDIT4") == 0)
604 {
605 DPRINT1("process registry chunk at %08lx\n", start);
606 CmImportHive((PCHAR) start);
607 }
608 }
609
610 /* Pass 2: process boot loaded drivers */
611 for (i=1; i < KeLoaderBlock.ModsCount; i++)
612 {
613 start = KeLoaderModules[i].ModStart;
614 name = (PCHAR)KeLoaderModules[i].String;
615 if (strcmp ((PCHAR) start, "REGEDIT4") != 0)
616 {
617 DPRINT1("process module '%s' at %08lx\n", name, start);
618 LdrProcessDriver((PVOID)start, name);
619 }
620 }
621
622 DPRINT("About to try MmAllocateContiguousAlignedMemory\n");
623 do
624 {
625 extern PVOID STDCALL
626 MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
627 IN PHYSICAL_ADDRESS HighestAcceptableAddress,
628 IN ULONG Alignment);
629 PVOID v;
630 PHYSICAL_ADDRESS p;
631 p.QuadPart = 16*1024*1024;
632 v = MmAllocateContiguousAlignedMemory(12*1024, p,
633 64*1024);
634 if (v != NULL)
635 {
636 DPRINT("Worked\n");
637 }
638 else
639 {
640 DPRINT("Failed\n");
641 }
642 }
643 while (0);
644
645 /* Create the SystemRoot symbolic link */
646 DbgPrint("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
647
648 CreateSystemRootLink ((PUCHAR)KeLoaderBlock.CommandLine);
649
650 #ifdef DBGPRINT_FILE_LOG
651 /* On the assumption that we can now access disks start up the debug
652 logger thread */
653 DebugLogInit2();
654 #endif /* DBGPRINT_FILE_LOG */
655
656
657 CmInitializeRegistry2();
658
659 /*
660 * Load Auto configured drivers
661 */
662 LdrLoadAutoConfigDrivers();
663
664 /*
665 * Assign drive letters
666 */
667 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
668 NULL,
669 NULL,
670 NULL);
671
672 /*
673 * Initialize shared user page:
674 * - set dos system path, dos device map, etc.
675 */
676 InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
677
678 /*
679 * Launch initial process
680 */
681 LdrLoadInitialProcess();
682
683 DbgPrint("Finished kernel initialization.\n");
684
685 /* FIXME: Call zero page thread function */
686 PsTerminateSystemThread(STATUS_SUCCESS);
687 }
688
689 VOID
690 _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
691 /*
692 * FUNCTION: Called by the boot loader to start the kernel
693 * ARGUMENTS:
694 * LoaderBlock = Pointer to boot parameters initialized by the boot
695 * loader
696 * NOTE: The boot parameters are stored in low memory which will become
697 * invalid after the memory managment is initialized so we make a local copy.
698 */
699 {
700 ULONG i;
701 ULONG last_kernel_address;
702 extern ULONG _bss_end__;
703
704 /*
705 * Copy the parameters to a local buffer because lowmem will go away
706 */
707 memcpy (&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
708 memcpy (&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
709 sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
710 KeLoaderBlock.ModsCount++;
711 KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
712
713 /*
714 * FIXME: Preliminary hack!!!! Add boot device to beginning of command line.
715 * This should be done by the boot loader.
716 */
717 strcpy (KeLoaderCommandLine,
718 "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN");
719 strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine);
720
721 KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
722 strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
723 KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
724 KeLoaderModules[0].ModStart = 0xC0000000;
725 KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
726 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
727 {
728 strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
729 KeLoaderModules[i].ModStart -= 0x200000;
730 KeLoaderModules[i].ModStart += 0xc0000000;
731 KeLoaderModules[i].ModEnd -= 0x200000;
732 KeLoaderModules[i].ModEnd += 0xc0000000;
733 KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
734 }
735
736 last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;
737
738 FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000;
739 LastKrnlPhysAddr = last_kernel_address - 0xc0000000 + 0x200000;
740 LastKernelAddress = last_kernel_address;
741
742 KeInit1();
743
744 #if 0
745 /*
746 * Allow interrupts
747 */
748 __asm__ ("sti\n\t");
749 #endif
750
751 KiSystemStartup();
752 }
753
754 /* EOF */
755