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