From 9177998d8ef610e4467fccedc6f371f12e85cf92 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 4 Dec 2006 22:08:02 +0000 Subject: [PATCH] Commit my initial work on getting Windows NT booting. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Right now, if stars on the sky get in proper places and you are lucky, it will load Windows NT 4.0 to GUI (it will be unusable due to absence of mouse/keyboard though). Here are log messages from my local tree which I used to develop this initial version (just for reference): Revision: 8 Author: alekseyb Date: 22:56:15, 24 íîÿáðÿ 2006 ã. Message: - Initialize "ValidBootPartition" field of ArcDiskInfo (without it Windows thinks the partition is not good) - Zero ArcDiskInfo before usage - Load filesystem driver (fastfat.sys for now) Windows NT4 now boots, but of course there are no mouse/keyboard. ---- Modified : /freeldr/arch/i386/hardware.c Modified : /freeldr/windows/winldr.c Modified : /freeldr/windows/wlregistry.c Revision: 7 Author: alekseyb Date: 15:37:37, 24 íîÿáðÿ 2006 ã. Message: - Fix Disk Peripheral entries to really be of DiskPeripheral type and PeripheralClass - Add to PcHwDetect() proper Child/Sibling-isation (depending on what has been found) - Fixed PCI information recognizing (changed structure + properly filling HardwareMechanism field) - Creating of actual configuration descriptor for PCI bus added - Fix conversion of hardware configuration list to virtual addressing, also adding better debug prints - Remove annoying DbgPrints from PE loader - Remove memory map dumping ---- Modified : /freeldr/arch/i386/hardware.c Modified : /freeldr/arch/i386/hwpci.c Modified : /freeldr/include/arch/i386/hardware.h Modified : /freeldr/windows/conversion.c Modified : /freeldr/windows/peloader.c Modified : /freeldr/windows/winldr.c Revision: 6 Author: alekseyb Date: 1:42:20, 23 íîÿáðÿ 2006 ã. Message: - Add ISA bus configuration entry, Disk Controller and Peripherals - Comment about number of GDT entries - Changed order of boot drivers - now they should correspond to what NT awaits The compatibility with ReactOS booting is broken at this point, because hardware detection results are being placed into configuration list and not in-memory registry. ---- Modified : /freeldr/arch/i386/hardware.c Modified : /freeldr/include/winldr.h Modified : /freeldr/windows/wlregistry.c Revision: 5 Author: alekseyb Date: 23:37:40, 18 íîÿáðÿ 2006 ã. Message: - Modify number of GDT descriptors, since NT Kernel assumes space for 128 GDT descriptors, and if it is less - it overwrites IDT entries following them, which lead to a major fsckup, and how kernel booted to some stage is a mystery. - Slightly modified comments, removed unnecessary TODO WinDBG connects now and seems to work (don't forget to disable debug output of freeldr, otherwise WinDBG can't connect). ---- Modified : /freeldr/include/winldr.h Modified : /freeldr/windows/winldr.c Revision: 4 Author: alekseyb Date: 18:25:49, 16 íîÿáðÿ 2006 ã. Message: - Fix RegistryPath in boot drivers (appended service name) - Convert RegistryPath.Buffer and pointer to DTE to VirtualAddresses (fixes KMODE_EXCEPTION) ---- Modified : /freeldr/windows/winldr.c Modified : /freeldr/windows/wlregistry.c Revision: 3 Author: alekseyb Date: 17:10:21, 15 íîÿáðÿ 2006 ã. Message: - Implemented storing configuration data of disks. - Moved hardware detection to a later stage so that it doesn't write to an unitialized pointer and actually stores the data in LoaderBlock->ConfigurationRoot. InitializeHWConfig() function should go away soon. ---- Modified : /freeldr/arch/i386/hardware.c Modified : /freeldr/windows/conversion.c Modified : /freeldr/windows/winldr.c Revision: 2 Author: alekseyb Date: 16:54:12, 13 íîÿáðÿ 2006 ã. Message: Import of what has been already done so far by me (WinNT 4.0 says INACCESSIBLE_BOOT_DEVICE). Just started working on Configuration List. ---- Modified : /freeldr/arch/i386/hardware.c Modified : /freeldr/arch/i386/i386idt.S Modified : /freeldr/arch/i386/i386trap.S Modified : /freeldr/arch/i386/xboxhw.c Modified : /freeldr/debug.c Modified : /freeldr/freeldr_arch.rbuild Modified : /freeldr/freeldr_base.rbuild Modified : /freeldr/freeldr_base64k.rbuild Modified : /freeldr/freeldr_main.rbuild Modified : /freeldr/include/arch/i386/machpc.h Modified : /freeldr/include/arch/i386/machxbox.h Modified : /freeldr/include/machine.h Modified : /freeldr/include/mm.h Modified : /freeldr/include/winldr.h Modified : /freeldr/linuxboot.c Modified : /freeldr/machine.c Modified : /freeldr/mm/meminit.c Modified : /freeldr/mm/mm.c Modified : /freeldr/reactos/binhive.c Modified : /freeldr/reactos/reactos.c Modified : /freeldr/reactos/setupldr.c Modified : /freeldr/windows/peloader.c Modified : /freeldr/windows/winldr.c Modified : /freeldr/windows/wlmemory.c Modified : /freeldr/windows/wlregistry.c Revision: 1 Author: alekseyb Date: 16:45:55, 13 íîÿáðÿ 2006 ã. Message: FreeLdr import from ReactOS trunk r24725 ---- Added : /freeldr Added : /freeldr/CHANGELOG Added : /freeldr/arch Added : /freeldr/arch/i386 Added : /freeldr/arch/i386/_alloca.S Added : /freeldr/arch/i386/arch.S Added : /freeldr/arch/i386/archmach.c Added : /freeldr/arch/i386/boot.S Added : /freeldr/arch/i386/drvmap.S Added : /freeldr/arch/i386/fathelp.asm Added : /freeldr/arch/i386/hardware.c Added : /freeldr/arch/i386/hwacpi.c Added : /freeldr/arch/i386/hwapm.c Added : /freeldr/arch/i386/hwcpu.c Added : /freeldr/arch/i386/hwpci.c Added : /freeldr/arch/i386/i386cpu.S Added : /freeldr/arch/i386/i386disk.c Added : /freeldr/arch/i386/i386idt.S Added : /freeldr/arch/i386/i386pnp.S Added : /freeldr/arch/i386/i386rtl.c Added : /freeldr/arch/i386/i386trap.S Added : /freeldr/arch/i386/i386vid.c Added : /freeldr/arch/i386/int386.S Added : /freeldr/arch/i386/linux.S Added : /freeldr/arch/i386/loader.c Added : /freeldr/arch/i386/machpc.c Added : /freeldr/arch/i386/machxbox.c Added : /freeldr/arch/i386/mb.S Added : /freeldr/arch/i386/pccons.c Added : /freeldr/arch/i386/pcdisk.c Added : /freeldr/arch/i386/pcmem.c Added : /freeldr/arch/i386/pcrtc.c Added : /freeldr/arch/i386/pcvideo.c Added : /freeldr/arch/i386/portio.c Added : /freeldr/arch/i386/xboxcons.c Added : /freeldr/arch/i386/xboxdisk.c Added : /freeldr/arch/i386/xboxfont.c Added : /freeldr/arch/i386/xboxhw.c Added : /freeldr/arch/i386/xboxi2c.c Added : /freeldr/arch/i386/xboxmem.c Added : /freeldr/arch/i386/xboxrtc.c Added : /freeldr/arch/i386/xboxvideo.c Added : /freeldr/arch/powerpc Added : /freeldr/arch/powerpc/boot.s Added : /freeldr/arch/powerpc/mach.c Added : /freeldr/arch/powerpc/mboot.c Added : /freeldr/bootmgr.c Added : /freeldr/cache Added : /freeldr/cache/blocklist.c Added : /freeldr/cache/cache.c Added : /freeldr/cmdline.c Added : /freeldr/comm Added : /freeldr/comm/rs232.c Added : /freeldr/custom.c Added : /freeldr/debug.c Added : /freeldr/disk Added : /freeldr/disk/disk.c Added : /freeldr/disk/partition.c Added : /freeldr/drivemap.c Added : /freeldr/freeldr.c Added : /freeldr/freeldr.rbuild Added : /freeldr/freeldr_arch.rbuild Added : /freeldr/freeldr_base.rbuild Added : /freeldr/freeldr_base64k.rbuild Added : /freeldr/freeldr_main.rbuild Added : /freeldr/freeldr_startup.rbuild Added : /freeldr/fs Added : /freeldr/fs/ext2.c Added : /freeldr/fs/fat.c Added : /freeldr/fs/fs.c Added : /freeldr/fs/fsrec.c Added : /freeldr/fs/iso.c Added : /freeldr/fs/ntfs.c Added : /freeldr/include Added : /freeldr/include/arch Added : /freeldr/include/arch/i386 Added : /freeldr/include/arch/i386/hardware.h Added : /freeldr/include/arch/i386/i386.h Added : /freeldr/include/arch/i386/machpc.h Added : /freeldr/include/arch/i386/machxbox.h Added : /freeldr/include/arch.h Added : /freeldr/include/bootmgr.h Added : /freeldr/include/cache.h Added : /freeldr/include/cmdline.h Added : /freeldr/include/comm.h Added : /freeldr/include/debug.h Added : /freeldr/include/disk.h Added : /freeldr/include/drivemap.h Added : /freeldr/include/freeldr.h Added : /freeldr/include/fs Added : /freeldr/include/fs/ext2.h Added : /freeldr/include/fs/fat.h Added : /freeldr/include/fs/iso.h Added : /freeldr/include/fs/ntfs.h Added : /freeldr/include/fs.h Added : /freeldr/include/fsrec.h Added : /freeldr/include/inffile.h Added : /freeldr/include/inifile.h Added : /freeldr/include/keycodes.h Added : /freeldr/include/linux.h Added : /freeldr/include/machine.h Added : /freeldr/include/miscboot.h Added : /freeldr/include/mm.h Added : /freeldr/include/multiboot.h Added : /freeldr/include/of.h Added : /freeldr/include/options.h Added : /freeldr/include/oslist.h Added : /freeldr/include/portio.h Added : /freeldr/include/reactos.h Added : /freeldr/include/registry.h Added : /freeldr/include/rtl.h Added : /freeldr/include/ui Added : /freeldr/include/ui/gui.h Added : /freeldr/include/ui/tui.h Added : /freeldr/include/ui.h Added : /freeldr/include/ver.h Added : /freeldr/include/video.h Added : /freeldr/include/winldr.h Added : /freeldr/inffile Added : /freeldr/inffile/inffile.c Added : /freeldr/inifile Added : /freeldr/inifile/ini_init.c Added : /freeldr/inifile/inifile.c Added : /freeldr/inifile/parse.c Added : /freeldr/linuxboot.c Added : /freeldr/machine.c Added : /freeldr/math Added : /freeldr/math/i386.h Added : /freeldr/math/libgcc2.c Added : /freeldr/math/libgcc2.h Added : /freeldr/math/longlong.h Added : /freeldr/math/powerpc.h Added : /freeldr/miscboot.c Added : /freeldr/mm Added : /freeldr/mm/meminit.c Added : /freeldr/mm/mm.c Added : /freeldr/options.c Added : /freeldr/oslist.c Added : /freeldr/reactos Added : /freeldr/reactos/arcname.c Added : /freeldr/reactos/binhive.c Added : /freeldr/reactos/reactos.c Added : /freeldr/reactos/registry.c Added : /freeldr/reactos/setupldr.c Added : /freeldr/rtl Added : /freeldr/rtl/libsupp.c Added : /freeldr/rtl/list.c Added : /freeldr/setupldr.rbuild Added : /freeldr/setupldr_main.rbuild Added : /freeldr/ui Added : /freeldr/ui/gui.c Added : /freeldr/ui/tui.c Added : /freeldr/ui/tuimenu.c Added : /freeldr/ui/ui.c Added : /freeldr/version.c Added : /freeldr/video Added : /freeldr/video/bank.c Added : /freeldr/video/fade.c Added : /freeldr/video/palette.c Added : /freeldr/video/pixel.c Added : /freeldr/video/video.c Added : /freeldr/windows Added : /freeldr/windows/conversion.c Added : /freeldr/windows/peloader.c Added : /freeldr/windows/winldr.c Added : /freeldr/windows/wlmemory.c Added : /freeldr/windows/wlregistry.c svn path=/branches/winldr/; revision=25067 --- arch/i386/hardware.c | 837 +++++++++++++++++++---------------- arch/i386/hwpci.c | 299 +++++++------ arch/i386/i386idt.S | 72 +-- arch/i386/i386trap.S | 36 +- arch/i386/xboxhw.c | 2 +- freeldr_arch.rbuild | 6 +- freeldr_base.rbuild | 4 +- freeldr_base64k.rbuild | 1 + freeldr_main.rbuild | 5 +- include/arch/i386/hardware.h | 6 +- include/arch/i386/machpc.h | 2 +- include/arch/i386/machxbox.h | 2 +- include/machine.h | 6 +- include/mm.h | 7 +- include/winldr.h | 5 +- linuxboot.c | 6 +- machine.c | 4 +- mm/meminit.c | 74 +++- mm/mm.c | 21 +- reactos/binhive.c | 1 + reactos/reactos.c | 3 +- reactos/setupldr.c | 3 +- windows/conversion.c | 11 +- windows/peloader.c | 544 ++++++++++++++++++++++- windows/winldr.c | 107 +++-- windows/wlmemory.c | 199 +++------ windows/wlregistry.c | 29 +- 27 files changed, 1484 insertions(+), 808 deletions(-) diff --git a/arch/i386/hardware.c b/arch/i386/hardware.c index a7c8a894abb..87d8c653e73 100644 --- a/arch/i386/hardware.c +++ b/arch/i386/hardware.c @@ -2,6 +2,7 @@ * FreeLoader * * Copyright (C) 2003, 2004 Eric Kohl + * Copyright (C) 2006 Aleksey Bragin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +24,10 @@ #define NDEBUG #include +/* Parts of hardware detection specific to ReactOS */ +/* They should go away once kernel is able to use configuration lists */ +#define ROS_SPECIFIC 1 + #define MILLISEC (10) #define PRECISION (8) @@ -117,7 +122,7 @@ typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK } __attribute__((packed)) CM_PNP_BIOS_INSTALLATION_CHECK, *PCM_PNP_BIOS_INSTALLATION_CHECK; -static WCHAR Hex[] = L"0123456789ABCDEF"; +static CHAR Hex[] = "0123456789abcdef"; static unsigned int delay_count = 1; extern ULONG reactos_disk_count; @@ -423,90 +428,45 @@ DetectPnpBios(FRLDRHKEY SystemKey, ULONG *BusNumber) static VOID -SetHarddiskConfigurationData(FRLDRHKEY DiskKey, +SetHarddiskConfigurationData(PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry, ULONG DriveNumber) { - PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; - PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; - EXTENDED_GEOMETRY ExtGeometry; - GEOMETRY Geometry; - ULONG Size; - LONG Error; + EXTENDED_GEOMETRY ExtGeometry; + GEOMETRY Geometry; - /* Set 'Configuration Data' value */ - Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + - sizeof(CM_DISK_GEOMETRY_DEVICE_DATA); - FullResourceDescriptor = MmAllocateMemory(Size); - if (FullResourceDescriptor == NULL) - { - DbgPrint((DPRINT_HWDETECT, - "Failed to allocate a full resource descriptor\n")); - return; - } - - memset(FullResourceDescriptor, 0, Size); - FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined; - FullResourceDescriptor->BusNumber = 0; - FullResourceDescriptor->PartialResourceList.Version = 1; - FullResourceDescriptor->PartialResourceList.Revision = 1; - FullResourceDescriptor->PartialResourceList.Count = 1; - FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = - CmResourceTypeDeviceSpecific; -// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition = -// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags = - FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize = - sizeof(CM_DISK_GEOMETRY_DEVICE_DATA); - - /* Get pointer to geometry data */ - DiskGeometry = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR)); - - /* Get the disk geometry */ - ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY); - if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size)) - { - DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector; - DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders; - DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack; - DiskGeometry->NumberOfHeads = ExtGeometry.Heads; - } - else if(MachDiskGetDriveGeometry(DriveNumber, &Geometry)) - { - DiskGeometry->BytesPerSector = Geometry.BytesPerSector; - DiskGeometry->NumberOfCylinders = Geometry.Cylinders; - DiskGeometry->SectorsPerTrack = Geometry.Sectors; - DiskGeometry->NumberOfHeads = Geometry.Heads; - } - else - { - DbgPrint((DPRINT_HWDETECT, "Reading disk geometry failed\n")); - MmFreeMemory(FullResourceDescriptor); - return; - } - DbgPrint((DPRINT_HWDETECT, - "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n", - DriveNumber, - DiskGeometry->NumberOfCylinders, - DiskGeometry->NumberOfHeads, - DiskGeometry->SectorsPerTrack, - DiskGeometry->BytesPerSector)); - - Error = RegSetValue(DiskKey, - L"Configuration Data", - REG_FULL_RESOURCE_DESCRIPTOR, - (PCHAR) FullResourceDescriptor, - Size); - MmFreeMemory(FullResourceDescriptor); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, - "RegSetValue(Configuration Data) failed (Error %u)\n", - (int)Error)); - } + /* Get the disk geometry */ + ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY); + if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size)) + { + DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector; + DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders; + DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack; + DiskGeometry->NumberOfHeads = ExtGeometry.Heads; + } + else if(MachDiskGetDriveGeometry(DriveNumber, &Geometry)) + { + DiskGeometry->BytesPerSector = Geometry.BytesPerSector; + DiskGeometry->NumberOfCylinders = Geometry.Cylinders; + DiskGeometry->SectorsPerTrack = Geometry.Sectors; + DiskGeometry->NumberOfHeads = Geometry.Heads; + } + else + { + DbgPrint((DPRINT_HWDETECT, "Reading disk geometry failed\n")); + return; + } + DbgPrint((DPRINT_HWDETECT, + "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n", + DriveNumber, + DiskGeometry->NumberOfCylinders, + DiskGeometry->NumberOfHeads, + DiskGeometry->SectorsPerTrack, + DiskGeometry->BytesPerSector)); } static VOID -SetHarddiskIdentifier(FRLDRHKEY DiskKey, +SetHarddiskIdentifier(PCHAR Identifier, ULONG DriveNumber) { PMASTER_BOOT_RECORD Mbr; @@ -514,9 +474,7 @@ SetHarddiskIdentifier(FRLDRHKEY DiskKey, ULONG i; ULONG Checksum; ULONG Signature; - WCHAR Identifier[20]; CHAR ArcName[256]; - LONG Error; /* Read the MBR */ if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER)) @@ -547,6 +505,7 @@ SetHarddiskIdentifier(FRLDRHKEY DiskKey, strcpy(reactos_arc_strings[reactos_disk_count], ArcName); reactos_arc_disk_info[reactos_disk_count].ArcName = reactos_arc_strings[reactos_disk_count]; + reactos_arc_disk_info[reactos_disk_count].ValidPartitionTable = TRUE; reactos_disk_count++; /* Convert checksum and signature to identifier string */ @@ -570,152 +529,252 @@ SetHarddiskIdentifier(FRLDRHKEY DiskKey, Identifier[17] = L'-'; Identifier[18] = L'A'; Identifier[19] = 0; - DbgPrint((DPRINT_HWDETECT, "Identifier: %S\n", Identifier)); - - /* Set identifier */ - Error = RegSetValue(DiskKey, - L"Identifier", - REG_SZ, - (PCHAR)Identifier, - sizeof(Identifier)); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, - "RegSetValue(Identifier) failed (Error %u)\n", - (int)Error)); - } + DbgPrint((DPRINT_HWDETECT, "Identifier: %s\n", Identifier)); } -static VOID +static PCONFIGURATION_COMPONENT_DATA DetectBiosDisks(FRLDRHKEY SystemKey, - FRLDRHKEY BusKey) + FRLDRHKEY BusKey, + PCONFIGURATION_COMPONENT_DATA ComponentRoot, + PCONFIGURATION_COMPONENT_DATA PreviousComponent, + BOOLEAN NextChild) { - PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; - PCM_INT13_DRIVE_PARAMETER Int13Drives; - GEOMETRY Geometry; - WCHAR Buffer[80]; - FRLDRHKEY DiskKey; - ULONG DiskCount; - ULONG Size; - ULONG i; - LONG Error; - BOOLEAN Changed; + PCM_INT13_DRIVE_PARAMETER Int13Drives; + PCM_PARTIAL_RESOURCE_LIST ResourceList; + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; + PCONFIGURATION_COMPONENT_DATA DiskComponentData, DiskPrevious; + PCONFIGURATION_COMPONENT DiskComponent; + BOOLEAN DisksNextChild; + PVOID ConfigurationData; + USHORT ConfigurationDataLength; + PVOID DeviceData; + USHORT DeviceDataSize; + GEOMETRY Geometry; + ULONG DiskCount; + ULONG Size; + ULONG i; + BOOLEAN Changed; - /* Count the number of visible drives */ - DiskReportError(FALSE); - DiskCount = 0; + /* Count the number of visible drives */ + DiskReportError(FALSE); + DiskCount = 0; - /* There are some really broken BIOSes out there. There are even BIOSes - * that happily report success when you ask them to read from non-existent - * harddisks. So, we set the buffer to known contents first, then try to - * read. If the BIOS reports success but the buffer contents haven't - * changed then we fail anyway */ - memset((PVOID) DISKREADBUFFER, 0xcd, 512); - while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER)) - { - Changed = FALSE; - for (i = 0; ! Changed && i < 512; i++) - { - Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd; - } - if (! Changed) - { - DbgPrint((DPRINT_HWDETECT, "BIOS reports success for disk %d but data didn't change\n", - (int)DiskCount)); - break; - } - DiskCount++; - memset((PVOID) DISKREADBUFFER, 0xcd, 512); - } - DiskReportError(TRUE); - DbgPrint((DPRINT_HWDETECT, "BIOS reports %d harddisk%s\n", - (int)DiskCount, (DiskCount == 1) ? "": "s")); - - /* Allocate resource descriptor */ - Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + - sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount; - FullResourceDescriptor = MmAllocateMemory(Size); - if (FullResourceDescriptor == NULL) - { - DbgPrint((DPRINT_HWDETECT, - "Failed to allocate resource descriptor\n")); - return; - } - - /* Initialize resource descriptor */ - memset(FullResourceDescriptor, 0, Size); - FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined; - FullResourceDescriptor->BusNumber = -1; - FullResourceDescriptor->PartialResourceList.Version = 1; - FullResourceDescriptor->PartialResourceList.Revision = 1; - FullResourceDescriptor->PartialResourceList.Count = 1; - FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = - CmResourceTypeDeviceSpecific; -// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition = -// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags = - FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize = - sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount; - - /* Get harddisk Int13 geometry data */ - Int13Drives = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR)); - for (i = 0; i < DiskCount; i++) - { - if (MachDiskGetDriveGeometry(0x80 + i, &Geometry)) + /* There are some really broken BIOSes out there. There are even BIOSes + * that happily report success when you ask them to read from non-existent + * harddisks. So, we set the buffer to known contents first, then try to + * read. If the BIOS reports success but the buffer contents haven't + * changed then we fail anyway */ + memset((PVOID) DISKREADBUFFER, 0xcd, 512); + while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER)) { - Int13Drives[i].DriveSelect = 0x80 + i; - Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1; - Int13Drives[i].SectorsPerTrack = Geometry.Sectors; - Int13Drives[i].MaxHeads = Geometry.Heads - 1; - Int13Drives[i].NumberDrives = DiskCount; - - DbgPrint((DPRINT_HWDETECT, - "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n", - 0x80 + i, - Geometry.Cylinders - 1, - Geometry.Heads -1, - Geometry.Sectors, - Geometry.BytesPerSector)); + Changed = FALSE; + for (i = 0; ! Changed && i < 512; i++) + { + Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd; + } + if (! Changed) + { + DbgPrint((DPRINT_HWDETECT, "BIOS reports success for disk %d but data didn't change\n", + (int)DiskCount)); + break; + } + DiskCount++; + memset((PVOID) DISKREADBUFFER, 0xcd, 512); } - } + DiskReportError(TRUE); + DbgPrint((DPRINT_HWDETECT, "BIOS reports %d harddisk%s\n", + (int)DiskCount, (DiskCount == 1) ? "": "s")); - /* Set 'Configuration Data' value */ - Error = RegSetValue(SystemKey, - L"Configuration Data", - REG_FULL_RESOURCE_DESCRIPTOR, - (PCHAR) FullResourceDescriptor, - Size); - MmFreeMemory(FullResourceDescriptor); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, - "RegSetValue(Configuration Data) failed (Error %u)\n", - (int)Error)); - return; - } + /* Create DiskController */ + DiskComponentData = (PCONFIGURATION_COMPONENT_DATA)MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + RtlZeroMemory(DiskComponentData, sizeof(CONFIGURATION_COMPONENT_DATA)); - /* Create and fill subkey for each harddisk */ - for (i = 0; i < DiskCount; i++) - { - /* Create disk key */ - swprintf (Buffer, - L"DiskController\\0\\DiskPeripheral\\%u", - i); + DiskComponent = &DiskComponentData->ComponentEntry; + RtlZeroMemory(DiskComponent, sizeof(CONFIGURATION_COMPONENT)); - Error = RegCreateKey(BusKey, - Buffer, - &DiskKey); - if (Error != ERROR_SUCCESS) + DiskComponent->Class = ControllerClass; + DiskComponent->Type = DiskController; + DiskComponent->AffinityMask = 0xFFFFFFFF; + DiskComponent->Flags = 64; // Taken from Windows XP registry + + /* Fill DiskController resources descriptor, which consists of: + Partial Resource List + 3 Partial Resource Descriptors (Dma, Irq and Port) */ + DiskComponentData->ConfigurationData = MmAllocateMemory(sizeof(CM_PARTIAL_RESOURCE_LIST) + + 2*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + RtlZeroMemory(DiskComponentData->ConfigurationData, sizeof(CM_PARTIAL_RESOURCE_LIST) + + 2*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + ResourceList = (PCM_PARTIAL_RESOURCE_LIST)DiskComponentData->ConfigurationData; + ResourceList->Count = 3; // DMA + Interrupt + Port + + /* DMA */ + ResourceList->PartialDescriptors[0].Type = CmResourceTypeDma; + ResourceList->PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined; + ResourceList->PartialDescriptors[0].u.Dma.Channel = 2; // default channel is 2, at least on WinXP + + /* Interrupt */ + ResourceList->PartialDescriptors[1].Type = CmResourceTypeInterrupt; + ResourceList->PartialDescriptors[1].ShareDisposition = CmResourceShareUndetermined; + ResourceList->PartialDescriptors[1].Flags = CM_RESOURCE_INTERRUPT_LATCHED; + ResourceList->PartialDescriptors[1].u.Interrupt.Level = 6; + ResourceList->PartialDescriptors[1].u.Interrupt.Vector = 6; + ResourceList->PartialDescriptors[1].u.Interrupt.Affinity = 0xFFFFFFFF; + + /* Port */ + ResourceList->PartialDescriptors[2].Type = CmResourceTypePort; + ResourceList->PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive; + ResourceList->PartialDescriptors[2].Flags = CM_RESOURCE_PORT_IO; + ResourceList->PartialDescriptors[2].u.Port.Start.QuadPart = 0x3F0LL; + ResourceList->PartialDescriptors[2].u.Port.Length = 8; + + /* Add DiskController to the parent/sibling */ + if (NextChild) { - DbgPrint((DPRINT_HWDETECT, "Failed to create drive key\n")); - continue; + PreviousComponent->Child = DiskComponentData; + DiskComponentData->Parent = PreviousComponent; + } + else + { + PreviousComponent->Sibling = DiskComponentData; + DiskComponentData->Parent = PreviousComponent->Parent; } - DbgPrint((DPRINT_HWDETECT, "Created key: %S\n", Buffer)); - /* Set disk values */ - SetHarddiskConfigurationData(DiskKey, 0x80 + i); - SetHarddiskIdentifier(DiskKey, 0x80 + i); - } + /* Get harddisk Int13 geometry data */ + Int13Drives = MmAllocateMemory(sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount); + memset(Int13Drives, 0, sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount); + + for (i = 0; i < DiskCount; i++) + { + if (MachDiskGetDriveGeometry(0x80 + i, &Geometry)) + { + Int13Drives[i].DriveSelect = 0x80 + i; + Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1; + Int13Drives[i].SectorsPerTrack = Geometry.Sectors; + Int13Drives[i].MaxHeads = Geometry.Heads - 1; + Int13Drives[i].NumberDrives = DiskCount; + + DbgPrint((DPRINT_HWDETECT, + "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n", + 0x80 + i, + Geometry.Cylinders - 1, + Geometry.Heads -1, + Geometry.Sectors, + Geometry.BytesPerSector)); + } + } + + /* Add disks as childs of Disk Controller */ + DisksNextChild = TRUE; + DiskPrevious = DiskComponentData; + + for (i = 0; i < DiskCount; i++) + { + PCONFIGURATION_COMPONENT_DATA DiskPeripheralData; + PCONFIGURATION_COMPONENT DiskPeripheralEntry; + PVOID DeviceSpecific; + + /* Create DiskPeripheral */ + DiskPeripheralData = (PCONFIGURATION_COMPONENT_DATA)MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + RtlZeroMemory(DiskPeripheralData, sizeof(CONFIGURATION_COMPONENT_DATA)); + + DiskPeripheralEntry = &DiskPeripheralData->ComponentEntry; + RtlZeroMemory(DiskPeripheralEntry, sizeof(CONFIGURATION_COMPONENT)); + + DiskPeripheralEntry->Class = PeripheralClass; + DiskPeripheralEntry->Type = DiskPeripheral; + DiskPeripheralEntry->AffinityMask = 0xFFFFFFFF; + DiskPeripheralEntry->Key = i; + DiskPeripheralEntry->Flags = 60; // Taken from Windows XP registry + //DiskPeripheralEntry->Identifier + DiskPeripheralEntry->Identifier = MmAllocateMemory(40); + SetHarddiskIdentifier((PCHAR)DiskPeripheralEntry->Identifier, 0x80 + i); + DiskPeripheralEntry->IdentifierLength = strlen(DiskPeripheralEntry->Identifier); + DiskPeripheralEntry->Identifier = PaToVa(DiskPeripheralEntry->Identifier); + + /* Fill DiskPeripheral resources descriptor, which consists of: + Partial resource list + 1 resource descriptor having device data + in CM_DISK_GEOMETRY_DEVICE_DATA format */ + Size = sizeof(CM_PARTIAL_RESOURCE_LIST) + sizeof(CM_DISK_GEOMETRY_DEVICE_DATA); + DiskPeripheralData->ConfigurationData = MmAllocateMemory(Size); + RtlZeroMemory(DiskPeripheralData->ConfigurationData, Size); + ResourceList = (PCM_PARTIAL_RESOURCE_LIST)DiskPeripheralData->ConfigurationData; + ResourceList->Count = 1; + + /* Device specific data */ + ResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific; + ResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize = sizeof(CM_DISK_GEOMETRY_DEVICE_DATA); + + DeviceSpecific = (PVOID)((ULONG_PTR)DiskPeripheralData->ConfigurationData + sizeof(CM_PARTIAL_RESOURCE_LIST)); + + /* Set disk values */ + SetHarddiskConfigurationData((PCM_DISK_GEOMETRY_DEVICE_DATA)DeviceSpecific, 0x80 + i); + + /* Add DiskController to the parent/sibling */ + if (DisksNextChild) + { + DiskPrevious->Child = DiskPeripheralData; + DiskPeripheralData->Parent = DiskPrevious; + DisksNextChild = FALSE; // all other will be siblings + } + else + { + DiskPrevious->Sibling = DiskPeripheralData; + DiskPeripheralData->Parent = DiskPrevious->Parent; + } + + /* Store just created disk peripheral as previous entry */ + DiskPrevious = DiskPeripheralData; + } + + /* Create configuration data for disks */ + /* Size is 1 resource list containing 2 resource descriptors, each one containing its own device data */ + ConfigurationData = MmAllocateMemory(sizeof(CM_PARTIAL_RESOURCE_LIST) + + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + DiskCount*sizeof(CM_INT13_DRIVE_PARAMETER) + 0); + + DeviceDataSize = DiskCount*sizeof(CM_INT13_DRIVE_PARAMETER); + + /* Set up resource list*/ + ResourceList = (PCM_PARTIAL_RESOURCE_LIST)ConfigurationData; + ResourceList->Version = 0; + ResourceList->Revision = 0; + ResourceList->Count = 2; + ResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific; + ResourceList->PartialDescriptors[0].Flags = 0; + ResourceList->PartialDescriptors[0].ShareDisposition = 0; + ResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize = DeviceDataSize; + ResourceList->PartialDescriptors[0].u.DeviceSpecificData.Reserved1 = 0; + ResourceList->PartialDescriptors[0].u.DeviceSpecificData.Reserved2 = 0; + + /* Copy disk's device data */ + DeviceData = (PVOID)((ULONG_PTR)ResourceList + sizeof(CM_PARTIAL_RESOURCE_LIST)); + memcpy(DeviceData, (PVOID)Int13Drives, DeviceDataSize); + + MmFreeMemory(Int13Drives); + + /* Now fill the 2nd partial resource descriptor */ + ResourceDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)((ULONG_PTR)ResourceList + + sizeof(CM_PARTIAL_RESOURCE_LIST) + DeviceDataSize); + + /* We don't provide any info yet for the 2nd partial resource descriptor */ + DeviceDataSize = 0; + + ResourceDescriptor->Type = CmResourceTypeDeviceSpecific; + ResourceDescriptor->Flags = 0; + ResourceDescriptor->ShareDisposition = 0; + ResourceDescriptor->u.DeviceSpecificData.DataSize = DeviceDataSize; + ResourceDescriptor->u.DeviceSpecificData.Reserved1 = 0; + ResourceDescriptor->u.DeviceSpecificData.Reserved2 = 0; + + ConfigurationDataLength = sizeof(CM_PARTIAL_RESOURCE_LIST) + + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + DiskCount*sizeof(CM_INT13_DRIVE_PARAMETER) + 0; + + /* Store this information in SystemClass */ + ComponentRoot->ComponentEntry.ConfigurationDataLength = ConfigurationDataLength; + ComponentRoot->ConfigurationData = ConfigurationData; + + + /* Return pointer to the disk controller */ + return DiskComponentData; } @@ -1631,6 +1690,7 @@ DetectKeyboardDevice(VOID) if ((Status & 0x01) != 0x01) { /* PC/XT keyboard or no keyboard */ + DPRINT1("PC/XT keyboard or no keyboard found\n"); return FALSE; } @@ -1638,6 +1698,7 @@ DetectKeyboardDevice(VOID) if (Scancode != 0xFA) { /* No ACK received */ + DPRINT1("No ACK received\n"); return FALSE; } @@ -1653,6 +1714,7 @@ DetectKeyboardDevice(VOID) if (Scancode != 0xAB) { /* No 0xAB received */ + DPRINT1("No 0xAB received\n"); return FALSE; } @@ -1661,6 +1723,7 @@ DetectKeyboardDevice(VOID) if ((Status & 0x01) != 0x01) { /* No byte in buffer */ + DPRINT1("No byte in buffer\n"); return FALSE; } @@ -1668,193 +1731,164 @@ DetectKeyboardDevice(VOID) if (Scancode != 0x41) { /* No 0x41 received */ + DPRINT1("No 0x41 received\n"); return FALSE; } /* Found MF-II keyboard */ + DPRINT1("Found MF-II keyboard\n"); return TRUE; } +static USHORT +KeyboardGetShiftFlags() +{ + REGS RegsIn; + REGS RegsOut; + + /* Uses Int 16h / AH=02h */ + + RegsIn.b.ah = 0x02; /* Subfunction 02h */ + RegsIn.b.al = 0x00; + + Int386(0x16, &RegsIn, &RegsOut); + + /* Return ax */ + if (INT386_SUCCESS(RegsOut)) + return RegsOut.w.ax; + else + return 0; +} static VOID -DetectKeyboardPeripheral(FRLDRHKEY ControllerKey) +DetectKeyboardPeripheral(PCONFIGURATION_COMPONENT_DATA KeyboardController) { - PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; - PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; - PCM_KEYBOARD_DEVICE_DATA KeyboardData; - FRLDRHKEY PeripheralKey; - ULONG Size; - LONG Error; + PCM_PARTIAL_RESOURCE_LIST ResourceList; + PCM_KEYBOARD_DEVICE_DATA KeyboardData; + ULONG Size; - /* HACK: don't call DetectKeyboardDevice() as it fails in Qemu 0.8.2 */ - if (TRUE || DetectKeyboardDevice()) - { - /* Create controller key */ - Error = RegCreateKey(ControllerKey, - L"KeyboardPeripheral\\0", - &PeripheralKey); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n")); - return; - } - DbgPrint((DPRINT_HWDETECT, "Created key: KeyboardPeripheral\\0\n")); + /* HACK: Keyboard detection under qemu doesn't work! */ + if (TRUE || DetectKeyboardDevice()) + { + PCONFIGURATION_COMPONENT_DATA KeyboardComponentData; + PCONFIGURATION_COMPONENT KeyboardEntry; - /* Set 'ComponentInformation' value */ - SetComponentInformation(ControllerKey, - 0x28, - 0, - 0xFFFFFFFF); + /* Create DiskPeripheral */ + KeyboardComponentData = (PCONFIGURATION_COMPONENT_DATA)MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + RtlZeroMemory(KeyboardComponentData, sizeof(CONFIGURATION_COMPONENT_DATA)); - /* Set 'Configuration Data' value */ - Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + - sizeof(CM_KEYBOARD_DEVICE_DATA); - FullResourceDescriptor = MmAllocateMemory(Size); - if (FullResourceDescriptor == NULL) - { - DbgPrint((DPRINT_HWDETECT, - "Failed to allocate resource descriptor\n")); - return; - } + KeyboardEntry = &KeyboardComponentData->ComponentEntry; + RtlZeroMemory(KeyboardEntry, sizeof(CONFIGURATION_COMPONENT)); - /* Initialize resource descriptor */ - memset(FullResourceDescriptor, 0, Size); - FullResourceDescriptor->InterfaceType = Isa; - FullResourceDescriptor->BusNumber = 0; - FullResourceDescriptor->PartialResourceList.Version = 1; - FullResourceDescriptor->PartialResourceList.Revision = 1; - FullResourceDescriptor->PartialResourceList.Count = 1; + KeyboardEntry->Class = PeripheralClass; + KeyboardEntry->Type = KeyboardPeripheral; + KeyboardEntry->AffinityMask = 0xFFFFFFFF; + KeyboardEntry->Flags = 0x28; + KeyboardEntry->Identifier = MmAllocateMemory(14); + strcpy(KeyboardEntry->Identifier, "PCAT_ENHANCED"); + KeyboardEntry->IdentifierLength = strlen(KeyboardEntry->Identifier); + KeyboardEntry->Identifier = PaToVa(KeyboardEntry->Identifier); - PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0]; - PartialDescriptor->Type = CmResourceTypeDeviceSpecific; - PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; - PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_KEYBOARD_DEVICE_DATA); + /* Fill KeyboardPeripheral resources descriptor, which consists of: + Partial resource list + 1 resource descriptor having device data + in CM_KEYBOARD_DEVICE_DATA format */ + Size = sizeof(CM_PARTIAL_RESOURCE_LIST) + sizeof(CM_KEYBOARD_DEVICE_DATA); + KeyboardComponentData->ConfigurationData = MmAllocateMemory(Size); + RtlZeroMemory(KeyboardComponentData->ConfigurationData, Size); + ResourceList = (PCM_PARTIAL_RESOURCE_LIST)KeyboardComponentData->ConfigurationData; + ResourceList->Count = 1; - KeyboardData = (PCM_KEYBOARD_DEVICE_DATA)(PartialDescriptor + 1); - KeyboardData->Version = 1; - KeyboardData->Revision = 1; - KeyboardData->Type = 4; - KeyboardData->Subtype = 0; - KeyboardData->KeyboardFlags = 0x20; + /* Device specific data */ + ResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific; + ResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize = sizeof(PCM_KEYBOARD_DEVICE_DATA); - /* Set 'Configuration Data' value */ - Error = RegSetValue(PeripheralKey, - L"Configuration Data", - REG_FULL_RESOURCE_DESCRIPTOR, - (PCHAR)FullResourceDescriptor, - Size); - MmFreeMemory(FullResourceDescriptor); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, - "RegSetValue(Configuration Data) failed (Error %u)\n", - (int)Error)); - } + KeyboardData = (PCM_KEYBOARD_DEVICE_DATA)((ULONG_PTR)KeyboardComponentData->ConfigurationData + sizeof(CM_PARTIAL_RESOURCE_LIST)); - /* Set 'Identifier' value */ - Error = RegSetValue(PeripheralKey, - L"Identifier", - REG_SZ, - (PCHAR)L"PCAT_ENHANCED", - 14 * sizeof(WCHAR)); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, - "RegSetValue() failed (Error %u)\n", - (int)Error)); - } - } + /* Set device-specific data */ + KeyboardData->Type = 4; + KeyboardData->Subtype = 0; + KeyboardData->KeyboardFlags = KeyboardGetShiftFlags(); + + /* Add Keyboard peripheral to the parent */ + KeyboardController->Child = KeyboardComponentData; + KeyboardComponentData->Parent = KeyboardController; + } } -static VOID -DetectKeyboardController(FRLDRHKEY BusKey) +static +PCONFIGURATION_COMPONENT_DATA +DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA ParentComponent, + BOOLEAN NextChild) { - PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; - PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; - FRLDRHKEY ControllerKey; - ULONG Size; - LONG Error; + PCONFIGURATION_COMPONENT_DATA ControllerComponent; + PCONFIGURATION_COMPONENT ControllerEntry; + PCM_PARTIAL_RESOURCE_LIST ResourceList; - /* Create controller key */ - Error = RegCreateKey(BusKey, - L"KeyboardController\\0", - &ControllerKey); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n")); - return; - } - DbgPrint((DPRINT_HWDETECT, "Created key: KeyboardController\\0\n")); + return ParentComponent; - /* Set 'ComponentInformation' value */ - SetComponentInformation(ControllerKey, - 0x28, - 0, - 0xFFFFFFFF); + /* Create controller key */ + ControllerComponent = (PCONFIGURATION_COMPONENT_DATA)MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + RtlZeroMemory(ControllerComponent, sizeof(CONFIGURATION_COMPONENT_DATA)); - /* Set 'Configuration Data' value */ - Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + - 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); - FullResourceDescriptor = MmAllocateMemory(Size); - if (FullResourceDescriptor == NULL) - { - DbgPrint((DPRINT_HWDETECT, - "Failed to allocate resource descriptor\n")); - return; - } + ControllerEntry = &ControllerComponent->ComponentEntry; + RtlZeroMemory(ControllerEntry, sizeof(CONFIGURATION_COMPONENT)); - /* Initialize resource descriptor */ - memset(FullResourceDescriptor, 0, Size); - FullResourceDescriptor->InterfaceType = Isa; - FullResourceDescriptor->BusNumber = 0; - FullResourceDescriptor->PartialResourceList.Version = 1; - FullResourceDescriptor->PartialResourceList.Revision = 1; - FullResourceDescriptor->PartialResourceList.Count = 3; + ControllerEntry->Class = ControllerClass; + ControllerEntry->Type = KeyboardController; + ControllerEntry->AffinityMask = 0xFFFFFFFF; + ControllerEntry->Flags = 0x28; - /* Set Interrupt */ - PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0]; - PartialDescriptor->Type = CmResourceTypeInterrupt; - PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; - PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; - PartialDescriptor->u.Interrupt.Level = 0; - PartialDescriptor->u.Interrupt.Vector = 1; - PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF; + /* Fill keyboard controller resources descriptor, which consists of: + Partial Resource List + 2 Partial Resource Descriptors (Irq and 2 Ports) */ + ControllerComponent->ConfigurationData = MmAllocateMemory(sizeof(CM_PARTIAL_RESOURCE_LIST) + + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + RtlZeroMemory(ControllerComponent->ConfigurationData, sizeof(CM_PARTIAL_RESOURCE_LIST) + + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + ResourceList = (PCM_PARTIAL_RESOURCE_LIST)ControllerComponent->ConfigurationData; + ResourceList->Count = 2; // Interrupt + Port + Port - /* Set IO Port 0x60 */ - PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[1]; - PartialDescriptor->Type = CmResourceTypePort; - PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; - PartialDescriptor->Flags = CM_RESOURCE_PORT_IO; - PartialDescriptor->u.Port.Start.LowPart = 0x60; - PartialDescriptor->u.Port.Start.HighPart = 0x0; - PartialDescriptor->u.Port.Length = 1; + /* Interrupt */ + ResourceList->PartialDescriptors[0].Type = CmResourceTypeInterrupt; + ResourceList->PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined; + ResourceList->PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED; + ResourceList->PartialDescriptors[0].u.Interrupt.Level = 0; + ResourceList->PartialDescriptors[0].u.Interrupt.Vector = 1; + ResourceList->PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF; - /* Set IO Port 0x64 */ - PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[2]; - PartialDescriptor->Type = CmResourceTypePort; - PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; - PartialDescriptor->Flags = CM_RESOURCE_PORT_IO; - PartialDescriptor->u.Port.Start.LowPart = 0x64; - PartialDescriptor->u.Port.Start.HighPart = 0x0; - PartialDescriptor->u.Port.Length = 1; + /* Set IO Port 0x60 */ + ResourceList->PartialDescriptors[1].Type = CmResourceTypePort; + ResourceList->PartialDescriptors[1].ShareDisposition = CmResourceShareDeviceExclusive; + ResourceList->PartialDescriptors[1].Flags = CM_RESOURCE_PORT_IO; + ResourceList->PartialDescriptors[1].u.Port.Start.LowPart = 0x60; + ResourceList->PartialDescriptors[1].u.Port.Start.HighPart = 0x0; + ResourceList->PartialDescriptors[1].u.Port.Length = 1; - /* Set 'Configuration Data' value */ - Error = RegSetValue(ControllerKey, - L"Configuration Data", - REG_FULL_RESOURCE_DESCRIPTOR, - (PCHAR)FullResourceDescriptor, - Size); - MmFreeMemory(FullResourceDescriptor); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, - "RegSetValue(Configuration Data) failed (Error %u)\n", - (int)Error)); - return; - } + /* Set IO Port 0x64 */ + ResourceList->PartialDescriptors[2].Type = CmResourceTypePort; + ResourceList->PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive; + ResourceList->PartialDescriptors[2].Flags = CM_RESOURCE_PORT_IO; + ResourceList->PartialDescriptors[2].u.Port.Start.LowPart = 0x64; + ResourceList->PartialDescriptors[2].u.Port.Start.HighPart = 0x0; + ResourceList->PartialDescriptors[2].u.Port.Length = 1; - DetectKeyboardPeripheral(ControllerKey); + /* Add this keyboard controller to the parent/sibling */ + if (NextChild) + { + ParentComponent->Child = ControllerComponent; + ControllerComponent->Parent = ParentComponent; + } + else + { + ParentComponent->Sibling = ControllerComponent; + ControllerComponent->Parent = ParentComponent->Parent; + } + + /* Detect any keyboard attached to this controller */ + DetectKeyboardPeripheral(ControllerComponent); + + /* Return pointer to the keyboard controller */ + return ControllerComponent; } @@ -2156,9 +2190,16 @@ DetectDisplayController(FRLDRHKEY BusKey) static VOID -DetectIsaBios(FRLDRHKEY SystemKey, ULONG *BusNumber) +DetectIsaBios(FRLDRHKEY SystemKey, + ULONG *BusNumber, + PCONFIGURATION_COMPONENT_DATA ComponentRoot, + PCONFIGURATION_COMPONENT_DATA PreviousComponent, + BOOLEAN NextChild) { PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; + PCONFIGURATION_COMPONENT_DATA IsaAdapter, LastComponent; + PCONFIGURATION_COMPONENT IsaComponent; + PVOID Identifier; WCHAR Buffer[80]; FRLDRHKEY BusKey; ULONG Size; @@ -2231,8 +2272,39 @@ DetectIsaBios(FRLDRHKEY SystemKey, ULONG *BusNumber) return; } + + /* Create adapter component */ + IsaAdapter = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + RtlZeroMemory(IsaAdapter, sizeof(CONFIGURATION_COMPONENT_DATA)); + + IsaComponent = &IsaAdapter->ComponentEntry; + RtlZeroMemory(IsaComponent, sizeof(CONFIGURATION_COMPONENT)); + + IsaComponent->Class = AdapterClass; + IsaComponent->Type = MultiFunctionAdapter; + IsaComponent->AffinityMask = 0xFFFFFFFF; + Identifier = MmAllocateMemory(sizeof("ISA")+1); + sprintf(Identifier, "ISA"); + IsaComponent->Identifier = PaToVa(Identifier); + IsaComponent->IdentifierLength = strlen(Identifier)+1; + + if (NextChild) + { + PreviousComponent->Child = IsaAdapter; + IsaAdapter->Parent = PreviousComponent; + } + else + { + PreviousComponent->Sibling = IsaAdapter; + IsaAdapter->Parent = PreviousComponent->Parent; + } + + /* Detect ISA/BIOS devices */ - DetectBiosDisks(SystemKey, BusKey); + + /* DetectBiosDisks writes information both to the root entry and to + its own entries */ + LastComponent = DetectBiosDisks(SystemKey, BusKey, ComponentRoot, IsaAdapter, TRUE); DetectBiosFloppyController(SystemKey, BusKey); @@ -2240,7 +2312,10 @@ DetectIsaBios(FRLDRHKEY SystemKey, ULONG *BusNumber) DetectParallelPorts(BusKey); - DetectKeyboardController(BusKey); + /* Detect keyboard and mouse */ + LastComponent = + DetectKeyboardController(LastComponent, + (IsaAdapter == LastComponent) ? TRUE : FALSE); DetectPS2Mouse(BusKey); @@ -2251,14 +2326,18 @@ DetectIsaBios(FRLDRHKEY SystemKey, ULONG *BusNumber) VOID -PcHwDetect(VOID) +PcHwDetect(PCONFIGURATION_COMPONENT_DATA *ComponentRoot) { FRLDRHKEY SystemKey; ULONG BusNumber = 0; LONG Error; + PCONFIGURATION_COMPONENT Component; + PCONFIGURATION_COMPONENT_DATA LastComponentData; + DbgPrint((DPRINT_HWDETECT, "DetectHardware()\n")); +#if ROS_SPECIFIC /* Create the 'System' key */ Error = RegCreateKey(NULL, L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System", @@ -2268,6 +2347,16 @@ PcHwDetect(VOID) DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error)); return; } +#endif + + /* Allocate root configuration component */ + *ComponentRoot = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + RtlZeroMemory(*ComponentRoot, sizeof(CONFIGURATION_COMPONENT_DATA)); + + /* Create root node - "System" */ + Component = &((*ComponentRoot)->ComponentEntry); + Component->Class = SystemClass; + Component->Type = MaximumType; #if 0 DetectSystemData(); @@ -2275,10 +2364,12 @@ PcHwDetect(VOID) DetectCPUs(SystemKey); /* Detect buses */ - DetectPciBios(SystemKey, &BusNumber); + /* FIXME: Don't forget situation when some buses may be absent! (NextChild = TRUE then) */ + LastComponentData = DetectPciBios(SystemKey, &BusNumber, *ComponentRoot, *ComponentRoot, TRUE); DetectApmBios(SystemKey, &BusNumber); DetectPnpBios(SystemKey, &BusNumber); - DetectIsaBios(SystemKey, &BusNumber); + DetectIsaBios(SystemKey, &BusNumber, *ComponentRoot, LastComponentData, + (LastComponentData == *ComponentRoot) ? TRUE : FALSE); DetectAcpiBios(SystemKey, &BusNumber); DbgPrint((DPRINT_HWDETECT, "DetectHardware() Done\n")); diff --git a/arch/i386/hwpci.c b/arch/i386/hwpci.c index 1046ec1ed6e..dee4d65108b 100644 --- a/arch/i386/hwpci.c +++ b/arch/i386/hwpci.c @@ -56,8 +56,9 @@ typedef struct _PCI_IRQ_ROUTING_TABLE typedef struct _CM_PCI_BUS_DATA { + UCHAR VersionMinor; + UCHAR VersionMajor; UCHAR BusCount; - USHORT PciVersion; UCHAR HardwareMechanism; } __attribute__((packed)) CM_PCI_BUS_DATA, *PCM_PCI_BUS_DATA; @@ -126,8 +127,9 @@ FindPciBios(PCM_PCI_BUS_DATA BusData) DbgPrint((DPRINT_HWDETECT, "CL: %x\n", RegsOut.b.cl)); BusData->BusCount = RegsOut.b.cl + 1; - BusData->PciVersion = RegsOut.w.bx; - BusData->HardwareMechanism = RegsOut.b.cl; + BusData->VersionMajor = RegsOut.b.bh; + BusData->VersionMinor = RegsOut.b.bl; + BusData->HardwareMechanism = RegsOut.b.al; return TRUE; } @@ -225,143 +227,170 @@ DetectPciIrqRoutingTable(FRLDRHKEY BusKey) } -VOID -DetectPciBios(FRLDRHKEY SystemKey, ULONG *BusNumber) +PCONFIGURATION_COMPONENT_DATA +DetectPciBios(FRLDRHKEY SystemKey, + ULONG *BusNumber, + PCONFIGURATION_COMPONENT_DATA ComponentRoot, + PCONFIGURATION_COMPONENT_DATA PreviousComponent, + BOOLEAN NextChild) { - PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; - CM_PCI_BUS_DATA BusData; - WCHAR Buffer[80]; - FRLDRHKEY BiosKey; - ULONG Size; - LONG Error; -#if 0 - FRLDRHKEY BusKey; - ULONG i; - WCHAR szPci[] = L"PCI"; -#endif + PCONFIGURATION_COMPONENT_DATA PciBusComponentData, PreviousBusData; + PCONFIGURATION_COMPONENT PciBusComponent; + PVOID Identifier; + PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; + CM_PCI_BUS_DATA BusData; + WCHAR Buffer[80]; + FRLDRHKEY BiosKey; + ULONG Size; + LONG Error; + ULONG i; + BOOLEAN NextComponentChild; - /* Report the PCI BIOS */ - if (FindPciBios(&BusData)) - { - /* Create new bus key */ - swprintf(Buffer, - L"MultifunctionAdapter\\%u", *BusNumber); - Error = RegCreateKey(SystemKey, - Buffer, - &BiosKey); - if (Error != ERROR_SUCCESS) + /* Return Previous component in case no PCI buses are detected */ + PreviousBusData = PreviousComponent; + NextComponentChild = NextChild; + + /* Report the PCI BIOS */ + if (FindPciBios(&BusData)) { - DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error)); - return; + /* Create new bus key */ + swprintf(Buffer, + L"MultifunctionAdapter\\%u", *BusNumber); + Error = RegCreateKey(SystemKey, + Buffer, + &BiosKey); + if (Error != ERROR_SUCCESS) + { + DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error)); + //return NULL; + } + + /* Set 'Component Information' */ + SetComponentInformation(BiosKey, + 0x0, + 0x0, + 0xFFFFFFFF); + + /* Increment bus number */ + (*BusNumber)++; + + /* Set 'Identifier' value */ + Error = RegSetValue(BiosKey, + L"Identifier", + REG_SZ, + (PCHAR)L"PCI BIOS", + 9 * sizeof(WCHAR)); + if (Error != ERROR_SUCCESS) + { + DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error)); + //return NULL; + } + + /* Set 'Configuration Data' value */ + Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR); + FullResourceDescriptor = MmAllocateMemory(Size); + if (FullResourceDescriptor == NULL) + { + DbgPrint((DPRINT_HWDETECT, + "Failed to allocate resource descriptor\n")); + //return NULL; + } + + /* Initialize resource descriptor */ + memset(FullResourceDescriptor, 0, Size); + FullResourceDescriptor->InterfaceType = PCIBus; + FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Version = 1; + FullResourceDescriptor->PartialResourceList.Revision = 1; + FullResourceDescriptor->PartialResourceList.Count = 1; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeBusNumber; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.BusNumber.Start = 0; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.BusNumber.Length = 1; + + /* Set 'Configuration Data' value */ + Error = RegSetValue(BiosKey, + L"Configuration Data", + REG_FULL_RESOURCE_DESCRIPTOR, + (PCHAR) FullResourceDescriptor, + Size); + MmFreeMemory(FullResourceDescriptor); + if (Error != ERROR_SUCCESS) + { + DbgPrint((DPRINT_HWDETECT, + "RegSetValue(Configuration Data) failed (Error %u)\n", + (int)Error)); + //return NULL; + } + + DetectPciIrqRoutingTable(BiosKey); + + /* Attach to the component we've got -- as child */ + PreviousBusData = PreviousComponent; + NextComponentChild = NextChild; + + /* Report PCI buses */ + for (i = 0; i < (ULONG)BusData.BusCount; i++) + { + /* Create data component */ + PciBusComponentData = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + RtlZeroMemory(PciBusComponentData, sizeof(CONFIGURATION_COMPONENT_DATA)); + + /* Save a pointer to the ComponentEntry */ + PciBusComponent = &PciBusComponentData->ComponentEntry; + + /* Fill ComponentEntry */ + PciBusComponent->Class = AdapterClass; + PciBusComponent->Type = MultiFunctionAdapter; + PciBusComponent->AffinityMask = 0xFFFFFFFF; + Identifier = MmAllocateMemory(sizeof("PCI")+1); + sprintf(Identifier, "PCI"); + PciBusComponent->Identifier = PaToVa(Identifier); + PciBusComponent->IdentifierLength = strlen(Identifier)+1; + + /* We have to treat first PCI bus's data differently */ + if (i == 0) + { + PCM_PARTIAL_RESOURCE_LIST ResourceList; + PVOID DeviceSpecific; + + Size = sizeof(CM_PARTIAL_RESOURCE_LIST) + sizeof(CM_PCI_BUS_DATA); + PciBusComponent->ConfigurationDataLength = Size; + PciBusComponentData->ConfigurationData = MmAllocateMemory(Size); + RtlZeroMemory(PciBusComponentData->ConfigurationData, Size); + + ResourceList = (PCM_PARTIAL_RESOURCE_LIST)PciBusComponentData->ConfigurationData; + ResourceList->Count = 1; + ResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific; + ResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize = sizeof(CM_PCI_BUS_DATA); + + /* Fill actual data */ + DeviceSpecific = (PVOID)((ULONG_PTR)PciBusComponentData->ConfigurationData + sizeof(CM_PARTIAL_RESOURCE_LIST)); + RtlCopyMemory(DeviceSpecific, (PVOID)&BusData, sizeof(CM_PCI_BUS_DATA)); + } + + if (NextComponentChild) + { + PreviousBusData->Child = PciBusComponentData; + PciBusComponentData->Parent = PreviousBusData; + + NextComponentChild = FALSE; + } + else + { + PreviousBusData->Sibling = PciBusComponentData; + PciBusComponentData->Parent = PreviousBusData->Parent; + } + + PreviousBusData = PciBusComponentData; + + /* Increment bus number */ + (*BusNumber)++; + } + } - /* Set 'Component Information' */ - SetComponentInformation(BiosKey, - 0x0, - 0x0, - 0xFFFFFFFF); - - /* Increment bus number */ - (*BusNumber)++; - - /* Set 'Identifier' value */ - Error = RegSetValue(BiosKey, - L"Identifier", - REG_SZ, - (PCHAR)L"PCI BIOS", - 9 * sizeof(WCHAR)); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error)); - return; - } - - /* Set 'Configuration Data' value */ - Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR); - FullResourceDescriptor = MmAllocateMemory(Size); - if (FullResourceDescriptor == NULL) - { - DbgPrint((DPRINT_HWDETECT, - "Failed to allocate resource descriptor\n")); - return; - } - - /* Initialize resource descriptor */ - memset(FullResourceDescriptor, 0, Size); - FullResourceDescriptor->InterfaceType = PCIBus; - FullResourceDescriptor->BusNumber = 0; - FullResourceDescriptor->PartialResourceList.Version = 1; - FullResourceDescriptor->PartialResourceList.Revision = 1; - FullResourceDescriptor->PartialResourceList.Count = 1; - FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeBusNumber; - FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive; - FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.BusNumber.Start = 0; - FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.BusNumber.Length = 1; - - /* Set 'Configuration Data' value */ - Error = RegSetValue(BiosKey, - L"Configuration Data", - REG_FULL_RESOURCE_DESCRIPTOR, - (PCHAR) FullResourceDescriptor, - Size); - MmFreeMemory(FullResourceDescriptor); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, - "RegSetValue(Configuration Data) failed (Error %u)\n", - (int)Error)); - return; - } - - DetectPciIrqRoutingTable(BiosKey); - -#if 0 - /* - * FIXME: - * Enabling this piece of code will corrupt the boot sequence! - * This is probably caused by a bug in the registry code! - */ - - /* Report PCI buses */ - for (i = 0; i < (ULONG)BusData.BusCount; i++) - { - swprintf(Buffer, - L"MultifunctionAdapter\\%u", *BusNumber); - Error = RegCreateKey(SystemKey, - Buffer, - &BusKey); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error)); - printf("RegCreateKey() failed (Error %u)\n", (int)Error); - return; - } - - /* Set 'Component Information' */ - SetComponentInformation(BusKey, - 0x0, - 0x0, - 0xFFFFFFFF); - - /* Increment bus number */ - (*BusNumber)++; - - - /* Set 'Identifier' value */ - Error = RegSetValue(BusKey, - L"Identifier", - REG_SZ, - (PCSTR)szPci, - sizeof(szPci)); - if (Error != ERROR_SUCCESS) - { - DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error)); - return; - } - } -#endif - - } + return PreviousBusData; } /* EOF */ diff --git a/arch/i386/i386idt.S b/arch/i386/i386idt.S index 7fc46fa9ff0..0e2fad8c140 100644 --- a/arch/i386/i386idt.S +++ b/arch/i386/i386idt.S @@ -27,93 +27,93 @@ .p2align 2 /* force 4-byte alignment */ EXTERN(i386idt) /* Exception 0 - Divide By Zero */ - .word i386DivideByZero /* Offset 0 - 15 */ + .word _i386DivideByZero /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Flags, Zero Byte */ + .word 0x8f00 /* Flags, Zero Byte */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 1 - Debug Exception */ - .word i386DebugException /* Offset 0 - 15 */ + .word _i386DebugException /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 2 - NMI */ - .word i386NMIException /* Offset 0 - 15 */ + .word _i386NMIException /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 3 - Breakpoint (INT 3) */ - .word i386Breakpoint /* Offset 0 - 15 */ + .word _i386Breakpoint /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 4 - Overflow (INTO with EFLAGS[OF] set) */ - .word i386Overflow /* Offset 0 - 15 */ + .word _i386Overflow /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 5 - Bound Exception */ - .word i386BoundException /* Offset 0 - 15 */ + .word _i386BoundException /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 6 - Invalid Opcode */ - .word i386InvalidOpcode /* Offset 0 - 15 */ + .word _i386InvalidOpcode /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 7 - FPU Not Available */ - .word i386FPUNotAvailable /* Offset 0 - 15 */ + .word _i386FPUNotAvailable /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 8 - Double Fault */ - .word i386DoubleFault /* Offset 0 - 15 */ + .word _i386DoubleFault /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 9 - Coprocessor Segment Overrun */ - .word i386CoprocessorSegment /* Offset 0 - 15 */ + .word _i386CoprocessorSegment /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 10 (0x0A) - Invalid TSS */ - .word i386InvalidTSS /* Offset 0 - 15 */ + .word _i386InvalidTSS /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 11 (0x0B) - Segment Not Present */ - .word i386SegmentNotPresent /* Offset 0 - 15 */ + .word _i386SegmentNotPresent /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 12 (0x0C) - Stack Exception */ - .word i386StackException /* Offset 0 - 15 */ + .word _i386StackException /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 13 (0x0D) - General Protection Fault */ - .word i386GeneralProtectionFault /* Offset 0 - 15 */ + .word _i386GeneralProtectionFault /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 14 (0x0E) - Page Fault */ - .word i386PageFault /* Offset 0 - 15 */ + .word _i386PageFault /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 15 (0x0F) - Reserved */ @@ -123,21 +123,21 @@ EXTERN(i386idt) .word 0x0000 /* Offset 16 - 31 */ /* Exception 16 (0x10) - Coprocessor Error */ - .word i386CoprocessorError /* Offset 0 - 15 */ + .word _i386CoprocessorError /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 17 (0x11) - Alignment Check */ - .word i386AlignmentCheck /* Offset 0 - 15 */ + .word _i386AlignmentCheck /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 18 (0x12) - Machine Check */ - .word i386MachineCheck /* Offset 0 - 15 */ + .word _i386MachineCheck /* Offset 0 - 15 */ .word 0x0008 /* Selector */ - .word 0x8e00 /* Zero byte, flags */ + .word 0x8f00 /* Zero byte, flags */ .word 0x0000 /* Offset 16 - 31 */ /* Exception 19 (0x13) - Reserved */ diff --git a/arch/i386/i386trap.S b/arch/i386/i386trap.S index 4a367311677..b17a2a090f8 100644 --- a/arch/i386/i386trap.S +++ b/arch/i386/i386trap.S @@ -591,63 +591,63 @@ i386PrintHexByte1: ret /************************************************************************/ -EXTERN(i386DivideByZero) +EXTERN(_i386DivideByZero) .code32 movl $i386DivideByZeroText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386DebugException) +EXTERN(_i386DebugException) .code32 movl $i386DebugExceptionText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386NMIException) +EXTERN(_i386NMIException) .code32 movl $i386NMIExceptionText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386Breakpoint) +EXTERN(_i386Breakpoint) .code32 movl $i386BreakpointText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386Overflow) +EXTERN(_i386Overflow) .code32 movl $i386OverflowText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386BoundException) +EXTERN(_i386BoundException) .code32 movl $i386BoundExceptionText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386InvalidOpcode) +EXTERN(_i386InvalidOpcode) .code32 movl $i386InvalidOpcodeText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386FPUNotAvailable) +EXTERN(_i386FPUNotAvailable) .code32 movl $i386FPUNotAvailableText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386DoubleFault) +EXTERN(_i386DoubleFault) .code32 popl %eax @@ -657,14 +657,14 @@ EXTERN(i386DoubleFault) jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386CoprocessorSegment) +EXTERN(_i386CoprocessorSegment) .code32 movl $i386CoprocessorSegmentText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386InvalidTSS) +EXTERN(_i386InvalidTSS) .code32 popl %eax @@ -674,7 +674,7 @@ EXTERN(i386InvalidTSS) jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386SegmentNotPresent) +EXTERN(_i386SegmentNotPresent) .code32 popl %eax @@ -684,7 +684,7 @@ EXTERN(i386SegmentNotPresent) jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386StackException) +EXTERN(_i386StackException) .code32 popl %eax @@ -694,7 +694,7 @@ EXTERN(i386StackException) jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386GeneralProtectionFault) +EXTERN(_i386GeneralProtectionFault) .code32 popl %eax @@ -704,7 +704,7 @@ EXTERN(i386GeneralProtectionFault) jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386PageFault) +EXTERN(_i386PageFault) .code32 popl %eax @@ -714,21 +714,21 @@ EXTERN(i386PageFault) jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386CoprocessorError) +EXTERN(_i386CoprocessorError) .code32 movl $i386CoprocessorErrorText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386AlignmentCheck) +EXTERN(_i386AlignmentCheck) .code32 movl $i386AlignmentCheckText,i386ExceptionDescriptionText jmp i386CommonExceptionHandler /************************************************************************/ -EXTERN(i386MachineCheck) +EXTERN(_i386MachineCheck) .code32 movl $i386MachineCheckText,i386ExceptionDescriptionText diff --git a/arch/i386/xboxhw.c b/arch/i386/xboxhw.c index f310a47febf..249e0fa1391 100644 --- a/arch/i386/xboxhw.c +++ b/arch/i386/xboxhw.c @@ -20,7 +20,7 @@ #include VOID -XboxHwDetect(VOID) +XboxHwDetect(PCONFIGURATION_COMPONENT_DATA *ComponentRoot) { } diff --git a/freeldr_arch.rbuild b/freeldr_arch.rbuild index ca61e7448ed..c92eaf3edc6 100644 --- a/freeldr_arch.rbuild +++ b/freeldr_arch.rbuild @@ -6,10 +6,11 @@ cache include - + + -ffreestanding -fno-builtin -fno-inline @@ -56,6 +57,7 @@ --> + -ffreestanding -fno-builtin -fno-inline diff --git a/freeldr_base.rbuild b/freeldr_base.rbuild index fe4cf462b15..b319454a725 100644 --- a/freeldr_base.rbuild +++ b/freeldr_base.rbuild @@ -4,9 +4,9 @@ . include - + -ffreestanding diff --git a/freeldr_base64k.rbuild b/freeldr_base64k.rbuild index d9e20fd17aa..4e3975bc7c9 100644 --- a/freeldr_base64k.rbuild +++ b/freeldr_base64k.rbuild @@ -6,6 +6,7 @@ --> + -ffreestanding -fno-builtin -fno-inline diff --git a/freeldr_main.rbuild b/freeldr_main.rbuild index a698373ef6e..d6e0c3181f5 100644 --- a/freeldr_main.rbuild +++ b/freeldr_main.rbuild @@ -2,10 +2,11 @@ include include - + + -ffreestanding -fno-builtin -fno-inline diff --git a/include/arch/i386/hardware.h b/include/arch/i386/hardware.h index 0bfae9a4400..9550c5d214f 100644 --- a/include/arch/i386/hardware.h +++ b/include/arch/i386/hardware.h @@ -76,7 +76,11 @@ VOID DetectApmBios(FRLDRHKEY SystemKey, ULONG *BusNumber); VOID DetectCPUs(FRLDRHKEY SystemKey); /* hwpci.c */ -VOID DetectPciBios(FRLDRHKEY SystemKey, ULONG *BusNumber); +PCONFIGURATION_COMPONENT_DATA DetectPciBios(FRLDRHKEY SystemKey, + ULONG *BusNumber, + PCONFIGURATION_COMPONENT_DATA ComponentRoot, + PCONFIGURATION_COMPONENT_DATA PreviousComponent, + BOOLEAN NextChild); /* i386cpu.S */ ULONG CpuidSupported(VOID); diff --git a/include/arch/i386/machpc.h b/include/arch/i386/machpc.h index c87e756b936..155ec1c4af9 100644 --- a/include/arch/i386/machpc.h +++ b/include/arch/i386/machpc.h @@ -55,7 +55,7 @@ ULONG PcDiskGetCacheableBlockCount(ULONG DriveNumber); VOID PcRTCGetCurrentDateTime(PULONG Year, PULONG Month, PULONG Day, PULONG Hour, PULONG Minute, PULONG Second); -VOID PcHwDetect(VOID); +VOID PcHwDetect(PCONFIGURATION_COMPONENT_DATA *ComponentRoot); #endif /* __I386_MACHPC_H_ */ diff --git a/include/arch/i386/machxbox.h b/include/arch/i386/machxbox.h index 4f24dab4766..03f02844eb9 100644 --- a/include/arch/i386/machxbox.h +++ b/include/arch/i386/machxbox.h @@ -58,7 +58,7 @@ ULONG XboxDiskGetCacheableBlockCount(ULONG DriveNumber); VOID XboxRTCGetCurrentDateTime(PULONG Year, PULONG Month, PULONG Day, PULONG Hour, PULONG Minute, PULONG Second); -VOID XboxHwDetect(VOID); +VOID XboxHwDetect(PCONFIGURATION_COMPONENT_DATA *ComponentRoot); VOID XboxSetLED(PCSTR Pattern); diff --git a/include/machine.h b/include/machine.h index 51996a7a1e5..005518da754 100644 --- a/include/machine.h +++ b/include/machine.h @@ -69,7 +69,7 @@ typedef struct tagMACHVTBL VOID (*RTCGetCurrentDateTime)(PULONG Year, PULONG Month, PULONG Day, PULONG Hour, PULONG Minute, PULONG Second); - VOID (*HwDetect)(VOID); + VOID (*HwDetect)(PCONFIGURATION_COMPONENT_DATA *ComponentRoot); } MACHVTBL, *PMACHVTBL; VOID MachInit(const char *CmdLine); @@ -111,7 +111,7 @@ BOOLEAN MachDiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPAR BOOLEAN MachDiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry); ULONG MachDiskGetCacheableBlockCount(ULONG DriveNumber); VOID MachRTCGetCurrentDateTime(PULONG Year, PULONG Month, PULONG Day, PULONG Hour, PULONG Minute, PULONG Second); -VOID MachHwDetect(VOID); +VOID MachHwDetect(PCONFIGURATION_COMPONENT_DATA *ComponentRoot); #define MachConsPutChar(Ch) MachVtbl.ConsPutChar(Ch) #define MachConsKbHit() MachVtbl.ConsKbHit() @@ -141,7 +141,7 @@ VOID MachHwDetect(VOID); #define MachDiskGetDriveGeometry(Drive, Geom) MachVtbl.DiskGetDriveGeometry((Drive), (Geom)) #define MachDiskGetCacheableBlockCount(Drive) MachVtbl.DiskGetCacheableBlockCount(Drive) #define MachRTCGetCurrentDateTime(Y, Mo, D, H, Mi, S) MachVtbl.RTCGetCurrentDateTime((Y), (Mo), (D), (H), (Mi), (S)); -#define MachHwDetect() MachVtbl.HwDetect() +#define MachHwDetect(ConfigRoot) MachVtbl.HwDetect((ConfigRoot)) #endif /* __MACHINE_H_ */ diff --git a/include/mm.h b/include/mm.h index 83c5fdf00c7..818fc9071b9 100644 --- a/include/mm.h +++ b/include/mm.h @@ -79,7 +79,7 @@ PVOID MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG Map VOID MmSortBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount); // Sorts the BIOS_MEMORY_MAP array so the first element corresponds to the first address in memory VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount); // Inits the page lookup table according to the memory types in the memory map VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY PageAllocated); // Marks the specified pages as allocated or free in the lookup table -VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount); // Allocates the specified pages in the lookup table +VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY MemoryType); // Allocates the specified pages in the lookup table ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount); // Returns the number of free pages in the lookup table ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, BOOLEAN FromEnd); // Returns the page number of the first available page range from the beginning or end of memory ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, ULONG LastPage); // Returns the page number of the first available page range before the specified page @@ -94,11 +94,12 @@ PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(ULONG *NoEntries); // Returns a pointer //BOOLEAN MmInitializeMemoryManager(ULONG LowMemoryStart, ULONG LowMemoryLength); BOOLEAN MmInitializeMemoryManager(VOID); PVOID MmAllocateMemory(ULONG MemorySize); +PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType); VOID MmFreeMemory(PVOID MemoryPointer); VOID MmChangeAllocationPolicy(BOOLEAN PolicyAllocatePagesFromEnd); //PVOID MmAllocateLowMemory(ULONG MemorySize); //VOID MmFreeLowMemory(PVOID MemoryPointer); -PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress); -PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress); +PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType); +PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType); #endif // defined __MEMORY_H diff --git a/include/winldr.h b/include/winldr.h index 57ef9a6f59d..bd7b9f51379 100644 --- a/include/winldr.h +++ b/include/winldr.h @@ -40,8 +40,8 @@ NTAPI #define SECTOR_SIZE 512 // Descriptors -#define NUM_GDT 28 //15. The kernel wants 0xD8 as a last GDT entry offset -#define NUM_IDT 0x100 // only 16 are used though +#define NUM_GDT 128 // Must be 128 +#define NUM_IDT 0x100 // only 16 are used though. Must be 0x100 // conversion.c PVOID VaToPa(PVOID Va); @@ -52,6 +52,7 @@ VOID ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start); // peloader.c BOOLEAN WinLdrLoadImage(IN PCHAR FileName, + TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA); diff --git a/linuxboot.c b/linuxboot.c index 27589bd6a26..2c5293766f9 100644 --- a/linuxboot.c +++ b/linuxboot.c @@ -375,7 +375,7 @@ BOOLEAN LinuxReadKernel(PFILE LinuxKernelFile) UiDrawStatusText(StatusText); // Allocate memory for Linux kernel - LinuxKernelLoadAddress = MmAllocateMemoryAtAddress(LinuxKernelSize, (PVOID)LINUX_KERNEL_LOAD_ADDRESS); + LinuxKernelLoadAddress = MmAllocateMemoryAtAddress(LinuxKernelSize, (PVOID)LINUX_KERNEL_LOAD_ADDRESS, LoaderSystemCode); if (LinuxKernelLoadAddress != (PVOID)LINUX_KERNEL_LOAD_ADDRESS) { return FALSE; @@ -452,11 +452,11 @@ BOOLEAN LinuxReadInitrd(PFILE LinuxInitrdFile) //LinuxInitrdLoadAddress = MmAllocateMemoryAtAddress(LinuxInitrdSize, (PVOID)ROUND_UP((LINUX_KERNEL_LOAD_ADDRESS + LinuxKernelSize), 0x100000)); if (LinuxSetupSector->Version <= 0x0202) { - LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LINUX_MAX_INITRD_ADDRESS); + LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LINUX_MAX_INITRD_ADDRESS, LoaderSystemCode); } else { - LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LinuxSetupSector->InitrdAddressMax); + LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LinuxSetupSector->InitrdAddressMax, LoaderSystemCode); } if (LinuxInitrdLoadAddress == NULL) { diff --git a/machine.c b/machine.c index 5d6933fa0ef..0d653aa95c9 100644 --- a/machine.c +++ b/machine.c @@ -228,9 +228,9 @@ MachRTCGetCurrentDateTime(PULONG Year, PULONG Month, PULONG Day, PULONG Hour, PU } VOID -MachHwDetect(VOID) +MachHwDetect(PCONFIGURATION_COMPONENT_DATA *ComponentRoot) { - MachVtbl.HwDetect(); + MachVtbl.HwDetect(ComponentRoot); } /* EOF */ diff --git a/mm/meminit.c b/mm/meminit.c index 9a5f20058c4..4e070676082 100644 --- a/mm/meminit.c +++ b/mm/meminit.c @@ -95,6 +95,27 @@ BOOLEAN MmInitializeMemoryManager(VOID) MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable, BiosMemoryMap, BiosMemoryMapEntryCount); MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable); + // Add machine-dependent stuff + // FIXME: this is only for i386 +#if 0 + MmMarkPagesInLookupTable(PageLookupTableAddress, 0x00, 1, LoaderFirmwarePermanent); // realmode int vectors + MmMarkPagesInLookupTable(PageLookupTableAddress, 0x01, 7, LoaderFirmwareTemporary); // freeldr stack + cmdline + MmMarkPagesInLookupTable(PageLookupTableAddress, 0x08, 0x70, LoaderLoadedProgram); // freeldr image (roughly max. 0x64 pages) + MmMarkPagesInLookupTable(PageLookupTableAddress, 0x78, 8, LoaderOsloaderStack); // prot mode stack + + MmMarkPagesInLookupTable(PageLookupTableAddress, 0x80, 0x10, LoaderOsloaderHeap); // File system read buffer + MmMarkPagesInLookupTable(PageLookupTableAddress, 0x90, 0x10, LoaderOsloaderHeap); // Disk read buffer for int 13h + + MmMarkPagesInLookupTable(PageLookupTableAddress, 0xA0, 0x60, LoaderFirmwarePermanent); // ROM / Video +#endif + //HACK: Temporary, for test, remove soon + MmMarkPagesInLookupTable(PageLookupTableAddress, 0x00, 0x100, LoaderFirmwarePermanent); + + MmMarkPagesInLookupTable(PageLookupTableAddress, 0xFFF, 1, LoaderSpecialMemory); // unusable memory + + //HACK: Needed for ReactOS only! (KERNEL_BASE_PHYS >> MM_PAGE_SHIFT) + //MmMarkPagesInLookupTable(PageLookupTableAddress, 0x200, 0x300, LoaderFirmwareTemporary); // ReactOS kernel sits here + FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress, TotalPagesInLookupTable); DbgPrint((DPRINT_MEMORY, "Memory Manager initialized. %d pages available.\n", FreePagesInLookupTable)); @@ -190,17 +211,50 @@ PVOID MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG Map RtlCopyMemory(TempBiosMemoryMap, BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32); MmSortBiosMemoryMap(TempBiosMemoryMap, MapCount); - for (Index=(MapCount-1); Index>=0; Index--) + for (Index=0; Index= PageLookupTableSize) + + // place it somewhere @ 10Mb if possible + // (afaik no bad things are placed at 10Mb, if there are + // - we just fallback to the usual algo) + + // skip if this is not usable region + if (TempBiosMemoryMap[Index].Type != BiosMemoryUsable) + continue; + + if (TempBiosMemoryMap[Index].BaseAddress <= 10 * 0x100000 && + TempBiosMemoryMap[Index].BaseAddress + TempBiosMemoryMap[Index].Length >= + 10 * 0x100000 + PageLookupTableSize) { - PageLookupTableMemAddress = (PVOID)(ULONG)(TempBiosMemoryMap[Index].BaseAddress + (TempBiosMemoryMap[Index].Length - PageLookupTableSize)); + PageLookupTableMemAddress = (PVOID)(10 * 0x100000); break; } } + // Check if we found a suitable place + if (PageLookupTableMemAddress == 0) + { + // no, let's do a traditional algorithm instead + for (Index=(MapCount-1); Index>=0; Index--) + { + // If this is usable memory with a big enough length + // then we'll put our page lookup table here + + // skip if this is not usable region + if (TempBiosMemoryMap[Index].Type != BiosMemoryUsable) + continue; + + if (TempBiosMemoryMap[Index].Length >= PageLookupTableSize) + { + PageLookupTableMemAddress = (PVOID)(ULONG) + (TempBiosMemoryMap[Index].BaseAddress + (TempBiosMemoryMap[Index].Length - PageLookupTableSize)); + break; + } + } + } + DbgPrint((DPRINT_MEMORY, "MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress)); return PageLookupTableMemAddress; @@ -243,7 +297,7 @@ VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_ME // Mark every page as allocated initially // We will go through and mark pages again according to the memory map // But this will mark any holes not described in the map as allocated - MmMarkPagesInLookupTable(PageLookupTable, 0, TotalPageCount, 1); + MmMarkPagesInLookupTable(PageLookupTable, 0, TotalPageCount, LoaderFirmwarePermanent); for (Index=0; Index0; Index--) + for (Index=/*LastFreePageHint-1*/(16*1024*1024>>12)-1; Index>0; Index--) + //for (Index=LastFreePageHint-1; Index>0; Index--) { if (RealPageLookupTable[Index].PageAllocated != LoaderFree) { diff --git a/mm/mm.c b/mm/mm.c index 1e36519f4dc..9df8b979870 100644 --- a/mm/mm.c +++ b/mm/mm.c @@ -59,7 +59,7 @@ VOID MmChangeAllocationPolicy(BOOLEAN PolicyAllocatePagesFromEnd) AllocateFromEnd = PolicyAllocatePagesFromEnd; } -PVOID MmAllocateMemory(ULONG MemorySize) +PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType) { ULONG PagesNeeded; ULONG FirstFreePageFromEnd; @@ -102,7 +102,7 @@ PVOID MmAllocateMemory(ULONG MemorySize) return NULL; } - MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded); + MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType); FreePagesInLookupTable -= PagesNeeded; MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE); @@ -125,7 +125,14 @@ PVOID MmAllocateMemory(ULONG MemorySize) return MemPointer; } -PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress) + +PVOID MmAllocateMemory(ULONG MemorySize) +{ + // Allocate it as "heap" + return MmAllocateMemoryWithType(MemorySize, LoaderOsloaderHeap); +} + +PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType) { ULONG PagesNeeded; ULONG StartPageNumber; @@ -168,7 +175,7 @@ PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress) return NULL; } - MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded); + MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, MemoryType); FreePagesInLookupTable -= PagesNeeded; MemPointer = (PVOID)(StartPageNumber * MM_PAGE_SIZE); @@ -184,7 +191,7 @@ PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress) return MemPointer; } -PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress) +PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType) { ULONG PagesNeeded; ULONG FirstFreePageFromEnd; @@ -223,7 +230,7 @@ PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress return NULL; } - MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded); + MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType); FreePagesInLookupTable -= PagesNeeded; MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE); @@ -377,7 +384,7 @@ VOID DumpMemoryAllocMap(VOID) if ((Idx % 32) == 0) { DbgPrint((DPRINT_MEMORY, "\n")); - DbgPrint((DPRINT_MEMORY, "%x:\t", (Idx * MM_PAGE_SIZE))); + DbgPrint((DPRINT_MEMORY, "%08x:\t", (Idx * MM_PAGE_SIZE))); } else if ((Idx % 4) == 0) { diff --git a/reactos/binhive.c b/reactos/binhive.c index 520e4f4d9be..72911baa935 100644 --- a/reactos/binhive.c +++ b/reactos/binhive.c @@ -680,6 +680,7 @@ RegImportSubKey(PHHIVE Hive, { HashCell = (PHASH_TABLE_CELL) HvGetCell (Hive, KeyCell->SubKeyLists[HvStable]); DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell)); + DbgPrint((DPRINT_REGISTRY, "HashCell->Id: %x\n", HashCell->Id)); DbgPrint((DPRINT_REGISTRY, "SubKeyCounts: %x\n", KeyCell->SubKeyCounts)); for (i = 0; i < KeyCell->SubKeyCounts[HvStable]; i++) diff --git a/reactos/reactos.c b/reactos/reactos.c index 5c60d63ca06..26777136c55 100644 --- a/reactos/reactos.c +++ b/reactos/reactos.c @@ -650,6 +650,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) UINT i; CHAR MsgBuffer[256]; ULONG SectionId; + PCONFIGURATION_COMPONENT_DATA ConfigRoot; ULONG_PTR Base; ULONG Size; @@ -767,7 +768,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) /* * Detect hardware */ - MachHwDetect(); + MachHwDetect(&ConfigRoot); UiDrawProgressBarCenter(5, 100, szLoadingMsg); if (AcpiPresent) LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE; diff --git a/reactos/setupldr.c b/reactos/setupldr.c index 87ebb1d4ee6..30618789ada 100644 --- a/reactos/setupldr.c +++ b/reactos/setupldr.c @@ -284,6 +284,7 @@ VOID RunLoader(VOID) const char *LoadOptions; UINT i; char szKernelName[256]; + PCONFIGURATION_COMPONENT_DATA ConfigRoot; HINF InfHandle; ULONG ErrorLine; @@ -354,7 +355,7 @@ VOID RunLoader(VOID) #else printf("Detecting hardware...\n\n"); #endif - MachHwDetect(); + MachHwDetect(&ConfigRoot); #ifdef USE_UI UiDrawStatusText(""); #endif diff --git a/windows/conversion.c b/windows/conversion.c index a42184bbfb4..ad1b621ae61 100644 --- a/windows/conversion.c +++ b/windows/conversion.c @@ -72,7 +72,7 @@ ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start) PCONFIGURATION_COMPONENT_DATA Child; PCONFIGURATION_COMPONENT_DATA Sibling; - DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)", Start)); + DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)\n", Start)); Child = Start; while (Child != NULL) @@ -89,11 +89,12 @@ ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start) if (Child->Sibling) Child->Sibling = PaToVa(Child->Sibling); - DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Child, Child->ComponentEntry.Class)); + DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d type %d, parent %p\n", Child, + Child->ComponentEntry.Class, Child->ComponentEntry.Type, Child->Parent)); // If the child has a sibling list, then search the sibling list // for an entry that matches the specified class, type, and key. - Sibling = Child->Sibling; + Sibling = VaToPa(Child->Sibling); while (Sibling != NULL) { if (Sibling->ConfigurationData) @@ -108,7 +109,8 @@ ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start) if (Sibling->Sibling) Sibling->Sibling = PaToVa(Sibling->Sibling); - DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Sibling, Sibling->ComponentEntry.Class)); + DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d type %d sib, parent %p\n", Sibling, + Sibling->ComponentEntry.Class, Sibling->ComponentEntry.Type, Sibling->Parent)); // If the sibling has a child tree, then search the child tree // for an entry that matches the specified class, type, and key. @@ -118,6 +120,7 @@ ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start) Sibling = VaToPa(Sibling->Sibling); } + // Go to the next child Child = VaToPa(Child->Child); } } diff --git a/windows/peloader.c b/windows/peloader.c index 2aeb30fbaca..9a02016abf3 100644 --- a/windows/peloader.c +++ b/windows/peloader.c @@ -1,5 +1,5 @@ /* - * PROJECT: WinLoader + * PROJECT: FreeLoader * LICENSE: GPL - See COPYING in the top level directory * FILE: freeldr/winldr/peloader.c * PURPOSE: Provides routines for loading PE files. To be merged with @@ -16,26 +16,146 @@ /* INCLUDES ***************************************************************/ #include -#define NDEBUG +//#define NDEBUG #include + +BOOLEAN +WinLdrpCompareDllName(IN PCH DllName, + IN PUNICODE_STRING UnicodeName); + +BOOLEAN +WinLdrpBindImportName(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PVOID DllBase, + IN PVOID ImageBase, + IN PIMAGE_THUNK_DATA ThunkData, + IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, + IN ULONG ExportSize, + IN BOOLEAN ProcessForwards); + +BOOLEAN +WinLdrpLoadAndScanReferencedDll(PLOADER_PARAMETER_BLOCK WinLdrBlock, + PCCH DirectoryPath, + PCH ImportName, + PLDR_DATA_TABLE_ENTRY *DataTableEntry); + +BOOLEAN +WinLdrpScanImportAddressTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PVOID DllBase, + IN PVOID ImageBase, + IN PIMAGE_THUNK_DATA ThunkData); + + + /* FUNCTIONS **************************************************************/ +/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */ BOOLEAN WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, IN PCH DllName, OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry) { + PLDR_DATA_TABLE_ENTRY DataTableEntry; + LIST_ENTRY *ModuleEntry; + + DbgPrint((DPRINT_WINDOWS, "WinLdrCheckForLoadedDll: DllName %X, LoadedEntry: %X\n", + DllName, LoadedEntry)); + + /* Just go through each entry in the LoadOrderList and compare loaded module's + name with a given name */ + ModuleEntry = WinLdrBlock->LoadOrderListHead.Flink; + while (ModuleEntry != &WinLdrBlock->LoadOrderListHead) + { + /* Get pointer to the current DTE */ + DataTableEntry = CONTAINING_RECORD(ModuleEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + DbgPrint((DPRINT_WINDOWS, "WinLdrCheckForLoadedDll: DTE %p, EP %p\n", + DataTableEntry, DataTableEntry->EntryPoint)); + + /* Compare names */ + if (WinLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName)) + { + /* Yes, found it, report pointer to the loaded module's DTE + to the caller and increase load count for it */ + *LoadedEntry = DataTableEntry; + DataTableEntry->LoadCount++; + DbgPrint((DPRINT_WINDOWS, "WinLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry)); + return TRUE; + } + + /* Go to the next entry */ + ModuleEntry = ModuleEntry->Flink; + } + + /* Nothing found */ return FALSE; } - BOOLEAN WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, IN PCCH DirectoryPath, IN PLDR_DATA_TABLE_ENTRY ScanDTE) { - return FALSE; + PLDR_DATA_TABLE_ENTRY DataTableEntry; + PIMAGE_IMPORT_DESCRIPTOR ImportTable; + ULONG ImportTableSize; + PCH ImportName; + BOOLEAN Status; + + /* Get a pointer to the import table of this image */ + ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase), + TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize); + + DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable(): %S ImportTable = 0x%X\n", + VaToPa(ScanDTE->BaseDllName.Buffer),ImportTable)); + + /* If image doesn't have any import directory - just return success */ + if (ImportTable == NULL) + return TRUE; + + /* Loop through all entries */ + for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != NULL);ImportTable++) + { + /* Get pointer to the name */ + ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name)); + DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable(): Looking at %s\n", ImportName)); + + /* In case we get a reference to ourselves - just skip it */ + if (WinLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName)) + continue; + + /* Load the DLL if it is not already loaded */ + if (!WinLdrCheckForLoadedDll(WinLdrBlock, ImportName, &DataTableEntry)) + { + Status = WinLdrpLoadAndScanReferencedDll(WinLdrBlock, + DirectoryPath, + ImportName, + &DataTableEntry); + + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "WinLdrpLoadAndScanReferencedDll() failed\n")); + return Status; + } + } + + /* Scan its import address table */ + Status = WinLdrpScanImportAddressTable( + WinLdrBlock, + DataTableEntry->DllBase, + ScanDTE->DllBase, + (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk)); + + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "WinLdrpScanImportAddressTable() failed\n")); + return Status; + } + } + + return TRUE; } BOOLEAN @@ -63,8 +183,7 @@ WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, /* Initialize corresponding fields of DTE based on NT headers value */ DataTableEntry->DllBase = BaseVA; DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; - DataTableEntry->EntryPoint = (PVOID)((ULONG)BaseVA + - NtHeaders->OptionalHeader.AddressOfEntryPoint); + DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint); DataTableEntry->SectionPointer = 0; DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum; @@ -123,6 +242,7 @@ WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, */ BOOLEAN WinLdrLoadImage(IN PCHAR FileName, + TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA) { PFILE FileHandle; @@ -135,7 +255,11 @@ WinLdrLoadImage(IN PCHAR FileName, BOOLEAN Status; ULONG i, BytesRead; - //Print(L"Loading %s... ", FileName); + CHAR ProgressString[256]; + + /* Inform user we are loading files */ + sprintf(ProgressString, "Loading %s...", FileName); + UiDrawProgressBarCenter(1, 100, ProgressString); /* Open the image file */ FileHandle = FsOpenFile(FileName); @@ -183,14 +307,15 @@ WinLdrLoadImage(IN PCHAR FileName, /* Try to allocate this memory, if fails - allocate somewhere else */ PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage, - (PVOID)NtHeaders->OptionalHeader.ImageBase); + (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)), + MemoryType); if (PhysicalBase == NULL) { /* It's ok, we don't panic - let's allocate again at any other "low" place */ - MmChangeAllocationPolicy(FALSE); - PhysicalBase = MmAllocateMemory(NtHeaders->OptionalHeader.SizeOfImage); - MmChangeAllocationPolicy(TRUE); + //MmChangeAllocationPolicy(FALSE); + PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType); + //MmChangeAllocationPolicy(TRUE); if (PhysicalBase == NULL) { @@ -263,12 +388,18 @@ WinLdrLoadImage(IN PCHAR FileName, Status = FsReadFile(FileHandle, SizeOfRawData, &BytesRead, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress); if (!Status && (BytesRead == 0)) + { + DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage(): Error reading section from file!\n")); break; + } } /* Size of data is less than the virtual size - fill up the remainder with zeroes */ if (SizeOfRawData < VirtualSize) + { + DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage(): SORD %d < VS %d", SizeOfRawData, VirtualSize)); RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData); + } SectionHeader++; } @@ -298,3 +429,394 @@ WinLdrLoadImage(IN PCHAR FileName, } /* PRIVATE FUNCTIONS *******************************************************/ + +/* DllName - physical, UnicodeString->Buffer - virtual */ +BOOLEAN +WinLdrpCompareDllName(IN PCH DllName, + IN PUNICODE_STRING UnicodeName) +{ + PWSTR Buffer; + UNICODE_STRING UnicodeNamePA; + ULONG i, Length; + + /* First obvious check: for length of two names */ + Length = strlen(DllName); + + UnicodeNamePA.Length = UnicodeName->Length; + UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength; + UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer); + DbgPrint((DPRINT_WINDOWS, "WinLdrpCompareDllName: %s and %wZ, Length = %d " + "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length)); + + if ((Length * sizeof(WCHAR)) > UnicodeName->Length) + return FALSE; + + /* Store pointer to unicode string's buffer */ + Buffer = VaToPa(UnicodeName->Buffer); + + /* Loop character by character */ + for (i = 0; i < Length; i++) + { + /* Compare two characters, uppercasing them */ + if (toupper(*DllName) != toupper((CHAR)*Buffer)) + return FALSE; + + /* Move to the next character */ + DllName++; + Buffer++; + } + + /* Check, if strings either fully match, or match till the "." (w/o extension) */ + if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.')) + { + /* Yes they do */ + return TRUE; + } + + /* Strings don't match, return FALSE */ + return FALSE; +} + +BOOLEAN +WinLdrpBindImportName(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PVOID DllBase, + IN PVOID ImageBase, + IN PIMAGE_THUNK_DATA ThunkData, + IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, + IN ULONG ExportSize, + IN BOOLEAN ProcessForwards) +{ + ULONG Ordinal; + PULONG NameTable, FunctionTable; + PUSHORT OrdinalTable; + LONG High, Low, Middle, Result; + ULONG Hint; + + //DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X, ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n", + // DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize, ProcessForwards)); + + /* Check passed DllBase param */ + if(DllBase == NULL) + { + DbgPrint((DPRINT_WINDOWS, "WARNING: DllBase == NULL!\n")); + return FALSE; + } + + /* Convert all non-critical pointers to PA from VA */ + ThunkData = VaToPa(ThunkData); + + /* Is the reference by ordinal? */ + if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards) + { + /* Yes, calculate the ordinal */ + Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) - (UINT32)ExportDirectory->Base); + //DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): Ordinal %d\n", Ordinal)); + } + else + { + /* It's reference by name, we have to look it up in the export directory */ + if (!ProcessForwards) + { + /* AddressOfData in thunk entry will become a virtual address (from relative) */ + //DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): ThunkData->u1.AOD was %p\n", ThunkData->u1.AddressOfData)); + ThunkData->u1.AddressOfData = + (PIMAGE_IMPORT_BY_NAME)RVA(ImageBase, ThunkData->u1.AddressOfData); + //DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): ThunkData->u1.AOD became %p\n", ThunkData->u1.AddressOfData)); + } + + /* Get pointers to Name and Ordinal tables (RVA -> VA) */ + NameTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames)); + OrdinalTable = (PUSHORT)VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals)); + + //DbgPrint((DPRINT_WINDOWS, "NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n", + // NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals)); + + /* Get the hint, convert it to a physical pointer */ + Hint = ((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Hint; + //DbgPrint((DPRINT_WINDOWS, "HintIndex %d\n", Hint)); + + /* If Hint is less than total number of entries in the export directory, + and import name == export name, then we can just get it from the OrdinalTable */ + if ( + (Hint < ExportDirectory->NumberOfNames) && + ( + strcmp(VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]), + (PCHAR)VaToPa( RVA(DllBase, NameTable[Hint])) ) == 0 + ) + ) + { + Ordinal = OrdinalTable[Hint]; + //DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): Ordinal %d\n", Ordinal)); + } + else + { + /* It's not the easy way, we have to lookup import name in the name table. + Let's use a binary search for this task. */ + + //DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName() looking up the import name using binary search...\n")); + + /* Low boundary is set to 0, and high boundary to the maximum index */ + Low = 0; + High = ExportDirectory->NumberOfNames - 1; + + /* Perform a binary-search loop */ + while (High >= Low) + { + /* Divide by 2 by shifting to the right once */ + Middle = (Low + High) >> 1; + + /* Compare the names */ + Result = strcmp(VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]), + (PCHAR)VaToPa(RVA(DllBase, NameTable[Middle]))); + + DbgPrint((DPRINT_WINDOWS, "Binary search: comparing Import '__', Export '%s'\n", + /*VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),*/ + (PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])))); + + DbgPrint((DPRINT_WINDOWS, "TE->u1.AOD %p, fulladdr %p\n", + ThunkData->u1.AddressOfData, + ((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name )); + + + /* Depending on result of strcmp, perform different actions */ + if (Result < 0) + { + /* Adjust top boundary */ + High = Middle - 1; + } + else if (Result > 0) + { + /* Adjust bottom boundary */ + Low = Middle + 1; + } + else + { + /* Yay, found it! */ + break; + } + } + + /* If high boundary is less than low boundary, then no result found */ + if (High < Low) + { + //Print(L"Error in binary search\n"); + DbgPrint((DPRINT_WINDOWS, "Error in binary search!\n")); + return FALSE; + } + + /* Everything allright, get the ordinal */ + Ordinal = OrdinalTable[Middle]; + + //DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName() found Ordinal %d\n", Ordinal)); + } + } + + /* Check ordinal number for validity! */ + if (Ordinal >= ExportDirectory->NumberOfFunctions) + { + DbgPrint((DPRINT_WINDOWS, "Ordinal number is invalid!\n")); + return FALSE; + } + + /* Get a pointer to the function table */ + FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions)); + + /* Save a pointer to the function */ + ThunkData->u1.Function = (PULONG)RVA(DllBase, FunctionTable[Ordinal]); + + /* Is it a forwarder? (function pointer isn't within the export directory) */ + if (((ULONG)VaToPa(ThunkData->u1.Function) > (ULONG)ExportDirectory) && + ((ULONG)VaToPa(ThunkData->u1.Function) < ((ULONG)ExportDirectory + ExportSize))) + { + PLDR_DATA_TABLE_ENTRY DataTableEntry; + CHAR ForwardDllName[255]; + PIMAGE_EXPORT_DIRECTORY RefExportDirectory; + ULONG RefExportSize; + + /* Save the name of the forward dll */ + RtlCopyMemory(ForwardDllName, (PCHAR)VaToPa(ThunkData->u1.Function), sizeof(ForwardDllName)); + + /* Strip out its extension */ + *strchr(ForwardDllName,'.') = '\0'; + + DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): ForwardDllName %s\n", ForwardDllName)); + if (!WinLdrCheckForLoadedDll(WinLdrBlock, ForwardDllName, &DataTableEntry)) + { + /* We can't continue if DLL couldn't be loaded, so bomb out with an error */ + //Print(L"Error loading DLL!\n"); + DbgPrint((DPRINT_WINDOWS, "Error loading DLL!\n")); + return FALSE; + } + + /* Get pointer to the export directory of loaded DLL */ + RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY) + RtlImageDirectoryEntryToData(VaToPa(DataTableEntry->DllBase), + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &RefExportSize); + + /* Fail if it's NULL */ + if (RefExportDirectory) + { + UCHAR Buffer[128]; + IMAGE_THUNK_DATA RefThunkData; + PIMAGE_IMPORT_BY_NAME ImportByName; + PCHAR ImportName; + BOOLEAN Status; + + /* Get pointer to the import name */ + ImportName = strchr((PCHAR)VaToPa(ThunkData->u1.Function), '.') + 1; + + /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */ + ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer; + + /* Fill the name with the import name */ + RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1); + + /* Set Hint to 0 */ + ImportByName->Hint = 0; + + /* And finally point ThunkData's AddressOfData to that structure */ + RefThunkData.u1.AddressOfData = ImportByName; + + /* And recursively call ourselves */ + Status = WinLdrpBindImportName( + WinLdrBlock, + DataTableEntry->DllBase, + ImageBase, + &RefThunkData, + RefExportDirectory, + RefExportSize, + TRUE); + + /* Fill out the ThunkData with data from RefThunkData */ + ThunkData->u1 = RefThunkData.u1; + + /* Return what we got from the recursive call */ + return Status; + } + else + { + /* Fail if ExportDirectory is NULL */ + return FALSE; + } + } + + /* Success! */ + return TRUE; +} + +BOOLEAN +WinLdrpLoadAndScanReferencedDll(PLOADER_PARAMETER_BLOCK WinLdrBlock, + PCCH DirectoryPath, + PCH ImportName, + PLDR_DATA_TABLE_ENTRY *DataTableEntry) +{ + CHAR FullDllName[256]; + BOOLEAN Status; + PVOID BasePA; + + /* Prepare the full path to the file to be loaded */ + strcpy(FullDllName, DirectoryPath); + strcat(FullDllName, ImportName); + + DbgPrint((DPRINT_WINDOWS, "Loading referenced DLL: %s\n", FullDllName)); + //Print(L"Loading referenced DLL: %s\n", FullDllName); + + /* Load the image */ + Status = WinLdrLoadImage(FullDllName, LoaderHalCode, &BasePA); + + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage() failed\n")); + return Status; + } + + /* Allocate DTE for newly loaded DLL */ + Status = WinLdrAllocateDataTableEntry(WinLdrBlock, + ImportName, + FullDllName, + BasePA, + DataTableEntry); + + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, + "WinLdrAllocateDataTableEntry() failed with Status=0x%X\n", Status)); + return Status; + } + + /* Scan its dependencies too */ + DbgPrint((DPRINT_WINDOWS, + "WinLdrScanImportDescriptorTable() calling ourselves for %S\n", + VaToPa((*DataTableEntry)->BaseDllName.Buffer))); + Status = WinLdrScanImportDescriptorTable(WinLdrBlock, DirectoryPath, *DataTableEntry); + + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, + "WinLdrScanImportDescriptorTable() failed with Status=0x%X\n", Status)); + return Status; + } + + return TRUE; +} + +BOOLEAN +WinLdrpScanImportAddressTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PVOID DllBase, + IN PVOID ImageBase, + IN PIMAGE_THUNK_DATA ThunkData) +{ + PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; + BOOLEAN Status; + ULONG ExportSize; + + DbgPrint((DPRINT_WINDOWS, "WinLdrpScanImportAddressTable(): DllBase 0x%X, " + "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData)); + + /* Obtain the export table from the DLL's base */ + if (DllBase == NULL) + { + //Print(L"Error, DllBase == NULL!\n"); + return FALSE; + } + else + { + ExportDirectory = + (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(VaToPa(DllBase), + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ExportSize); + } + + DbgPrint((DPRINT_WINDOWS, "WinLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory)); + + /* If pointer to Export Directory is */ + if (ExportDirectory == NULL) + return FALSE; + + /* Go through each entry in the thunk table and bind it */ + while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != NULL) + { + /* Bind it */ + Status = WinLdrpBindImportName( + WinLdrBlock, + DllBase, + ImageBase, + ThunkData, + ExportDirectory, + ExportSize, + FALSE); + + /* Move to the next entry */ + ThunkData++; + + /* Return error if binding was unsuccessful */ + if (!Status) + return Status; + } + + /* Return success */ + return TRUE; +} diff --git a/windows/winldr.c b/windows/winldr.c index 33e51b105bc..b5bbf1acb2f 100644 --- a/windows/winldr.c +++ b/windows/winldr.c @@ -45,34 +45,49 @@ 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) +//TODO: Move to arch-independent hardware.c file +PVOID +HwCreateComponentResources(PCONFIGURATION_COMPONENT Component, + ULONG DeviceDataLength, + PVOID DeviceData) { - PCONFIGURATION_COMPONENT_DATA ConfigurationRoot; - PCONFIGURATION_COMPONENT Component; - PCONFIGURATION_COMPONENT_DATA /*CurrentEntry,*/ PreviousEntry, AdapterEntry; - BOOLEAN IsNextEntryChild; + return NULL; +} + +//TODO: Move to arch-independent hardware.c file +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)); + //LoaderBlock->ConfigurationRoot = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA)); + //RtlZeroMemory(LoaderBlock->ConfigurationRoot, sizeof(CONFIGURATION_COMPONENT_DATA)); /* Fill root == SystemClass */ - ConfigurationRoot = LoaderBlock->ConfigurationRoot; - Component = &LoaderBlock->ConfigurationRoot->ComponentEntry; + //ConfigurationRoot = LoaderBlock->ConfigurationRoot; + //Component = &LoaderBlock->ConfigurationRoot->ComponentEntry; - Component->Class = SystemClass; - Component->Type = MaximumType; - Component->Version = 0; // FIXME: ? - Component->Key = 0; - Component->AffinityMask = 0; + //Component->Class = SystemClass; + //Component->Type = MaximumType; + //Component->Version = 0; // FIXME: ? + //Component->ConfigurationDataLength = 0; + //Component->Key = 0; + //Component->AffinityMask = 0; - IsNextEntryChild = TRUE; - PreviousEntry = ConfigurationRoot; + //Component->Identifier = 0; + //Component->IdentifierLength = 0; + + + //IsNextEntryChild = TRUE; + //PreviousEntry = ConfigurationRoot; /* Enumerate all PCI buses */ - AdapterEntry = ConfigurationRoot; + //AdapterEntry = ConfigurationRoot; /* TODO: Disk Geometry */ /* TODO: Keyboard */ @@ -118,12 +133,12 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock) VOID WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock) { - //CHAR Options[] = "/CRASHDEBUG /DEBUGPORT=COM1 /BAUDRATE=115200"; - CHAR Options[] = "/NODEBUG"; + CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200"; + //CHAR Options[] = "/NODEBUG"; 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)"; + CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)"; + CHAR ArcHal[] = "multi(0)disk(0)rdisk(0)partition(1)"; ULONG i; PLOADER_PARAMETER_EXTENSION Extension; @@ -165,15 +180,20 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock) PARC_DISK_SIGNATURE ArcDiskInfo; /* Get the ARC structure */ - ArcDiskInfo = &BldrDiskInfo[i]; + ArcDiskInfo = (PARC_DISK_SIGNATURE)MmAllocateMemory(sizeof(ARC_DISK_SIGNATURE));//&BldrDiskInfo[i]; + RtlZeroMemory(ArcDiskInfo, sizeof(ARC_DISK_SIGNATURE)); /* Copy the data over */ ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature; ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum; /* Copy the ARC Name */ + //ArcDiskInfo->ArcName = (PCHAR)MmAllocateMemory(sizeof(CHAR)*256); strcpy(BldrArcNames[i], reactos_arc_disk_info[i].ArcName); - ArcDiskInfo->ArcName = BldrArcNames[i]; + ArcDiskInfo->ArcName = (PCHAR)PaToVa(BldrArcNames[i]); + + /* Mark partition table as valid */ + ArcDiskInfo->ValidPartitionTable = TRUE; /* Insert into the list */ InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead, @@ -187,16 +207,17 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock) /* Create configuration entries */ InitializeHWConfig(LoaderBlock); - /* Convert all DTE into virtual addresses */ - //TODO: !!! - + /* Convert all list's to Virtual address */ + + /* Convert all DTE into virtual addresses */ List_PaToVa(&LoaderBlock->LoadOrderListHead); /* this one will be converted right before switching to virtual paging mode */ //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead); + /* Convert list of boot drivers */ List_PaToVa(&LoaderBlock->BootDriverListHead); /* Initialize Extension now */ @@ -232,7 +253,7 @@ void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock, //LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType? /* Allocate 2 pages for PCR */ - Pcr = (ULONG_PTR)MmAllocateMemory(2 * MM_PAGE_SIZE); + Pcr = (ULONG_PTR)MmAllocateMemoryWithType(2 * MM_PAGE_SIZE, LoaderStartupPcrPage); *PcrBasePage = Pcr >> MM_PAGE_SHIFT; if (Pcr == 0) @@ -245,7 +266,7 @@ void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock, TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1); TssPages = TssSize / MM_PAGE_SIZE; - Tss = (ULONG_PTR)MmAllocateMemory(TssSize); + Tss = (ULONG_PTR)MmAllocateMemoryWithType(TssSize, LoaderMemoryData); *TssBasePage = Tss >> MM_PAGE_SHIFT; @@ -303,7 +324,7 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock, // It's not loaded, we have to load it sprintf(FullPath,"%s%wZ", BootPath, FilePath); - Status = WinLdrLoadImage(FullPath, &DriverBase); + Status = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase); if (!Status) return FALSE; @@ -346,8 +367,8 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock, { 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)); + DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath, + BootDriver->DataTableEntry, &BootDriver->RegistryPath)); // Paths are relative (FIXME: Are they always relative?) @@ -363,6 +384,10 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock, return FALSE; } + // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore + BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer); + BootDriver->DataTableEntry = PaToVa(BootDriver->DataTableEntry); + NextBd = BootDriver->ListEntry.Flink; } @@ -421,9 +446,6 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) return; } - /* Detect hardware */ - MachHwDetect(); - UiDrawStatusText("Loading..."); /* Try to open system drive */ @@ -444,16 +466,19 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) // Allocate and minimalistic-initialize LPB AllocateAndInitLPB(&LoaderBlock); + // Detect hardware + MachHwDetect(&LoaderBlock->ConfigurationRoot); + // Load kernel strcpy(FileName, BootPath); strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE"); - Status = WinLdrLoadImage(FileName, &NtosBase); + Status = WinLdrLoadImage(FileName, LoaderSystemCode, &NtosBase); DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase)); // Load HAL strcpy(FileName, BootPath); strcat(FileName, "SYSTEM32\\HAL.DLL"); - Status = WinLdrLoadImage(FileName, &HalBase); + Status = WinLdrLoadImage(FileName, LoaderHalCode, &HalBase); DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase)); // Load kernel-debugger support dll @@ -461,7 +486,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) { strcpy(FileName, BootPath); strcat(FileName, "SYSTEM32\\KDCOM.DLL"); - Status = WinLdrLoadImage(FileName, &KdComBase); + Status = WinLdrLoadImage(FileName, LoaderBootDriver, &KdComBase); DbgPrint((DPRINT_WINDOWS, "KdCom loaded with status %d at %p\n", Status, KdComBase)); } @@ -503,6 +528,10 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) LoaderBlockVA = PaToVa(LoaderBlock); + /* "Stop all motors", change videomode */ + DiskStopFloppyMotor(); + MachVideoPrepareForReactOS(); + /* Debugging... */ //DumpMemoryAllocMap(); @@ -523,7 +552,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) asm("jmp test1\n"); asm(".att_syntax\n");*/ - + /* Pass control */ (*KiSystemStartup)(LoaderBlockVA); return; diff --git a/windows/wlmemory.c b/windows/wlmemory.c index 82511c71ae9..1ecaf0d43cf 100644 --- a/windows/wlmemory.c +++ b/windows/wlmemory.c @@ -28,33 +28,31 @@ extern ULONG TotalNLSSize; #define HYPER_SPACE_ENTRY 0x300 -//TODO: Check if this is correct PCHAR MemTypeDesc[] = { - "ExceptionBlock ", - "SystemBlock ", + "ExceptionBlock ", // ? + "SystemBlock ", // ? "Free ", - "Bad ", - "LoadedProgram ", - "FirmwareTemporary ", - "FirmwarePermanent ", - "OsloaderHeap ", - "OsloaderStack ", + "Bad ", // used + "LoadedProgram ", // == Free + "FirmwareTemporary ", // == Free + "FirmwarePermanent ", // == Bad + "OsloaderHeap ", // used + "OsloaderStack ", // == Free "SystemCode ", "HalCode ", - "BootDriver ", - "ConsoleInDriver ", - "ConsoleOutDriver ", - "StartupDpcStack ", - "StartupKernelStack", - "StartupPanicStack ", - "StartupPcrPage ", - "StartupPdrPage ", - "RegistryData ", - "MemoryData ", - "NlsData ", - "SpecialMemory ", - "BBTMemory ", - "Maximum " + "BootDriver ", // not used + "ConsoleInDriver ", // ? + "ConsoleOutDriver ", // ? + "StartupDpcStack ", // ? + "StartupKernelStack", // ? + "StartupPanicStack ", // ? + "StartupPcrPage ", // ? + "StartupPdrPage ", // ? + "RegistryData ", // used + "MemoryData ", // not used + "NlsData ", // used + "SpecialMemory ", // == Bad + "BBTMemory " // == Bad }; VOID @@ -63,8 +61,8 @@ WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); VOID MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, - UINT64 BasePage, - UINT64 PageCount, + ULONG BasePage, + ULONG PageCount, ULONG Type); VOID WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, @@ -138,8 +136,9 @@ MempAllocatePageTables() // Allocate memory block for all these things: // PDE, HAL mapping page table, physical mapping, kernel mapping + // FIXME: PDE+HAL+KernelPTEs == FirmwarePermanent, Physical PTEs = FirmwareTemporary TotalSize = (1+1+NumPageTables*2)*MM_PAGE_SIZE; - Buffer = MmAllocateMemory(TotalSize); + Buffer = MmAllocateMemoryWithType(TotalSize, LoaderFirmwarePermanent); if (Buffer == NULL) { @@ -269,8 +268,8 @@ MempSetupPaging(IN ULONG StartPage, VOID MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, - UINT64 BasePage, - UINT64 PageCount, + ULONG BasePage, + ULONG PageCount, ULONG Type) { BOOLEAN Status; @@ -296,72 +295,32 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, // Check if it's more than the allowed for OS loader // if yes - don't map the pages, just add as FirmwareTemporary // - if (BasePage + PageCount > LOADER_HIGH_ZONE && (Type != LoaderNlsData)) + if (BasePage + PageCount > LOADER_HIGH_ZONE) { Mad[MadCount].MemoryType = LoaderFirmwareTemporary; WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]); MadCount++; - Status = MempSetupPaging(BasePage, PageCount); - if (!Status) - { - DbgPrint((DPRINT_WINDOWS, "Error during WinLdrpSetupPaging\n")); - return; - } return; } - if (BasePage == 0xFFF && PageCount == 1) + // + // Set memory type + // + Mad[MadCount].MemoryType = Type; + + // + // Add descriptor + // + WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]); + MadCount++; + + // + // Map it + // + if (BasePage >= 0x100) { - Mad[MadCount].MemoryType = LoaderSpecialMemory; - - WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]); - MadCount++; - - // - // Map it - // - Status = MempSetupPaging(BasePage, PageCount); - if (!Status) - { - DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n")); - return; - } - } - else if (BasePage == 0 && PageCount == 1) - { - Mad[MadCount].MemoryType = LoaderFirmwarePermanent; - - WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]); - MadCount++; - - // - // Map it - // - Status = MempSetupPaging(BasePage, PageCount); - if (!Status) - { - DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n")); - return; - } - } - else - { - // - // Set memory type - // - Mad[MadCount].MemoryType = Type; - - // - // Add descriptor - // - WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]); - MadCount++; - - // - // Map it - // Status = MempSetupPaging(BasePage, PageCount); if (!Status) { @@ -378,12 +337,11 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, PVOID GdtIdt) { ULONG i, PagesCount; - ULONG LastPageIndex, LastPageType, NtType; + ULONG LastPageIndex, LastPageType; PPAGE_LOOKUP_TABLE_ITEM MemoryMap; ULONG NoEntries; PKTSS Tss; - PVOID NlsBase = VaToPa(((PNLS_DATA_BLOCK)VaToPa(LoaderBlock->NlsData))->AnsiCodePageData); - ULONG NlsBasePage = (ULONG_PTR)NlsBase >> PAGE_SHIFT; + BOOLEAN Status; // // Creating a suitable memory map for the Windows can be tricky, so let's @@ -420,8 +378,15 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, return FALSE; } - DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries, NlsBasePage 0x%X\n", - NoEntries, NlsBasePage)); + DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries\n", NoEntries)); + + // Always contigiously map low 1Mb of memory + Status = MempSetupPaging(0, 0x100); + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging of low 1Mb\n")); + return FALSE; + } // Construct a good memory map from what we've got PagesCount = 1; @@ -430,66 +395,14 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, for(i=1;i NlsBasePage+TotalNLSSize) && (i != NoEntries-1) ) + (i != NoEntries-1) ) { PagesCount++; } - else if (i == NlsBasePage) - { - // This is NLS data, map it accordingly - // It's VERY important for NT kernel - it calculates size of NLS - // tables based on NlsData memory type descriptors! - - // Firstly map what we already have (if we have any) - // Convert mem types - if (LastPageType == 0) - NtType = LoaderFree; - else if (LastPageType != 0 && LastPageType != 1) - NtType = LoaderFirmwarePermanent; - else if (LastPageType == 1) - NtType = LoaderSystemCode; - else - NtType = LoaderFirmwarePermanent; - - if (PagesCount > 0) - MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType); - - // Then map nls data - MempAddMemoryBlock(LoaderBlock, NlsBasePage, TotalNLSSize, LoaderNlsData); - - // skip them - i += TotalNLSSize; - - // Reset our counter vars - LastPageIndex = i; - LastPageType = MemoryMap[i].PageAllocated; - PagesCount = 1; - - continue; - } else { // Add the resulting region - - // Convert mem types - if (LastPageType == 0) - { - NtType = LoaderFree; - } - else if (LastPageType != 0 && LastPageType != 1) - { - NtType = LoaderFirmwarePermanent; - } - else if (LastPageType == 1) - { - NtType = LoaderSystemCode; - } - else - { - NtType = LoaderFirmwarePermanent; - } - - MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType); + MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, LastPageType); // Reset our counter vars LastPageIndex = i; diff --git a/windows/wlregistry.c b/windows/wlregistry.c index b7737d8adfb..3640a6a8b48 100644 --- a/windows/wlregistry.c +++ b/windows/wlregistry.c @@ -74,8 +74,9 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, } /* 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); + HiveDataPhysical = (ULONG_PTR)MmAllocateMemoryWithType( + MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT, + LoaderRegistryData); if (HiveDataPhysical == 0) { @@ -143,6 +144,14 @@ BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, // Scan registry and prepare boot drivers list WinLdrScanRegistry(LoaderBlock, DirectoryPath); + // Add boot filesystem driver to the list + //FIXME: Use corresponding driver instead of hardcoding + Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead, + L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", + NULL, + L"fastfat"); + + // Get names of NLS files Status = WinLdrGetNLSNames(AnsiName, OemName, LangName); if (!Status) @@ -333,7 +342,7 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, /* Store it for later marking the pages as NlsData type */ TotalNLSSize = TotalSize; - NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); + NlsDataBase = (ULONG_PTR)MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData); if (NlsDataBase == 0) goto Failure; @@ -564,7 +573,7 @@ WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n")); } else { - //DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n", + //DbgPrint((DPRINT_WINDOWS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n", // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName)); } } @@ -639,7 +648,7 @@ WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n")); } else { - //DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n", + //DbgPrint((DPRINT_WINDOWS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n", // ServiceName, StartValue, TagValue, DriverGroup, GroupName)); } } @@ -713,9 +722,9 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead, } // Add registry path - PathLength = wcslen(RegistryPath)*sizeof(WCHAR); + PathLength = (wcslen(RegistryPath)+wcslen(ServiceName))*sizeof(WCHAR); BootDriverEntry->RegistryPath.Length = 0; - BootDriverEntry->RegistryPath.MaximumLength = PathLength+sizeof(WCHAR); + BootDriverEntry->RegistryPath.MaximumLength = PathLength;//+sizeof(WCHAR); BootDriverEntry->RegistryPath.Buffer = MmAllocateMemory(PathLength); if (!BootDriverEntry->RegistryPath.Buffer) return FALSE; @@ -724,8 +733,12 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead, if (!NT_SUCCESS(Status)) return FALSE; + Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, ServiceName); + if (!NT_SUCCESS(Status)) + return FALSE; + // Insert entry at top of the list - InsertHeadList(BootDriverListHead, &BootDriverEntry->ListEntry); + InsertTailList(BootDriverListHead, &BootDriverEntry->ListEntry); return TRUE; }