Author: hpoussin
Date: Sun Oct 11 19:08:33 2009
New Revision: 43377
URL:
http://svn.reactos.org/svn/reactos?rev=43377&view=rev
Log:
[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
Modified:
trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c
trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c
trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h
trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c
trunk/reactos/boot/freeldr/freeldr/windows/winldr.c
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c [iso-8859-1] Sun Oct 11 19:08:33
2009
@@ -71,7 +71,6 @@
ArmDiskGetDriveGeometry(IN ULONG DriveNumber,
OUT PGEOMETRY Geometry)
{
- ASSERT(gRamDiskBase == NULL);
return FALSE;
}
@@ -81,15 +80,13 @@
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 @@
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
Modified: trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/disk/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c [iso-8859-1] Sun Oct 11 19:08:33
2009
@@ -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)
-{
- //
- // Return data from our RAM Disk
- //
- ASSERT(((ULONG_PTR)gRamDiskBase + (ULONG_PTR)Offset) <
- ((ULONG_PTR)gRamDiskBase + (ULONG_PTR)gRamDiskSize));
- return (PVOID)((ULONG_PTR)gRamDiskBase + (ULONG_PTR)(Offset));
-}
-
-ULONG
-RamDiskGetCacheableBlockCount(IN ULONG Reserved)
-{
- //
- // Allow 32KB transfers (64 sectors), emulating BIOS LBA
- //
- ASSERT(Reserved == 0x49);
- return 64;
-}
-
-BOOLEAN
-RamDiskGetDriveGeometry(IN ULONG Reserved,
- OUT PGEOMETRY Geometry)
-{
- //
- // Should never be called when the caller expects valid Geometry!
- //
- ASSERT(Reserved == 0x49);
- return TRUE;
-}
-
-BOOLEAN
-RamDiskReadLogicalSectors(IN ULONG Reserved,
- IN ULONGLONG SectorNumber,
- IN ULONG SectorCount,
- IN PVOID Buffer)
+static LONG RamDiskClose(ULONG FileId)
+{
+ //
+ // Nothing to do
+ //
+ return ESUCCESS;
+}
+
+static LONG RamDiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
+{
+ //
+ // Give current seek offset and ram disk size to caller
+ //
+ RtlZeroMemory(Information, sizeof(FILEINFORMATION));
+ Information->EndingAddress.LowPart = gRamDiskSize;
+ Information->CurrentAddress.LowPart = gRamDiskOffset;
+
+ return ESUCCESS;
+}
+
+static LONG RamDiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
+{
+ //
+ // Always return success, as contents are already in memory
+ //
+ return ESUCCESS;
+}
+
+static LONG RamDiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
PVOID StartAddress;
- ULONG Length;
- ASSERT(Reserved == 0x49);
-
- //
- // Get actual pointers and lengths
- //
- StartAddress = (PVOID)((ULONG_PTR)SectorNumber * 512);
- Length = SectorCount * 512;
-
+
+ //
+ // Get actual pointer
+ //
+ 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 @@
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 @@
//
// 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;
}
}
+
+ ArcClose(RamFile);
+
+ // Register a new device for the ramdisk
+ FsRegisterDevice("ramdisk(0)", &RamDiskVtbl);
}
}
-
-VOID
-NTAPI
-RamDiskSwitchFromBios(VOID)
-{
- extern ULONG BootDrive, BootPartition;
-
- //
- // 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;
- }
-}
Modified: trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/inclu…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h [iso-8859-1] Sun Oct 11 19:08:33
2009
@@ -14,12 +14,6 @@
//
VOID
NTAPI
-RamDiskSwitchFromBios(
- VOID
-);
-
-VOID
-NTAPI
RamDiskLoadVirtualFile(
IN PCHAR FileName
);
Modified: trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/react…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c [iso-8859-1] Sun Oct 11 19:08:33
2009
@@ -746,15 +746,6 @@
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, '\\'));
Modified: trunk/reactos/boot/freeldr/freeldr/windows/winldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/winldr.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/winldr.c [iso-8859-1] Sun Oct 11 19:08:33
2009
@@ -390,6 +390,7 @@
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 @@
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...");