[ros-diffs] [fireball] 24354: - 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()

fireball at svn.reactos.org fireball at svn.reactos.org
Sun Oct 1 23:15:16 CEST 2006


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/windows/winldr.c?rev=24354&r1=24353&r2=24354&view=diff
==============================================================================
--- 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;




More information about the Ros-diffs mailing list