Author: fireball
Date: Tue Oct 10 14:38:45 2006
New Revision: 24480
URL:
http://svn.reactos.org/svn/reactos?rev=24480&view=rev
Log:
- Implement WinLdrLoadBootDrivers() / WinLdrLoadDeviceDriver() - to be able to load
boot-time drivers
- Perform hardware detection in the beginning (I had to insert RegInitializeRegistry()
hack because MachHwDetect initializes certain stuff in registry)
- Convert info from hwdetect to suitable form in LPB (code by Alex Ionescu, just
moved/adapted). Debug routine added to output its contents.
- Move allocation memory for NlsData into "phase 0" (AllocateAndInitLPB)
- Fixed SystemRoot to be of a correct form (later will be autogenerated of course, now
just for reference)
Modified:
trunk/reactos/boot/freeldr/freeldr/windows/winldr.c
Modified: trunk/reactos/boot/freeldr/freeldr/windows/winldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/winldr.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/winldr.c Tue Oct 10 14:38:45 2006
@@ -26,10 +26,25 @@
//#define NDEBUG
#include <debug.h>
+//FIXME: Do a better way to retrieve Arc disk information
+extern ULONG reactos_disk_count;
+extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
+extern char reactos_arc_strings[32][256];
+
+ARC_DISK_SIGNATURE BldrDiskInfo[32];
+CHAR BldrArcNames[32][256];
+
+BOOLEAN
+WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
+ IN PCH DllName,
+ OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
+
// debug stuff
VOID DumpMemoryAllocMap(VOID);
VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
+VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock);
+
void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
{
@@ -87,6 +102,14 @@
InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
InitializeListHead(&LoaderBlock->BootDriverListHead);
+ /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
+ LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK));
+ if (LoaderBlock->NlsData == NULL)
+ {
+ UiMessageBox("Failed to allocate memory for NLS table data!");
+ return;
+ }
+ RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK));
*OutLoaderBlock = LoaderBlock;
}
@@ -97,11 +120,12 @@
{
//CHAR Options[] = "/CRASHDEBUG /DEBUGPORT=COM1 /BAUDRATE=115200";
CHAR Options[] = "/NODEBUG";
- CHAR SystemRoot[] = "\\WINNT";
+ CHAR SystemRoot[] = "\\WINNT\\";
CHAR HalPath[] = "\\";
CHAR ArcBoot[] = "multi(0)disk(0)rdisk(1)partition(1)";
CHAR ArcHal[] = "multi(0)disk(0)rdisk(1)partition(1)";
+ ULONG i;
PLOADER_PARAMETER_EXTENSION Extension;
LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
@@ -134,17 +158,31 @@
/* Arc devices */
LoaderBlock->ArcDiskInformation =
(PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION));
InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
+
+ /* Convert ARC disk information from freeldr to a correct format */
+ for (i = 0; i < reactos_disk_count; i++)
+ {
+ PARC_DISK_SIGNATURE ArcDiskInfo;
+
+ /* Get the ARC structure */
+ ArcDiskInfo = &BldrDiskInfo[i];
+
+ /* Copy the data over */
+ ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature;
+ ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum;
+
+ /* Copy the ARC Name */
+ strcpy(BldrArcNames[i], reactos_arc_disk_info[i].ArcName);
+ ArcDiskInfo->ArcName = BldrArcNames[i];
+
+ /* Insert into the list */
+ InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
+ &ArcDiskInfo->ListEntry);
+ }
+
+ /* Convert the list to virtual address */
List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
-
- /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
- LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK));
- if (LoaderBlock->NlsData == NULL)
- {
- UiMessageBox("Failed to allocate memory for NLS table data!");
- return;
- }
- RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK));
/* Create configuration entries */
InitializeHWConfig(LoaderBlock);
@@ -224,6 +262,111 @@
/* Zero newly prepared GDT+IDT */
RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT);
+}
+
+BOOLEAN
+WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
+ LPSTR BootPath,
+ PUNICODE_STRING FilePath,
+ ULONG Flags,
+ PLDR_DATA_TABLE_ENTRY *DriverDTE)
+{
+ CHAR FullPath[1024];
+ CHAR DriverPath[1024];
+ CHAR DllName[1024];
+ PCHAR DriverNamePos;
+ BOOLEAN Status;
+ PVOID DriverBase;
+
+ // Separate the path to file name and directory path
+ sprintf(DriverPath, "%wZ", FilePath);
+ DriverNamePos = strrchr(DriverPath, '\\');
+ if (DriverNamePos != NULL)
+ {
+ // Copy the name
+ strcpy(DllName, DriverNamePos+1);
+
+ // Cut out the name from the path
+ *(DriverNamePos+1) = 0;
+ }
+
+ DbgPrint((DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath,
DllName, LoaderBlock));
+
+
+ // Check if driver is already loaded
+ Status = WinLdrCheckForLoadedDll(LoaderBlock, DllName, DriverDTE);
+ if (Status)
+ {
+ // We've got the pointer to its DTE, just return success
+ return TRUE;
+ }
+
+ // It's not loaded, we have to load it
+ sprintf(FullPath,"%s%wZ", BootPath, FilePath);
+ Status = WinLdrLoadImage(FullPath, &DriverBase);
+ if (!Status)
+ return FALSE;
+
+ // Allocate a DTE for it
+ Status = WinLdrAllocateDataTableEntry(LoaderBlock, DllName, DllName, DriverBase,
DriverDTE);
+ if (!Status)
+ {
+ DbgPrint((DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n"));
+ return FALSE;
+ }
+
+ // Modify any flags, if needed
+ (*DriverDTE)->Flags |= Flags;
+
+ // Look for any dependencies it may have, and load them too
+ sprintf(FullPath,"%s%s", BootPath, DriverPath);
+ Status = WinLdrScanImportDescriptorTable(LoaderBlock, FullPath, *DriverDTE);
+ if (!Status)
+ {
+ DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for
%s\n",
+ FullPath));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOLEAN
+WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
+ LPSTR BootPath)
+{
+ PLIST_ENTRY NextBd;
+ PBOOT_DRIVER_LIST_ENTRY BootDriver;
+ BOOLEAN Status;
+
+ // Walk through the boot drivers list
+ NextBd = LoaderBlock->BootDriverListHead.Flink;
+
+ while (NextBd != &LoaderBlock->BootDriverListHead)
+ {
+ BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
+
+ //DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n",
&BootDriver->FilePath,
+ // BootDriver->DataTableEntry, &BootDriver->RegistryPath));
+
+ // Paths are relative (FIXME: Are they always relative?)
+
+ // Load it
+ Status = WinLdrLoadDeviceDriver(LoaderBlock, BootPath, &BootDriver->FilePath,
+ 0, &BootDriver->DataTableEntry);
+
+ // If loading failed - cry loudly
+ //FIXME: Maybe remove it from the list and try to continue?
+ if (!Status)
+ {
+ UiMessageBox("Can't load boot driver!");
+ return FALSE;
+ }
+
+ NextBd = BootDriver->ListEntry.Flink;
+ }
+
+ return TRUE;
}
VOID
@@ -245,8 +388,6 @@
ULONG PcrBasePage=0;
ULONG TssBasePage=0;
-
-
//sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is
not implemented yet", OperatingSystemVersion);
//UiMessageBox(MsgBuffer);
@@ -259,6 +400,13 @@
return;
}
+ UiDrawBackdrop();
+ UiDrawStatusText("Detecting Hardware...");
+ UiDrawProgressBarCenter(1, 100, "Loading Windows...");
+
+ //FIXME: This is needed only for MachHwDetect() which performs registry operations!
+ RegInitializeRegistry();
+
/* Make sure the system path is set in the .ini file */
if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath,
sizeof(SystemPath)))
{
@@ -272,6 +420,9 @@
UiMessageBox("Invalid system path");
return;
}
+
+ /* Detect hardware */
+ MachHwDetect();
UiDrawStatusText("Loading...");
@@ -333,15 +484,16 @@
if (KdComDTE)
WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KdComDTE);
- /* Initialize Phase 1 - before NLS */
- WinLdrInitializePhase1(LoaderBlock);
-
/* Load Hive, and then NLS data, OEM font, and prepare boot drivers list */
Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath);
DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n",
Status));
/* Load boot drivers */
- //WinLdrLoadBootDrivers();
+ Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
+ DbgPrint((DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status));
+
+ /* Initialize Phase 1 - no drivers loading anymore */
+ WinLdrInitializePhase1(LoaderBlock);
/* Alloc PCR, TSS, do magic things with the GDT/IDT */
WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
@@ -362,6 +514,7 @@
WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
WinLdrpDumpBootDriver(LoaderBlockVA);
+ WinLdrpDumpArcDisks(LoaderBlockVA);
//FIXME: If I substitute this debugging checkpoint, GCC will "optimize away"
the code below
//while (1) {};
@@ -414,3 +567,23 @@
NextBd = BootDriver->ListEntry.Flink;
}
}
+
+VOID
+WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PLIST_ENTRY NextBd;
+ PARC_DISK_SIGNATURE ArcDisk;
+
+ NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink;
+
+ while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead)
+ {
+ ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
+
+ DbgPrint((DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
+ ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature));
+
+ NextBd = ArcDisk->ListEntry.Flink;
+ }
+}
+