From 02db465a106f8ea4b85fb695e96ba642dea073e3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 11 Oct 2009 17:08:33 +0000 Subject: [PATCH] [freeldr] Rework the ramdisk driver to let it be a full device, instead of a deprecated harddisk which was only available once real harddisks were disabled Add support for /RDPATH switch in WINLDR boot style svn path=/trunk/; revision=43377 --- .../boot/freeldr/freeldr/arch/arm/macharm.c | 8 +- reactos/boot/freeldr/freeldr/disk/ramdisk.c | 196 +++++++++++------- .../boot/freeldr/freeldr/include/ramdisk.h | 6 - .../boot/freeldr/freeldr/reactos/reactos.c | 9 - reactos/boot/freeldr/freeldr/windows/winldr.c | 23 ++ 5 files changed, 144 insertions(+), 98 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/arm/macharm.c b/reactos/boot/freeldr/freeldr/arch/arm/macharm.c index 2dc74fe4dcb..c636a0a9fe0 100644 --- a/reactos/boot/freeldr/freeldr/arch/arm/macharm.c +++ b/reactos/boot/freeldr/freeldr/arch/arm/macharm.c @@ -71,7 +71,6 @@ BOOLEAN ArmDiskGetDriveGeometry(IN ULONG DriveNumber, OUT PGEOMETRY Geometry) { - ASSERT(gRamDiskBase == NULL); return FALSE; } @@ -81,15 +80,13 @@ ArmDiskReadLogicalSectors(IN ULONG DriveNumber, IN ULONG SectorCount, IN PVOID Buffer) { - ASSERT(gRamDiskBase == NULL); return FALSE; } ULONG ArmDiskGetCacheableBlockCount(IN ULONG DriveNumber) { - ASSERT(gRamDiskBase == NULL); - return FALSE; + return 0; } PCONFIGURATION_COMPONENT_DATA @@ -191,12 +188,11 @@ MachInit(IN PCCH CommandLine) MachVtbl.HwDetect = ArmHwDetect; // - // Setup disk I/O routines, switch to ramdisk ones for non-NAND boot + // Setup disk I/O routines // MachVtbl.DiskReadLogicalSectors = ArmDiskReadLogicalSectors; MachVtbl.DiskGetDriveGeometry = ArmDiskGetDriveGeometry; MachVtbl.DiskGetCacheableBlockCount = ArmDiskGetCacheableBlockCount; - RamDiskSwitchFromBios(); // // Now set default disk handling routines -- we don't need to override diff --git a/reactos/boot/freeldr/freeldr/disk/ramdisk.c b/reactos/boot/freeldr/freeldr/disk/ramdisk.c index a5de38acfea..18397d6e962 100644 --- a/reactos/boot/freeldr/freeldr/disk/ramdisk.c +++ b/reactos/boot/freeldr/freeldr/disk/ramdisk.c @@ -1,9 +1,10 @@ /* * PROJECT: ReactOS Boot Loader * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: boot/freeldr/arch/i386/ramdisk.c + * FILE: boot/freeldr/freeldr/disk/ramdisk.c * PURPOSE: Implements routines to support booting from a RAM Disk * PROGRAMMERS: ReactOS Portable Systems Group + * Hervé Poussineau */ /* INCLUDES *******************************************************************/ @@ -16,78 +17,108 @@ PVOID gRamDiskBase; ULONG gRamDiskSize; +ULONG gRamDiskOffset; /* FUNCTIONS ******************************************************************/ -FORCEINLINE -PVOID -RamDiskGetDataAtOffset(IN PVOID Offset) +static LONG RamDiskClose(ULONG FileId) { // - // Return data from our RAM Disk + // Nothing to do // - ASSERT(((ULONG_PTR)gRamDiskBase + (ULONG_PTR)Offset) < - ((ULONG_PTR)gRamDiskBase + (ULONG_PTR)gRamDiskSize)); - return (PVOID)((ULONG_PTR)gRamDiskBase + (ULONG_PTR)(Offset)); + return ESUCCESS; } -ULONG -RamDiskGetCacheableBlockCount(IN ULONG Reserved) +static LONG RamDiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information) { // - // Allow 32KB transfers (64 sectors), emulating BIOS LBA + // Give current seek offset and ram disk size to caller // - ASSERT(Reserved == 0x49); - return 64; + RtlZeroMemory(Information, sizeof(FILEINFORMATION)); + Information->EndingAddress.LowPart = gRamDiskSize; + Information->CurrentAddress.LowPart = gRamDiskOffset; + + return ESUCCESS; } -BOOLEAN -RamDiskGetDriveGeometry(IN ULONG Reserved, - OUT PGEOMETRY Geometry) +static LONG RamDiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) { // - // Should never be called when the caller expects valid Geometry! + // Always return success, as contents are already in memory // - ASSERT(Reserved == 0x49); - return TRUE; + return ESUCCESS; } -BOOLEAN -RamDiskReadLogicalSectors(IN ULONG Reserved, - IN ULONGLONG SectorNumber, - IN ULONG SectorCount, - IN PVOID Buffer) +static LONG RamDiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) { PVOID StartAddress; - ULONG Length; - ASSERT(Reserved == 0x49); // - // Get actual pointers and lengths + // Get actual pointer // - StartAddress = (PVOID)((ULONG_PTR)SectorNumber * 512); - Length = SectorCount * 512; - + StartAddress = (PVOID)((ULONG_PTR)gRamDiskBase + gRamDiskOffset); + // // Don't allow reads past our image // - if (((ULONG_PTR)StartAddress + Length) > gRamDiskSize) return FALSE; + if (gRamDiskOffset + N > gRamDiskSize) + { + *Count = 0; + return EIO; + } // // Do the read // - RtlCopyMemory(Buffer, RamDiskGetDataAtOffset(StartAddress), Length); - return TRUE; + RtlCopyMemory(Buffer, StartAddress, N); + *Count = N; + + return ESUCCESS; } +static LONG RamDiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) +{ + // + // Only accept absolute mode now + // + if (SeekMode != SeekAbsolute) + return EINVAL; + + // + // Check if we're in the ramdisk + // + if (Position->HighPart != 0) + return EINVAL; + if (Position->LowPart >= gRamDiskSize) + return EINVAL; + + // + // OK, remember seek position + // + gRamDiskOffset = Position->LowPart; + + return ESUCCESS; +} + +static const DEVVTBL RamDiskVtbl = { + RamDiskClose, + RamDiskGetFileInformation, + RamDiskOpen, + RamDiskRead, + RamDiskSeek, +}; + VOID NTAPI RamDiskLoadVirtualFile(IN PCHAR FileName) { - PFILE RamFile; - ULONG TotalRead, ChunkSize; - PCHAR MsgBuffer = "Loading ramdisk..."; + ULONG RamFile; + ULONG TotalRead, ChunkSize, Count; + PCHAR MsgBuffer = "Loading ramdisk..."; ULONG PercentPerChunk, Percent; + FILEINFORMATION Information; + LARGE_INTEGER Position; + LONG ret; // // Display progress @@ -95,25 +126,45 @@ RamDiskLoadVirtualFile(IN PCHAR FileName) UiDrawProgressBarCenter(1, 100, MsgBuffer); // - // Try opening the ramdisk file (this assumes the boot volume was opened) - // - RamFile = FsOpenFile(FileName); - if (RamFile) + // Try opening the ramdisk file + // + ret = ArcOpen(FileName, OpenReadOnly, &RamFile); + if (ret == ESUCCESS) { // // Get the file size // - gRamDiskSize = FsGetFileSize(RamFile); - if (!gRamDiskSize) return; - + ret = ArcGetFileInformation(RamFile, &Information); + if (ret != ESUCCESS) + { + ArcClose(RamFile); + return; + } + + // + // For now, limit RAM disks to 4GB + // + if (Information.EndingAddress.HighPart != 0) + { + UiMessageBox("RAM disk too big\n"); + ArcClose(RamFile); + return; + } + gRamDiskSize = Information.EndingAddress.LowPart; + // // Allocate memory for it // ChunkSize = 8 * 1024 * 1024; Percent = PercentPerChunk = 100 / (gRamDiskSize / ChunkSize); gRamDiskBase = MmAllocateMemory(gRamDiskSize); - if (!gRamDiskBase) return; - + if (!gRamDiskBase) + { + UiMessageBox("Failed to allocate memory for RAM disk\n"); + ArcClose(RamFile); + return; + } + // // Read it in chunks // @@ -139,43 +190,34 @@ RamDiskLoadVirtualFile(IN PCHAR FileName) // // Copy the contents // - - if (!FsReadFile(RamFile, - ChunkSize, - NULL, - (PVOID)((ULONG_PTR)gRamDiskBase + TotalRead))) + Position.HighPart = 0; + Position.LowPart = TotalRead; + ret = ArcSeek(RamFile, &Position, SeekAbsolute); + if (ret == ESUCCESS) { - // - // Fail - // + ret = ArcRead(RamFile, + (PVOID)((ULONG_PTR)gRamDiskBase + TotalRead), + ChunkSize, + &Count); + } + + // + // Check for success + // + if (ret != ESUCCESS || Count != ChunkSize) + { + MmFreeMemory(gRamDiskBase); + gRamDiskBase = NULL; + gRamDiskSize = 0; + ArcClose(RamFile); UiMessageBox("Failed to read ramdisk\n"); + return; } } - } -} -VOID -NTAPI -RamDiskSwitchFromBios(VOID) -{ - extern ULONG BootDrive, BootPartition; + ArcClose(RamFile); - // - // Check if we have a ramdisk, in which case we need to switch routines - // - if (gRamDiskBase) - { - // - // Don't use the BIOS for reads anymore - // - MachVtbl.DiskReadLogicalSectors = RamDiskReadLogicalSectors; - MachVtbl.DiskGetDriveGeometry = RamDiskGetDriveGeometry; - MachVtbl.DiskGetCacheableBlockCount = RamDiskGetCacheableBlockCount; - - // - // Switch to ramdisk boot partition - // - BootDrive = 0x49; - BootPartition = 0; + // Register a new device for the ramdisk + FsRegisterDevice("ramdisk(0)", &RamDiskVtbl); } } diff --git a/reactos/boot/freeldr/freeldr/include/ramdisk.h b/reactos/boot/freeldr/freeldr/include/ramdisk.h index 08378adfb6d..f8338eea396 100644 --- a/reactos/boot/freeldr/freeldr/include/ramdisk.h +++ b/reactos/boot/freeldr/freeldr/include/ramdisk.h @@ -12,12 +12,6 @@ // // Ramdisk Routines // -VOID -NTAPI -RamDiskSwitchFromBios( - VOID -); - VOID NTAPI RamDiskLoadVirtualFile( diff --git a/reactos/boot/freeldr/freeldr/reactos/reactos.c b/reactos/boot/freeldr/freeldr/reactos/reactos.c index 6e52a6855e2..7db4d0e6037 100644 --- a/reactos/boot/freeldr/freeldr/reactos/reactos.c +++ b/reactos/boot/freeldr/freeldr/reactos/reactos.c @@ -746,15 +746,6 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) UiDrawStatusText("Loading..."); - // - // If we have a ramdisk, this will switch to the ramdisk disk routines - // which read from memory instead of using the firmware. This has to be done - // after hardware detection, since hardware detection will require using the - // real routines in order to perform disk-detection (just because we're on a - // ram-boot doesn't mean the user doesn't have actual disks installed too!) - // - RamDiskSwitchFromBios(); - /* Get boot path */ if (strchr(SystemPath, '\\') != NULL) strcpy(szBootPath, strchr(SystemPath, '\\')); diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index 105966137c7..76622ee940d 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -390,6 +390,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion) CHAR FullPath[MAX_PATH], SystemRoot[MAX_PATH], BootPath[MAX_PATH]; CHAR FileName[MAX_PATH]; CHAR BootOptions[256]; + PCHAR File; PCHAR PathSeparator; PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL; BOOLEAN Status; @@ -445,6 +446,28 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion) strcpy(BootOptions, ""); } + // + // Check if a ramdisk file was given + // + File = strstr(BootOptions, "/RDPATH="); + if (File) + { + // + // Copy the file name and everything else after it + // + strcpy(FileName, File + 8); + + // + // Null-terminate + // + *strstr(FileName, " ") = ANSI_NULL; + + // + // Load the ramdisk + // + RamDiskLoadVirtualFile(FileName); + } + /* Let user know we started loading */ UiDrawStatusText("Loading..."); -- 2.17.1