Synchronize with trunk's revision r57599.
[reactos.git] / boot / freeldr / freeldr / windows / winldr.c
1 /*
2 * FreeLoader
3 *
4 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 * Copyright (C) 2006 Aleksey Bragin <aleksey@reactos.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include <freeldr.h>
23
24 #include <ndk/ldrtypes.h>
25 #include <debug.h>
26
27 DBG_DEFAULT_CHANNEL(WINDOWS);
28
29 //FIXME: Do a better way to retrieve Arc disk information
30 extern ULONG reactos_disk_count;
31 extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
32
33 extern BOOLEAN UseRealHeap;
34 extern ULONG LoaderPagesSpanned;
35 extern BOOLEAN AcpiPresent;
36
37 extern HEADLESS_LOADER_BLOCK LoaderRedirectionInformation;
38 extern BOOLEAN WinLdrTerminalConnected;
39 extern void WinLdrSetupEms(IN PCHAR BootOptions);
40
41 PLOADER_SYSTEM_BLOCK WinLdrSystemBlock;
42
43 // debug stuff
44 VOID DumpMemoryAllocMap(VOID);
45
46 // Init "phase 0"
47 VOID
48 AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
49 {
50 PLOADER_PARAMETER_BLOCK LoaderBlock;
51
52 /* Allocate and zero-init the LPB */
53 WinLdrSystemBlock = MmAllocateMemoryWithType(sizeof(LOADER_SYSTEM_BLOCK),
54 LoaderSystemBlock);
55 if (WinLdrSystemBlock == NULL)
56 {
57 UiMessageBox("Failed to allocate memory for system block!");
58 return;
59 }
60
61 RtlZeroMemory(WinLdrSystemBlock, sizeof(LOADER_SYSTEM_BLOCK));
62
63 LoaderBlock = &WinLdrSystemBlock->LoaderBlock;
64 LoaderBlock->NlsData = &WinLdrSystemBlock->NlsDataBlock;
65
66 /* Init three critical lists, used right away */
67 InitializeListHead(&LoaderBlock->LoadOrderListHead);
68 InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
69 InitializeListHead(&LoaderBlock->BootDriverListHead);
70
71 *OutLoaderBlock = LoaderBlock;
72 }
73
74 // Init "phase 1"
75 VOID
76 WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
77 LPCSTR Options,
78 LPCSTR SystemRoot,
79 LPCSTR BootPath,
80 USHORT VersionToBoot)
81 {
82 /* Examples of correct options and paths */
83 //CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
84 //CHAR Options[] = "/NODEBUG";
85 //CHAR SystemRoot[] = "\\WINNT\\";
86 //CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
87
88 CHAR HalPath[] = "\\";
89 CHAR ArcBoot[256];
90 CHAR MiscFiles[256];
91 ULONG i;
92 ULONG_PTR PathSeparator;
93 PLOADER_PARAMETER_EXTENSION Extension;
94
95 /* Construct SystemRoot and ArcBoot from SystemPath */
96 PathSeparator = strstr(BootPath, "\\") - BootPath;
97 strncpy(ArcBoot, BootPath, PathSeparator);
98 ArcBoot[PathSeparator] = 0;
99
100 TRACE("ArcBoot: %s\n", ArcBoot);
101 TRACE("SystemRoot: %s\n", SystemRoot);
102 TRACE("Options: %s\n", Options);
103
104 /* Fill Arc BootDevice */
105 LoaderBlock->ArcBootDeviceName = WinLdrSystemBlock->ArcBootDeviceName;
106 strncpy(LoaderBlock->ArcBootDeviceName, ArcBoot, MAX_PATH);
107 LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
108
109 /* Fill Arc HalDevice, it matches ArcBoot path */
110 LoaderBlock->ArcHalDeviceName = WinLdrSystemBlock->ArcBootDeviceName;
111 LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);
112
113 /* Fill SystemRoot */
114 LoaderBlock->NtBootPathName = WinLdrSystemBlock->NtBootPathName;
115 strncpy(LoaderBlock->NtBootPathName, SystemRoot, MAX_PATH);
116 LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
117
118 /* Fill NtHalPathName */
119 LoaderBlock->NtHalPathName = WinLdrSystemBlock->NtHalPathName;
120 strncpy(LoaderBlock->NtHalPathName, HalPath, MAX_PATH);
121 LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
122
123 /* Fill load options */
124 LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions;
125 strncpy(LoaderBlock->LoadOptions, Options, MAX_OPTIONS_LENGTH);
126 LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
127
128 /* Arc devices */
129 LoaderBlock->ArcDiskInformation = &WinLdrSystemBlock->ArcDiskInformation;
130 InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
131
132 /* Convert ARC disk information from freeldr to a correct format */
133 for (i = 0; i < reactos_disk_count; i++)
134 {
135 PARC_DISK_SIGNATURE_EX ArcDiskSig;
136
137 /* Allocate the ARC structure */
138 ArcDiskSig = HeapAllocate(FrLdrDefaultHeap,
139 sizeof(ARC_DISK_SIGNATURE_EX),
140 'giSD');
141
142 /* Copy the data over */
143 ArcDiskSig->DiskSignature.Signature = reactos_arc_disk_info[i].Signature;
144 ArcDiskSig->DiskSignature.CheckSum = reactos_arc_disk_info[i].CheckSum;
145
146 /* Copy the ARC Name */
147 strncpy(ArcDiskSig->ArcName, reactos_arc_disk_info[i].ArcName, MAX_PATH);
148 ArcDiskSig->DiskSignature.ArcName = PaToVa(ArcDiskSig->ArcName);
149
150 /* Mark partition table as valid */
151 ArcDiskSig->DiskSignature.ValidPartitionTable = TRUE;
152
153 /* Insert into the list */
154 InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
155 &ArcDiskSig->DiskSignature.ListEntry);
156 }
157
158 /* Convert all list's to Virtual address */
159
160 /* Convert the ArcDisks list to virtual address */
161 List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
162 LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
163
164 /* Convert configuration entries to VA */
165 ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
166 LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
167
168 /* Convert all DTE into virtual addresses */
169 List_PaToVa(&LoaderBlock->LoadOrderListHead);
170
171 /* this one will be converted right before switching to
172 virtual paging mode */
173 //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
174
175 /* Convert list of boot drivers */
176 List_PaToVa(&LoaderBlock->BootDriverListHead);
177
178 /* Initialize Extension now */
179 Extension = &WinLdrSystemBlock->Extension;
180 Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
181 Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
182 Extension->MinorVersion = VersionToBoot & 0xFF;
183 Extension->Profile.Status = 2;
184
185 /* Check if ACPI is present */
186 if (AcpiPresent)
187 {
188 /* See KiRosFrldrLpbToNtLpb for details */
189 Extension->AcpiTable = (PVOID)1;
190 }
191
192 #ifdef _M_IX86
193 /* Set headless block pointer */
194 if (WinLdrTerminalConnected)
195 {
196 Extension->HeadlessLoaderBlock = &WinLdrSystemBlock->HeadlessLoaderBlock;
197 RtlCopyMemory(Extension->HeadlessLoaderBlock,
198 &LoaderRedirectionInformation,
199 sizeof(HEADLESS_LOADER_BLOCK));
200 Extension->HeadlessLoaderBlock = PaToVa(Extension->HeadlessLoaderBlock);
201 }
202 #endif
203 /* Load drivers database */
204 strcpy(MiscFiles, BootPath);
205 strcat(MiscFiles, "AppPatch\\drvmain.sdb");
206 Extension->DrvDBImage = PaToVa(WinLdrLoadModule(MiscFiles,
207 &Extension->DrvDBSize,
208 LoaderRegistryData));
209
210 /* Convert extension and setup block pointers */
211 LoaderBlock->Extension = PaToVa(Extension);
212
213 if (LoaderBlock->SetupLdrBlock)
214 LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock);
215
216 TRACE("WinLdrInitializePhase1() completed\n");
217 }
218
219 static BOOLEAN
220 WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
221 LPSTR BootPath,
222 PUNICODE_STRING FilePath,
223 ULONG Flags,
224 PLDR_DATA_TABLE_ENTRY *DriverDTE)
225 {
226 CHAR FullPath[1024];
227 CHAR DriverPath[1024];
228 CHAR DllName[1024];
229 PCHAR DriverNamePos;
230 BOOLEAN Status;
231 PVOID DriverBase;
232
233 // Separate the path to file name and directory path
234 _snprintf(DriverPath, sizeof(DriverPath), "%wZ", FilePath);
235 DriverNamePos = strrchr(DriverPath, '\\');
236 if (DriverNamePos != NULL)
237 {
238 // Copy the name
239 strcpy(DllName, DriverNamePos+1);
240
241 // Cut out the name from the path
242 *(DriverNamePos+1) = 0;
243 }
244 else
245 {
246 // There is no directory in the path
247 strcpy(DllName, DriverPath);
248 DriverPath[0] = 0;
249 }
250
251 TRACE("DriverPath: %s, DllName: %s, LPB\n", DriverPath, DllName);
252
253
254 // Check if driver is already loaded
255 Status = WinLdrCheckForLoadedDll(LoadOrderListHead, DllName, DriverDTE);
256 if (Status)
257 {
258 // We've got the pointer to its DTE, just return success
259 return TRUE;
260 }
261
262 // It's not loaded, we have to load it
263 _snprintf(FullPath, sizeof(FullPath), "%s%wZ", BootPath, FilePath);
264 Status = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
265 if (!Status)
266 return FALSE;
267
268 // Allocate a DTE for it
269 Status = WinLdrAllocateDataTableEntry(LoadOrderListHead, DllName, DllName, DriverBase, DriverDTE);
270 if (!Status)
271 {
272 ERR("WinLdrAllocateDataTableEntry() failed\n");
273 return FALSE;
274 }
275
276 // Modify any flags, if needed
277 (*DriverDTE)->Flags |= Flags;
278
279 // Look for any dependencies it may have, and load them too
280 sprintf(FullPath,"%s%s", BootPath, DriverPath);
281 Status = WinLdrScanImportDescriptorTable(LoadOrderListHead, FullPath, *DriverDTE);
282 if (!Status)
283 {
284 ERR("WinLdrScanImportDescriptorTable() failed for %s\n", FullPath);
285 return FALSE;
286 }
287
288 return TRUE;
289 }
290
291 BOOLEAN
292 WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
293 LPSTR BootPath)
294 {
295 PLIST_ENTRY NextBd;
296 PBOOT_DRIVER_LIST_ENTRY BootDriver;
297 BOOLEAN Status;
298
299 // Walk through the boot drivers list
300 NextBd = LoaderBlock->BootDriverListHead.Flink;
301
302 while (NextBd != &LoaderBlock->BootDriverListHead)
303 {
304 BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
305
306 TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
307 BootDriver->LdrEntry, &BootDriver->RegistryPath);
308
309 // Paths are relative (FIXME: Are they always relative?)
310
311 // Load it
312 Status = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead, BootPath, &BootDriver->FilePath,
313 0, &BootDriver->LdrEntry);
314
315 // If loading failed - cry loudly
316 //FIXME: Maybe remove it from the list and try to continue?
317 if (!Status)
318 {
319 UiMessageBox("Can't load boot driver!");
320 return FALSE;
321 }
322
323 // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore
324 BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);
325 BootDriver->FilePath.Buffer = PaToVa(BootDriver->FilePath.Buffer);
326 BootDriver->LdrEntry = PaToVa(BootDriver->LdrEntry);
327
328 NextBd = BootDriver->Link.Flink;
329 }
330
331 return TRUE;
332 }
333
334 PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size,
335 TYPE_OF_MEMORY MemoryType)
336 {
337 ULONG FileId;
338 PVOID PhysicalBase;
339 FILEINFORMATION FileInfo;
340 ULONG FileSize;
341 ULONG Status;
342 ULONG BytesRead;
343
344 //CHAR ProgressString[256];
345
346 /* Inform user we are loading files */
347 //sprintf(ProgressString, "Loading %s...", FileName);
348 //UiDrawProgressBarCenter(1, 100, ProgressString);
349
350 TRACE("Loading module %s\n", ModuleName);
351 *Size = 0;
352
353 /* Open the image file */
354 Status = ArcOpen((PCHAR)ModuleName, OpenReadOnly, &FileId);
355 if (Status != ESUCCESS)
356 {
357 /* In case of errors, we just return, without complaining to the user */
358 return NULL;
359 }
360
361 /* Get this file's size */
362 Status = ArcGetFileInformation(FileId, &FileInfo);
363 if (Status != ESUCCESS)
364 {
365 ArcClose(FileId);
366 return NULL;
367 }
368 FileSize = FileInfo.EndingAddress.LowPart;
369 *Size = FileSize;
370
371 /* Allocate memory */
372 PhysicalBase = MmAllocateMemoryWithType(FileSize, MemoryType);
373 if (PhysicalBase == NULL)
374 {
375 ArcClose(FileId);
376 return NULL;
377 }
378
379 /* Load whole file */
380 Status = ArcRead(FileId, PhysicalBase, FileSize, &BytesRead);
381 ArcClose(FileId);
382 if (Status != ESUCCESS)
383 {
384 return NULL;
385 }
386
387 TRACE("Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize);
388
389 return PhysicalBase;
390 }
391
392
393 USHORT
394 WinLdrDetectVersion()
395 {
396 LONG rc;
397 FRLDRHKEY hKey;
398
399 rc = RegOpenKey(
400 NULL,
401 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
402 &hKey);
403 if (rc != ERROR_SUCCESS)
404 {
405 // Key doesn't exist; assume NT 4.0
406 return _WIN32_WINNT_NT4;
407 }
408
409 // We may here want to read the value of ProductVersion
410 return _WIN32_WINNT_WS03;
411 }
412
413 static
414 PVOID
415 LoadModule(
416 PLOADER_PARAMETER_BLOCK LoaderBlock,
417 PCCH Path,
418 PCCH File,
419 TYPE_OF_MEMORY MemoryType,
420 PLDR_DATA_TABLE_ENTRY *Dte,
421 ULONG Percentage)
422 {
423 CHAR FullFileName[MAX_PATH];
424 CHAR ProgressString[256];
425 NTSTATUS Status;
426 PVOID BaseAdress;
427
428 UiDrawBackdrop();
429 sprintf(ProgressString, "Loading %s...", File);
430 UiDrawProgressBarCenter(Percentage, 100, ProgressString);
431
432 strcpy(FullFileName, Path);
433 strcat(FullFileName, "SYSTEM32\\");
434 strcat(FullFileName, File);
435
436 Status = WinLdrLoadImage(FullFileName, MemoryType, &BaseAdress);
437 TRACE("%s loaded with status %d at %p\n",
438 File, Status, BaseAdress);
439
440 strcpy(FullFileName, "WINDOWS\\SYSTEM32\\");
441 strcat(FullFileName, File);
442 WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead, File,
443 FullFileName, BaseAdress, Dte);
444
445 return BaseAdress;
446 }
447
448 VOID
449 LoadAndBootWindows(PCSTR OperatingSystemName,
450 PSTR SettingsValue,
451 USHORT OperatingSystemVersion)
452 {
453 BOOLEAN HasSection;
454 char BootPath[MAX_PATH];
455 CHAR FileName[MAX_PATH];
456 CHAR BootOptions[256];
457 PCHAR File;
458 BOOLEAN Status;
459 ULONG_PTR SectionId;
460 PLOADER_PARAMETER_BLOCK LoaderBlock;
461
462 // Open the operating system section
463 // specified in the .ini file
464 HasSection = IniOpenSection(OperatingSystemName, &SectionId);
465
466 UiDrawBackdrop();
467 UiDrawProgressBarCenter(1, 100, "Loading NT...");
468
469 /* Read the system path is set in the .ini file */
470 if (!HasSection ||
471 !IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath)))
472 {
473 strcpy(BootPath, OperatingSystemName);
474 }
475
476 /* Special case for LiveCD */
477 if (!_strnicmp(BootPath, "LiveCD", strlen("LiveCD")))
478 {
479 strcpy(FileName, BootPath + strlen("LiveCD"));
480 MachDiskGetBootPath(BootPath, sizeof(BootPath));
481 strcat(BootPath, FileName);
482 }
483
484 /* append a backslash */
485 if ((strlen(BootPath)==0) || BootPath[strlen(BootPath)] != '\\')
486 strcat(BootPath, "\\");
487
488 /* Read booting options */
489 if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))
490 {
491 /* Get options after the title */
492 const CHAR*p = SettingsValue;
493 while (*p == ' ' || *p == '"')
494 p++;
495 while (*p != '\0' && *p != '"')
496 p++;
497 strcpy(BootOptions, p);
498 TRACE("BootOptions: '%s'\n", BootOptions);
499 }
500
501 /* Append boot-time options */
502 AppendBootTimeOptions(BootOptions);
503
504 /* Check if a ramdisk file was given */
505 File = strstr(BootOptions, "/RDPATH=");
506 if (File)
507 {
508 /* Copy the file name and everything else after it */
509 strcpy(FileName, File + 8);
510
511 /* Null-terminate */
512 *strstr(FileName, " ") = ANSI_NULL;
513
514 /* Load the ramdisk */
515 RamDiskLoadVirtualFile(FileName);
516 }
517
518 /* Let user know we started loading */
519 //UiDrawStatusText("Loading...");
520
521 TRACE("BootPath: '%s'\n", BootPath);
522
523 /* Allocate and minimalistic-initialize LPB */
524 AllocateAndInitLPB(&LoaderBlock);
525
526 #ifdef _M_IX86
527 /* Setup redirection support */
528 WinLdrSetupEms(BootOptions);
529 #endif
530
531 /* Load Hive */
532 UiDrawBackdrop();
533 UiDrawProgressBarCenter(15, 100, "Loading system hive...");
534 Status = WinLdrInitSystemHive(LoaderBlock, BootPath);
535 TRACE("SYSTEM hive loaded with status %d\n", Status);
536
537 /* Load NLS data, OEM font, and prepare boot drivers list */
538 Status = WinLdrScanSystemHive(LoaderBlock, BootPath);
539 TRACE("SYSTEM hive scanned with status %d\n", Status);
540
541
542 LoadAndBootWindowsCommon(OperatingSystemVersion,
543 LoaderBlock,
544 BootOptions,
545 BootPath,
546 0);
547 }
548
549 VOID
550 LoadAndBootWindowsCommon(
551 USHORT OperatingSystemVersion,
552 PLOADER_PARAMETER_BLOCK LoaderBlock,
553 LPCSTR BootOptions,
554 LPCSTR BootPath,
555 BOOLEAN Setup)
556 {
557 PLOADER_PARAMETER_BLOCK LoaderBlockVA;
558 BOOLEAN Status;
559 CHAR FileName[MAX_PATH];
560 PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL;
561 KERNEL_ENTRY_POINT KiSystemStartup;
562 LPCSTR SystemRoot;
563 TRACE("LoadAndBootWindowsCommon()\n");
564
565 /* Convert BootPath to SystemRoot */
566 SystemRoot = strstr(BootPath, "\\");
567
568 /* Detect hardware */
569 UseRealHeap = TRUE;
570 LoaderBlock->ConfigurationRoot = MachHwDetect();
571
572 if (OperatingSystemVersion == 0)
573 OperatingSystemVersion = WinLdrDetectVersion();
574
575 /* Load kernel */
576 LoadModule(LoaderBlock, BootPath, "NTOSKRNL.EXE", LoaderSystemCode, &KernelDTE, 30);
577
578 /* Load HAL */
579 LoadModule(LoaderBlock, BootPath, "HAL.DLL", LoaderHalCode, &HalDTE, 45);
580
581 /* Load kernel-debugger support dll */
582 if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
583 {
584 LoadModule(LoaderBlock, BootPath, "KDCOM.DLL", LoaderSystemCode, &KdComDTE, 60);
585 }
586
587 /* Load all referenced DLLs for kernel, HAL and kdcom.dll */
588 strcpy(FileName, BootPath);
589 strcat(FileName, "system32\\");
590 Status = WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, FileName, KernelDTE);
591 Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, FileName, HalDTE);
592 if (KdComDTE)
593 Status &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, FileName, KdComDTE);
594
595 if (!Status)
596 {
597 UiMessageBox("Error loading imported dll.");
598 return;
599 }
600
601 /* Load boot drivers */
602 UiDrawBackdrop();
603 UiDrawProgressBarCenter(100, 100, "Loading boot drivers...");
604 Status = WinLdrLoadBootDrivers(LoaderBlock, (PCHAR)BootPath);
605 TRACE("Boot drivers loaded with status %d\n", Status);
606
607 /* Initialize Phase 1 - no drivers loading anymore */
608 WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemRoot, BootPath, OperatingSystemVersion);
609
610 /* Save entry-point pointer and Loader block VAs */
611 KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
612 LoaderBlockVA = PaToVa(LoaderBlock);
613
614 /* "Stop all motors", change videomode */
615 MachPrepareForReactOS(Setup);
616
617 /* Debugging... */
618 //DumpMemoryAllocMap();
619
620 /* Do the machine specific initialization */
621 WinLdrSetupMachineDependent(LoaderBlock);
622
623 /* Map pages and create memory descriptors */
624 WinLdrSetupMemoryLayout(LoaderBlock);
625
626 /* Set processor context */
627 WinLdrSetProcessorContext();
628
629 /* Save final value of LoaderPagesSpanned */
630 LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
631
632 TRACE("Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
633 KiSystemStartup, LoaderBlockVA);
634
635 // Zero KI_USER_SHARED_DATA page
636 memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE);
637
638 WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
639 WinLdrpDumpBootDriver(LoaderBlockVA);
640 #ifndef _M_AMD64
641 WinLdrpDumpArcDisks(LoaderBlockVA);
642 #endif
643
644 //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below
645 //while (1) {};
646 /*asm(".intel_syntax noprefix\n");
647 asm("test1:\n");
648 asm("jmp test1\n");
649 asm(".att_syntax\n");*/
650
651 /* Pass control */
652 (*KiSystemStartup)(LoaderBlockVA);
653 }
654
655 VOID
656 WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
657 {
658 PLIST_ENTRY NextMd;
659 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
660
661 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
662
663 while (NextMd != &LoaderBlock->MemoryDescriptorListHead)
664 {
665 MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
666
667 TRACE("BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
668 MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType);
669
670 NextMd = MemoryDescriptor->ListEntry.Flink;
671 }
672 }
673
674 VOID
675 WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)
676 {
677 PLIST_ENTRY NextBd;
678 PBOOT_DRIVER_LIST_ENTRY BootDriver;
679
680 NextBd = LoaderBlock->BootDriverListHead.Flink;
681
682 while (NextBd != &LoaderBlock->BootDriverListHead)
683 {
684 BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
685
686 TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
687 BootDriver->LdrEntry, &BootDriver->RegistryPath);
688
689 NextBd = BootDriver->Link.Flink;
690 }
691 }
692
693 VOID
694 WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
695 {
696 PLIST_ENTRY NextBd;
697 PARC_DISK_SIGNATURE ArcDisk;
698
699 NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink;
700
701 while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead)
702 {
703 ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
704
705 TRACE("ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
706 ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature);
707
708 NextBd = ArcDisk->ListEntry.Flink;
709 }
710 }
711
712