Author: fireball
Date: Mon Oct 2 01:15:15 2006
New Revision: 24354
URL:
http://svn.reactos.org/svn/reactos?rev=24354&view=rev
Log:
- Implement loading of NLS data, SYSTEM hive data (just simple loading into memory,
without any kind of parsing or even checking if that data is correct)
- Add a function for creating a stub of hardware config (config consisting of only one
node - root)
- Implement two steps of LPB initialization (names Phase 0 and Phase 1 are used internally
by me, and doesn't correspond to anything)
- Implement a WinLdrSetupForNt, which allocates and initializes some specific structures
(PCR, TSS, GDT, IDT)
- Respectively enable calls to these functions from LoadAndBootWindows()
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 Mon Oct 2 01:15:15 2006
@@ -27,6 +27,422 @@
VOID DumpMemoryAllocMap(VOID);
VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
+BOOLEAN
+WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN LPCSTR DirectoryPath,
+ IN LPCSTR AnsiFileName,
+ IN LPCSTR OemFileName,
+ IN LPCSTR LanguageFileName)
+{
+ CHAR FileName[255];
+ PFILE AnsiFileHandle;
+ PFILE OemFileHandle;
+ PFILE LanguageFileHandle;
+ ULONG AnsiFileSize, OemFileSize, LanguageFileSize;
+ ULONG TotalSize;
+ ULONG_PTR NlsDataBase;
+ PVOID NlsVirtual;
+ BOOLEAN Status, AnsiEqualsOem = FALSE;
+
+ /* There may be a case, when OEM and ANSI page coincide */
+ if (!strcmp(AnsiFileName, OemFileName))
+ AnsiEqualsOem = TRUE;
+
+ /* Open file with ANSI and store its size */
+ //Print(L"Loading %s...\n", Filename);
+ strcpy(FileName, DirectoryPath);
+ strcat(FileName, AnsiFileName);
+ AnsiFileHandle = FsOpenFile(FileName);
+
+ if (AnsiFileHandle == NULL)
+ goto Failure;
+
+ AnsiFileSize = FsGetFileSize(AnsiFileHandle);
+ DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize));
+ FsCloseFile(AnsiFileHandle);
+
+ /* Open OEM file and store its length */
+ if (AnsiEqualsOem)
+ {
+ OemFileSize = 0;
+ }
+ else
+ {
+ //Print(L"Loading %s...\n", Filename);
+ strcpy(FileName, DirectoryPath);
+ strcat(FileName, OemFileName);
+ OemFileHandle = FsOpenFile(FileName);
+
+ if (OemFileHandle == NULL)
+ goto Failure;
+
+ OemFileSize = FsGetFileSize(OemFileHandle);
+ FsCloseFile(OemFileHandle);
+ }
+ DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize));
+
+ /* And finally open the language codepage file and store its length */
+ //Print(L"Loading %s...\n", Filename);
+ strcpy(FileName, DirectoryPath);
+ strcat(FileName, LanguageFileName);
+ LanguageFileHandle = FsOpenFile(FileName);
+
+ if (LanguageFileHandle == NULL)
+ goto Failure;
+
+ LanguageFileSize = FsGetFileSize(LanguageFileHandle);
+ FsCloseFile(LanguageFileHandle);
+ DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize));
+
+ /* Sum up all three length, having in mind that every one of them
+ must start at a page boundary => thus round up each file to a page */
+ TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +
+ MM_SIZE_TO_PAGES(OemFileSize) +
+ MM_SIZE_TO_PAGES(LanguageFileSize);
+
+ NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE);
+
+ if (NlsDataBase == 0)
+ goto Failure;
+
+ NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase);
+ LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
+ LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual +
+ (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
+ LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual +
+ (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +
+ (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT));
+
+ /* Ansi and OEM data are the same - just set pointers to the same area */
+ if (AnsiEqualsOem)
+ LoaderBlock->NlsData->OemCodePageData =
LoaderBlock->NlsData->AnsiCodePageData;
+
+
+ /* Now actually read the data into memory, starting with Ansi file */
+ strcpy(FileName, DirectoryPath);
+ strcat(FileName, AnsiFileName);
+ AnsiFileHandle = FsOpenFile(FileName);
+
+ if (AnsiFileHandle == NULL)
+ goto Failure;
+
+ Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL,
VaToPa(LoaderBlock->NlsData->AnsiCodePageData));
+
+ if (!Status)
+ goto Failure;
+
+ FsCloseFile(AnsiFileHandle);
+
+ /* OEM now, if it doesn't equal Ansi of course */
+ if (!AnsiEqualsOem)
+ {
+ strcpy(FileName, DirectoryPath);
+ strcat(FileName, OemFileName);
+ OemFileHandle = FsOpenFile(FileName);
+
+ if (OemFileHandle == NULL)
+ goto Failure;
+
+ Status = FsReadFile(OemFileHandle, OemFileSize, NULL,
VaToPa(LoaderBlock->NlsData->OemCodePageData));
+
+ if (!Status)
+ goto Failure;
+
+ FsCloseFile(AnsiFileHandle);
+ }
+
+ /* finally the language file */
+ strcpy(FileName, DirectoryPath);
+ strcat(FileName, LanguageFileName);
+ LanguageFileHandle = FsOpenFile(FileName);
+
+ if (LanguageFileHandle == NULL)
+ goto Failure;
+
+ Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL,
VaToPa(LoaderBlock->NlsData->UnicodeCodePageData));
+
+ if (!Status)
+ goto Failure;
+
+ FsCloseFile(LanguageFileHandle);
+
+ //
+ // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
+ // Should go to WinLdrLoadOemHalFont(), when it will be implemented
+ //
+ LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);
+
+ /* Convert NlsTables address to VA */
+ LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);
+
+ return TRUE;
+
+Failure:
+ //UiMessageBox("Error reading NLS file %s\n", Filename);
+ UiMessageBox("Error reading NLS file!");
+ return FALSE;
+}
+
+BOOLEAN
+WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN LPCSTR DirectoryPath,
+ IN LPCSTR HiveName)
+{
+ PFILE FileHandle;
+ CHAR FullHiveName[256];
+ BOOLEAN Status;
+ ULONG HiveFileSize;
+ ULONG_PTR HiveDataPhysical;
+ PVOID HiveDataVirtual;
+
+ /* Concatenate path and filename to get the full name */
+ strcpy(FullHiveName, DirectoryPath);
+ strcat(FullHiveName, HiveName);
+ //Print(L"Loading %s...\n", FullHiveName);
+ FileHandle = FsOpenFile(FullHiveName);
+
+ if (FileHandle == NULL)
+ {
+ UiMessageBox("Opening hive file failed!");
+ return FALSE;
+ }
+
+ /* Get the file length */
+ HiveFileSize = FsGetFileSize(FileHandle);
+
+ if (HiveFileSize == 0)
+ {
+ FsCloseFile(FileHandle);
+ UiMessageBox("Hive file has 0 size!");
+ return FALSE;
+ }
+
+ /* Round up the size to page boundary and alloc memory */
+ HiveDataPhysical = (ULONG_PTR)MmAllocateMemory(
+ MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT);
+
+ if (HiveDataPhysical == 0)
+ {
+ FsCloseFile(FileHandle);
+ UiMessageBox("Unable to alloc memory for a hive!");
+ return FALSE;
+ }
+
+ /* Convert address to virtual */
+ HiveDataVirtual = (PVOID)(KSEG0_BASE | HiveDataPhysical);
+
+ /* Fill LoaderBlock's entries */
+ LoaderBlock->RegistryLength = HiveFileSize;
+ LoaderBlock->RegistryBase = HiveDataVirtual;
+
+ /* Finally read from file to the memory */
+ Status = FsReadFile(FileHandle, HiveFileSize, NULL, (PVOID)HiveDataPhysical);
+ FsCloseFile(FileHandle);
+ if (!Status)
+ {
+ UiMessageBox("Unable to read from hive file!");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
+ PCONFIGURATION_COMPONENT Component;
+ PCONFIGURATION_COMPONENT_DATA /*CurrentEntry,*/ PreviousEntry, AdapterEntry;
+ BOOLEAN IsNextEntryChild;
+
+ DbgPrint((DPRINT_WINDOWS, "InitializeHWConfig()\n"));
+
+ LoaderBlock->ConfigurationRoot =
MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA));
+ RtlZeroMemory(LoaderBlock->ConfigurationRoot, sizeof(CONFIGURATION_COMPONENT_DATA));
+
+ /* Fill root == SystemClass */
+ ConfigurationRoot = LoaderBlock->ConfigurationRoot;
+ Component = &LoaderBlock->ConfigurationRoot->ComponentEntry;
+
+ Component->Class = SystemClass;
+ Component->Type = MaximumType;
+ Component->Version = 0; // FIXME: ?
+ Component->Key = 0;
+ Component->AffinityMask = 0;
+
+ IsNextEntryChild = TRUE;
+ PreviousEntry = ConfigurationRoot;
+
+ /* Enumerate all PCI buses */
+ AdapterEntry = ConfigurationRoot;
+
+ /* TODO: Disk Geometry */
+ /* TODO: Keyboard */
+
+ /* TODO: Serial port */
+
+ //Config->ConfigurationData = alloc(sizeof(CONFIGURATION_COMPONENT_DATA),
EfiLoaderData);
+
+ /* Convert everything to VA */
+ ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
+ LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
+}
+
+
+// Init "phase 0"
+VOID
+AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
+{
+ PLOADER_PARAMETER_BLOCK LoaderBlock;
+
+ /* Allocate and zero-init the LPB */
+ LoaderBlock = MmAllocateMemory(sizeof(LOADER_PARAMETER_BLOCK));
+ RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+
+ /* Init three critical lists, used right away */
+ InitializeListHead(&LoaderBlock->LoadOrderListHead);
+ InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
+ InitializeListHead(&LoaderBlock->BootDriverListHead);
+
+
+ *OutLoaderBlock = LoaderBlock;
+}
+
+// Init "phase 1"
+VOID
+WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ //CHAR Options[] = "/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200";
+ CHAR Options[] = "/NODEBUG";
+ CHAR SystemRoot[] = "\\WINNT";
+ CHAR HalPath[] = "\\";
+ CHAR ArcBoot[] = "multi(0)";
+ CHAR ArcHal[] = "multi(0)";
+
+ PLOADER_PARAMETER_EXTENSION Extension;
+
+ LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
+
+ /* Fill Arc BootDevice */
+ LoaderBlock->ArcBootDeviceName = MmAllocateMemory(strlen(ArcBoot)+1);
+ strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);
+ LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
+
+ /* Fill Arc HalDevice */
+ LoaderBlock->ArcHalDeviceName = MmAllocateMemory(strlen(ArcHal)+1);
+ strcpy(LoaderBlock->ArcHalDeviceName, ArcHal);
+ LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);
+
+ /* Fill SystemRoot */
+ LoaderBlock->NtBootPathName = MmAllocateMemory(strlen(SystemRoot)+1);
+ strcpy(LoaderBlock->NtBootPathName, SystemRoot);
+ LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
+
+ /* Fill NtHalPathName */
+ LoaderBlock->NtHalPathName = MmAllocateMemory(strlen(HalPath)+1);
+ strcpy(LoaderBlock->NtHalPathName, HalPath);
+ LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
+
+ /* Fill load options */
+ LoaderBlock->LoadOptions = MmAllocateMemory(strlen(Options)+1);
+ strcpy(LoaderBlock->LoadOptions, Options);
+ LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
+
+ /* Arc devices */
+ LoaderBlock->ArcDiskInformation =
(PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION));
+ InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
+ 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);
+
+ /* Convert all DTE into virtual addresses */
+ //TODO: !!!
+
+ /* Convert all list's to Virtual address */
+ List_PaToVa(&LoaderBlock->LoadOrderListHead);
+
+ /* this one will be converted right before switching to
+ virtual paging mode */
+ //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
+
+ List_PaToVa(&LoaderBlock->BootDriverListHead);
+
+ /* Initialize Extension now */
+ Extension = MmAllocateMemory(sizeof(LOADER_PARAMETER_EXTENSION));
+ if (Extension == NULL)
+ {
+ UiMessageBox("Failed to allocate LPB Extension!");
+ return;
+ }
+ RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION));
+
+ Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
+ Extension->MajorVersion = 4;
+ Extension->MinorVersion = 0;
+
+
+ LoaderBlock->Extension = PaToVa(Extension);
+}
+
+// Last step before going virtual
+void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
+ PVOID *GdtIdt,
+ ULONG *PcrBasePage,
+ ULONG *TssBasePage)
+{
+ ULONG TssSize;
+ ULONG TssPages;
+ ULONG_PTR Pcr = 0;
+ ULONG_PTR Tss = 0;
+ ULONG BlockSize, NumPages;
+
+ LoaderBlock->u.I386.CommonDataArea = NULL;//CommonDataArea;
+ //LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType?
+
+ /* Allocate 2 pages for PCR */
+ Pcr = (ULONG_PTR)MmAllocateMemory(2 * MM_PAGE_SIZE);
+ *PcrBasePage = Pcr >> MM_PAGE_SHIFT;
+
+ if (Pcr == 0)
+ {
+ UiMessageBox("Can't allocate PCR\n");
+ return;
+ }
+
+ /* Allocate TSS */
+ TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
+ TssPages = TssSize / MM_PAGE_SIZE;
+
+ Tss = (ULONG_PTR)MmAllocateMemory(TssSize);
+
+ *TssBasePage = Tss >> MM_PAGE_SHIFT;
+
+ /* Allocate space for new GDT + IDT */
+ BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT
limits here?
+ NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
+ *GdtIdt = (PKGDTENTRY)MmAllocateMemory(NumPages * MM_PAGE_SIZE);
+
+ if (*GdtIdt == NULL)
+ {
+ UiMessageBox("Can't allocate pages for GDT+IDT!\n");
+ return;
+ }
+
+ /* Zero newly prepared GDT+IDT */
+ RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT);
+}
+
+
VOID
LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
{
@@ -96,7 +512,7 @@
DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath));
/* Allocate and minimalistic-initialize LPB */
- //AllocateAndInitLPB(&LoaderBlock);
+ AllocateAndInitLPB(&LoaderBlock);
// Load kernel
strcpy(FileName, BootPath);
@@ -122,19 +538,19 @@
WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE);
/* Initialize Phase 1 - before NLS */
- //WinLdrInitializePhase1(LoaderBlock);
+ WinLdrInitializePhase1(LoaderBlock);
/* Load SYSTEM hive and its LOG file */
strcpy(SearchPath, BootPath);
strcat(SearchPath, "SYSTEM32\\CONFIG\\");
- //Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM");
+ Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM");
DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status));
/* Load NLS data */
strcpy(SearchPath, BootPath);
strcat(SearchPath, "SYSTEM32\\");
- //Status = WinLdrLoadNLSData(LoaderBlock, SearchPath,
- // "c_1252.nls", "c_437.nls", "l_intl.nls");
+ Status = WinLdrLoadNLSData(LoaderBlock, SearchPath,
+ "c_1252.nls", "c_437.nls", "l_intl.nls");
DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status));
/* Load OEM HAL font */
@@ -142,7 +558,7 @@
/* Load boot drivers */
/* Alloc PCR, TSS, do magic things with the GDT/IDT */
- //WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
+ WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
/* Save entry-point pointer (VA) */
KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;