[FREELDR]
[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 }
218
219 BOOLEAN
220 WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
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 %p\n", DriverPath, DllName, LoaderBlock);
252
253
254 // Check if driver is already loaded
255 Status = WinLdrCheckForLoadedDll(LoaderBlock, 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(LoaderBlock, 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(LoaderBlock, 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, 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, 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, FileName, KernelDTE);
591 Status &= WinLdrScanImportDescriptorTable(LoaderBlock, FileName, HalDTE);
592 if (KdComDTE)
593 Status &= WinLdrScanImportDescriptorTable(LoaderBlock, 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 WinLdrpDumpArcDisks(LoaderBlockVA);
641
642 //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below
643 //while (1) {};
644 /*asm(".intel_syntax noprefix\n");
645 asm("test1:\n");
646 asm("jmp test1\n");
647 asm(".att_syntax\n");*/
648
649 /* Pass control */
650 (*KiSystemStartup)(LoaderBlockVA);
651 }
652
653 VOID
654 WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
655 {
656 PLIST_ENTRY NextMd;
657 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
658
659 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
660
661 while (NextMd != &LoaderBlock->MemoryDescriptorListHead)
662 {
663 MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
664
665 TRACE("BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
666 MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType);
667
668 NextMd = MemoryDescriptor->ListEntry.Flink;
669 }
670 }
671
672 VOID
673 WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)
674 {
675 PLIST_ENTRY NextBd;
676 PBOOT_DRIVER_LIST_ENTRY BootDriver;
677
678 NextBd = LoaderBlock->BootDriverListHead.Flink;
679
680 while (NextBd != &LoaderBlock->BootDriverListHead)
681 {
682 BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
683
684 TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
685 BootDriver->LdrEntry, &BootDriver->RegistryPath);
686
687 NextBd = BootDriver->Link.Flink;
688 }
689 }
690
691 VOID
692 WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
693 {
694 PLIST_ENTRY NextBd;
695 PARC_DISK_SIGNATURE ArcDisk;
696
697 NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink;
698
699 while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead)
700 {
701 ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
702
703 TRACE("ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
704 ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature);
705
706 NextBd = ArcDisk->ListEntry.Flink;
707 }
708 }
709
710