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.150 2003/04/01 16:35:22 ekohl 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/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>
53 #include <internal/ntosdbg.h>
59 #include <internal/debug.h>
61 /* GLOBALS *******************************************************************/
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
;
79 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
82 /* FUNCTIONS ****************************************************************/
85 RtlpCheckFileNameExtension(PCHAR FileName
,
90 Ext
= strrchr(FileName
, '.');
93 if ((Extension
== NULL
) || (*Extension
== 0))
99 if (*Extension
!= '.')
102 if (_stricmp(Ext
, Extension
) == 0)
110 InitSystemSharedUserPage (PCSZ ParameterLine
)
112 UNICODE_STRING ArcDeviceName
;
113 UNICODE_STRING ArcName
;
114 UNICODE_STRING BootPath
;
115 UNICODE_STRING DriveDeviceName
;
116 UNICODE_STRING DriveName
;
117 WCHAR DriveNameBuffer
[20];
119 PWCHAR ArcNameBuffer
;
123 OBJECT_ATTRIBUTES ObjectAttributes
;
126 BOOLEAN BootDriveFound
;
130 * The shared user page has been zeroed-out right after creation.
131 * There is NO need to do this again.
134 SharedUserData
->NtProductType
= NtProductWinNt
;
136 BootDriveFound
= FALSE
;
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...]"
145 /* create local parameter line copy */
146 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
147 strcpy (ParamBuffer
, (char *)ParameterLine
);
148 DPRINT("%s\n", ParamBuffer
);
150 /* cut options off */
151 p
= strchr (ParamBuffer
, ' ');
156 DPRINT("%s\n", ParamBuffer
);
159 p
= strchr (ParamBuffer
, '\\');
162 DPRINT("Boot path: %s\n", p
);
163 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
168 DPRINT("Boot path: %s\n", "\\");
169 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
171 DPRINT("Arc name: %s\n", ParamBuffer
);
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
);
179 /* free ParamBuffer */
180 ExFreePool (ParamBuffer
);
182 /* allocate arc device name string */
183 ArcDeviceName
.Length
= 0;
184 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
185 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
187 InitializeObjectAttributes (&ObjectAttributes
,
193 Status
= NtOpenSymbolicLinkObject (&Handle
,
194 SYMBOLIC_LINK_ALL_ACCESS
,
196 RtlFreeUnicodeString (&ArcName
);
197 if (!NT_SUCCESS(Status
))
199 RtlFreeUnicodeString (&BootPath
);
200 RtlFreeUnicodeString (&ArcDeviceName
);
201 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
207 Status
= NtQuerySymbolicLinkObject (Handle
,
211 if (!NT_SUCCESS(Status
))
213 RtlFreeUnicodeString (&BootPath
);
214 RtlFreeUnicodeString (&ArcDeviceName
);
215 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
220 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
223 /* allocate device name string */
224 DriveDeviceName
.Length
= 0;
225 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
226 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
228 for (i
= 0; i
< 26; i
++)
230 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
231 RtlInitUnicodeString (&DriveName
,
234 InitializeObjectAttributes (&ObjectAttributes
,
240 Status
= NtOpenSymbolicLinkObject (&Handle
,
241 SYMBOLIC_LINK_ALL_ACCESS
,
243 if (!NT_SUCCESS(Status
))
245 DPRINT("Failed to open link %wZ\n",
250 Status
= NtQuerySymbolicLinkObject (Handle
,
253 if (!NT_SUCCESS(Status
))
255 DPRINT("Failed query open link %wZ\n",
259 DPRINT("Opened link: %wZ ==> %wZ\n",
260 &DriveName
, &DriveDeviceName
);
262 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
))
264 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
265 swprintf(SharedUserData
->NtSystemRoot
,
266 L
"%C:%wZ", 'A' + i
, &BootPath
);
268 BootDriveFound
= TRUE
;
274 RtlFreeUnicodeString (&BootPath
);
275 RtlFreeUnicodeString (&DriveDeviceName
);
276 RtlFreeUnicodeString (&ArcDeviceName
);
278 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData
->DosDeviceMap
);
280 if (BootDriveFound
== FALSE
)
282 DbgPrint("No system drive found!\n");
289 ExpInitializeExecutive(VOID
)
291 LARGE_INTEGER Timeout
;
292 HANDLE ProcessHandle
;
294 ULONG BootDriverCount
;
304 * Fail at runtime if someone has changed various structures without
305 * updating the offsets used for the assembler code.
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
);
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
);
326 KeLowerIrql(DISPATCH_LEVEL
);
330 MmInit1(FirstKrnlPhysAddr
,
333 (PADDRESS_RANGE
)&KeMemoryMap
,
334 KeMemoryMapRangeCount
);
336 /* create default nls tables */
340 * Initialize the kernel debugger
342 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
347 KeLowerIrql(PASSIVE_LEVEL
);
350 KeBugCheck(SECURITY_INITIALIZATION_FAILED
);
355 KeBugCheck(SECURITY1_INITIALIZATION_FAILED
);
357 PiInitProcessManager();
361 if (KdPollBreakIn ())
363 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
367 * Display version number and copyright/warranty message
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 "
376 HalDisplayString("conditions. There is absolutely no warranty for "
379 /* Initialize all processors */
380 KeNumberProcessors
= 0;
382 while (!HalAllProcessorsStarted())
384 PVOID ProcessorStack
;
386 if (KeNumberProcessors
!= 0)
388 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
389 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
391 /* Allocate a stack for use when booting the processor */
392 /* FIXME: The nonpaged memory for the stack is not released after use */
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
++;
401 if (KeNumberProcessors
> 1)
404 "Found %d system processors. [%u MB Memory]\n",
406 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
411 "Found 1 system processor. [%u MB Memory]\n",
412 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
414 HalDisplayString(str
);
417 * Initialize various critical subsystems
419 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
424 LdrInitModuleManagement();
425 CmInitializeRegistry();
430 FsRtlpInitFileLockingImplementation();
432 /* Report all resources used by hal */
433 HalReportResourceUsage();
436 * Initalize services loaded at boot time
438 DPRINT("%d files loaded\n",KeLoaderBlock
.ModsCount
);
439 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
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
);
447 /* Pass 1: load nls files */
448 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
450 name
= (PCHAR
)KeLoaderModules
[i
].String
;
451 if (RtlpCheckFileNameExtension(name
, ".nls"))
458 name
= (PCHAR
)KeLoaderModules
[i
+1].String
;
459 if (RtlpCheckFileNameExtension(name
, ".nls"))
461 Mod2Start
= (ULONG
)KeLoaderModules
[i
+1].ModStart
;
462 Mod2End
= (ULONG
)KeLoaderModules
[i
+1].ModEnd
;
464 name
= (PCHAR
)KeLoaderModules
[i
+2].String
;
465 if (RtlpCheckFileNameExtension(name
, ".nls"))
467 Mod3Start
= (ULONG
)KeLoaderModules
[i
+2].ModStart
;
468 Mod3End
= (ULONG
)KeLoaderModules
[i
+2].ModEnd
;
472 /* Initialize nls sections */
473 RtlpInitNlsSections((ULONG
)KeLoaderModules
[i
].ModStart
,
474 (ULONG
)KeLoaderModules
[i
].ModEnd
,
483 /* Pass 2: import system hive registry chunk */
485 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
487 start
= KeLoaderModules
[i
].ModStart
;
488 length
= KeLoaderModules
[i
].ModEnd
- start
;
490 DPRINT("Module: '%s'\n", (PCHAR
)KeLoaderModules
[i
].String
);
491 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
494 name
= (PCHAR
)KeLoaderModules
[i
].String
;
501 if (!_stricmp (name
, "system") ||
502 !_stricmp (name
, "system.hiv"))
504 CPRINT("Process system hive registry chunk at %08lx\n", start
);
506 CmImportSystemHive((PCHAR
)start
, length
);
510 /* Pass 3: import hardware hive registry chunk */
511 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
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"))
519 CPRINT("Process hardware hive registry chunk at %08lx\n", start
);
520 CmImportHardwareHive((PCHAR
)start
, length
);
524 /* Initialize volatile registry settings */
525 if (SetupBoot
== FALSE
)
527 CmInit2((PCHAR
)KeLoaderBlock
.CommandLine
);
531 * Enter the kernel debugger before starting up the boot drivers
537 IoCreateDriverList();
539 /* Pass 4: process boot loaded drivers */
541 for (i
=1; i
< KeLoaderBlock
.ModsCount
; i
++)
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"))
549 CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n",
550 name
, start
, length
);
551 LdrInitializeBootStartDriver((PVOID
)start
, name
, length
);
553 if (RtlpCheckFileNameExtension(name
, ".sys"))
557 if (BootDriverCount
== 0)
559 DbgPrint("No boot drivers available.\n");
563 /* Create ARC names for boot devices */
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
);
572 #ifdef DBGPRINT_FILE_LOG
573 /* On the assumption that we can now access disks start up the debug
576 #endif /* DBGPRINT_FILE_LOG */
583 PiInitDefaultLocale();
586 * Start the motherboard enumerator (the HAL)
588 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
591 * Load boot start drivers
593 IopLoadBootStartDrivers();
596 * Load Auto configured drivers
598 LdrLoadAutoConfigDrivers();
601 IoDestroyDriverList();
604 * Assign drive letters
606 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
612 * Initialize shared user page:
613 * - set dos system path, dos device map, etc.
615 InitSystemSharedUserPage ((PUCHAR
)KeLoaderBlock
.CommandLine
);
618 * Launch initial process
620 Status
= LdrLoadInitialProcess(&ProcessHandle
,
622 if (!NT_SUCCESS(Status
))
624 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
628 * Crash the system if the initial process terminates within 5 seconds.
630 Timeout
.QuadPart
= -50000000LL;
631 Status
= NtWaitForSingleObject(ProcessHandle
,
634 if (Status
!= STATUS_TIMEOUT
)
636 KeBugCheckEx(SESSION5_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
639 NtClose(ThreadHandle
);
640 NtClose(ProcessHandle
);
642 PsTerminateSystemThread(STATUS_SUCCESS
);
647 KiSystemStartup(BOOLEAN BootProcessor
)
649 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
654 ExpInitializeExecutive();
657 /* Do application processor initialization */
658 KeApplicationProcessorInit();
659 PsApplicationProcessorInit();
660 KeLowerIrql(PASSIVE_LEVEL
);
661 PsIdleThreadMain(NULL
);
667 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
669 * FUNCTION: Called by the boot loader to start the kernel
671 * LoaderBlock = Pointer to boot parameters initialized by the boot
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.
679 ULONG last_kernel_address
;
680 extern ULONG _bss_end__
;
685 /* Low level architecture specific initialization */
689 * Copy the parameters to a local buffer because lowmem will go away
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
;
698 * Convert a path specification in the grub format to one understood by the
699 * rest of the kernel.
701 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[0] == '(')
703 ULONG DiskNumber
= 0, PartNumber
= 0;
709 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[1] == 'h' &&
710 ((PUCHAR
)_LoaderBlock
->CommandLine
)[2] == 'd')
712 DiskNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[3] - '0';
713 PartNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[5] - '0';
715 strcpy(Temp
, &((PUCHAR
)_LoaderBlock
->CommandLine
)[7]);
716 if ((options
= strchr(Temp
, ' ')) != NULL
)
725 if ((s1
= strrchr(Temp
, '/')) != NULL
)
728 if ((s1
= strrchr(Temp
, '/')) != NULL
)
733 sprintf(KeLoaderCommandLine
,
734 "multi(0)disk(0)rdisk(%d)partition(%d)%s %s",
735 DiskNumber
, PartNumber
+ 1, Temp
, options
);
737 p
= KeLoaderCommandLine
;
738 while (*p
!= 0 && *p
!= ' ')
746 DPRINT1("Command Line: %s\n", KeLoaderCommandLine
);
750 strcpy(KeLoaderCommandLine
, (PUCHAR
)_LoaderBlock
->CommandLine
);
752 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
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
++)
761 if ((s
= strrchr((PUCHAR
)KeLoaderModules
[i
].String
, '/')) != 0)
763 strcpy(KeLoaderModuleStrings
[i
], s
+ 1);
767 strcpy(KeLoaderModuleStrings
[i
], (PUCHAR
)KeLoaderModules
[i
].String
);
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
];
777 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
780 HalBase
= KeLoaderModules
[1].ModStart
;
782 PAGE_ROUND_UP(KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
);
787 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)0xC0000000, &DriverSize
);
789 LdrHalBase
= (ULONG_PTR
)DriverBase
;
790 last_kernel_address
= DriverBase
+ DriverSize
;
793 * Process ntoskrnl.exe
795 LdrSafePEProcessModule((PVOID
)0xC0000000, (PVOID
)0xC0000000, (PVOID
)DriverBase
, &DriverSize
);
797 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- 0xc0000000 + 0x200000;
798 LastKrnlPhysAddr
= last_kernel_address
- 0xc0000000 + 0x200000;
799 LastKernelAddress
= last_kernel_address
;
802 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
803 KeLoaderBlock
.Flags
&= ~MB_FLAGS_MMAP_INFO
;
806 KeMemoryMapRangeCount
= 0;
807 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
809 /* We have a memory map from the nice BIOS */
810 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
812 while (i
< KeLoaderBlock
.MmapLength
)
814 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
815 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
816 sizeof(ADDRESS_RANGE
));
817 KeMemoryMapRangeCount
++;