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