[ros-diffs] [ros-arm-bringup] 32128: Implement ramdisk support for FreeLDR (ramdisk.c and ramdisk.h). The implementation is portable across all architectures. We also define a virual ramdisk file (hardcoded name is reactos.img, on the boot volume) for testing ramdisk support on architectures without native ramdisk support (such as x86). This could be $ We introduce two new FreeLDR command-line parameters that should be sent by non-x86 firmware: rdbase and rdsize, and a new freeldr.ini ARC path: ramdisk(0) -- this is compatible with Windows. For compatibility and status output, we use 8MB chunks for reading virtual ramdisk files (a dot is displayed for each additional 8MB chunk). Finally, for code-reuse, the ramdisk implementation will "steal" the BIOS support routines in the arch-vtable and replace them with simple memcpy wrappers. To the disk/filesystem routines in Fre$ For now, only FAT ramdisks have been tested, and a sector size of 512 bytes is implied. We also disable the FAT block cache since it wouldn't make much sense to cache RAM. $lds since the kernel won't get that far for a while.

ros-arm-bringup at svn.reactos.org ros-arm-bringup at svn.reactos.org
Tue Feb 5 02:29:50 CET 2008


Author: ros-arm-bringup
Date: Tue Feb  5 04:29:49 2008
New Revision: 32128

URL: http://svn.reactos.org/svn/reactos?rev=32128&view=rev
Log:
Implement ramdisk support for FreeLDR (ramdisk.c and ramdisk.h). The implementation is portable across all architectures.
We also define a virual ramdisk file (hardcoded name is reactos.img, on the boot volume) for testing ramdisk support on architectures without native ramdisk support (such as x86). This could be $
We introduce two new FreeLDR command-line parameters that should be sent by non-x86 firmware: rdbase and rdsize, and a new freeldr.ini ARC path: ramdisk(0) -- this is compatible with Windows.
For compatibility and status output, we use 8MB chunks for reading virtual ramdisk files (a dot is displayed for each additional 8MB chunk).
Finally, for code-reuse, the ramdisk implementation will "steal" the BIOS support routines in the arch-vtable and replace them with simple memcpy wrappers. To the disk/filesystem routines in Fre$
For now, only FAT ramdisks have been tested, and a sector size of 512 bytes is implied. We also disable the FAT block cache since it wouldn't make much sense to cache RAM.
$lds since the kernel won't get that far for a while.


Added:
    trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c   (with props)
    trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h   (with props)
Modified:
    trunk/reactos/boot/freeldr/freeldr/bootmgr.c
    trunk/reactos/boot/freeldr/freeldr/freeldr.c
    trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild
    trunk/reactos/boot/freeldr/freeldr/include/freeldr.h
    trunk/reactos/boot/freeldr/freeldr/reactos/arcname.c
    trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c

Modified: trunk/reactos/boot/freeldr/freeldr/bootmgr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/bootmgr.c?rev=32128&r1=32127&r2=32128&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/bootmgr.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/bootmgr.c Tue Feb  5 04:29:49 2008
@@ -37,6 +37,14 @@
 		return;
 	}
 
+	//
+	// Check if we have a virtual RAM disk
+	// This is for x86 emulation -- on real hardware, the RAM disk will be
+	// located in one of the hardware memory descriptors as well as on the 
+	// freeldr command-line
+	//
+	RamDiskCheckForVirtualFile();
+
 	if (!IniFileInitialize())
 	{
 		UiMessageBoxCritical("Error initializing .ini file");

Added: trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c?rev=32128&view=auto
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c (added)
+++ trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c Tue Feb  5 04:29:49 2008
@@ -1,0 +1,176 @@
+/*
+ * PROJECT:         ReactOS Boot Loader
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            boot/freeldr/arch/i386/ramdisk.c
+ * PURPOSE:         Implements routines to support booting from a RAM Disk
+ * PROGRAMMERS:     alex at winsiderss.com
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <freeldr.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+PVOID gRamDiskBase;
+ULONG gRamDiskSize;
+extern BOOLEAN gCacheEnabled;
+
+/* 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
+    //
+    return 64;
+}
+
+BOOLEAN
+RamDiskGetDriveGeometry(IN ULONG Reserved,
+                        OUT PGEOMETRY Geometry)
+{
+    //
+    // Should never be called when the caller expects valid Geometry!
+    //
+    return TRUE;
+}
+
+BOOLEAN
+RamDiskReadLogicalSectors(IN ULONG Reserved,
+                          IN ULONGLONG SectorNumber,
+                          IN ULONG SectorCount,
+                          IN PVOID Buffer)
+{
+    PVOID StartAddress;
+    ULONG Length;
+        
+    //
+    // Get actual pointers and lengths
+    //
+    StartAddress = (PVOID)((ULONG)SectorNumber * 512);
+    Length = SectorCount * 512;
+    
+    //
+    // Don't allow reads past our image
+    //
+    if (((ULONG_PTR)StartAddress + Length) > gRamDiskSize) return FALSE;
+
+    //
+    // Do the read
+    //
+    RtlCopyMemory(Buffer, RamDiskGetDataAtOffset(StartAddress), Length);
+    return TRUE;
+}
+
+VOID
+NTAPI
+RamDiskCheckForVirtualFile(VOID)
+{
+    PFILE RamFile;
+    ULONG TotalRead, ChunkSize;
+    
+    //
+    // Try opening the ramdisk file (this assumes the boot volume was opened)
+    //
+    RamFile = FsOpenFile("reactos.img");
+    if (RamFile)
+    {
+        //
+        // Get the file size
+        //
+        gRamDiskSize = FsGetFileSize(RamFile);
+        TuiPrintf("Found virtual ramdisk (%dKB) \n", gRamDiskSize / 1024);
+        if (!gRamDiskSize) return;
+        
+        //
+        // Allocate memory for it
+        //
+        ChunkSize = 8 * 1024 * 1024;
+        gRamDiskBase = MmAllocateMemory(gRamDiskSize);
+        if (!gRamDiskBase) return;
+        
+        //
+        // Read it in chunks
+        //
+        TuiPrintf("Loading ramdisk @ 0x%x...", gRamDiskBase);
+        for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize)
+        {
+            //
+            // Check if we're at the last chunk
+            //
+            if ((gRamDiskSize - TotalRead) < ChunkSize)
+            {
+                //
+                // Only need the actual data required
+                //
+                ChunkSize = gRamDiskSize - TotalRead;
+            }
+            
+            //
+            // Copy the contents
+            //
+            TuiPrintf(".");
+            if (!FsReadFile(RamFile,
+                            ChunkSize,
+                            NULL,
+                            (PVOID)((ULONG_PTR)gRamDiskBase + TotalRead)))
+            {
+                //
+                // Fail
+                //
+                TuiPrintf("Failed to read ramdisk\n");
+            }
+        }
+        TuiPrintf("\n");
+    }
+}
+
+VOID
+NTAPI
+RamDiskSwitchFromBios(VOID)
+{
+    //
+    // 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;
+        
+        //
+        // Also disable cached FAT reads
+        //
+        gCacheEnabled = FALSE;
+    }
+}
+
+VOID
+NTAPI
+RamDiskInit(IN PCHAR CmdLine)
+{
+    //
+    // Get RAM disk parameters
+    //
+    gRamDiskBase = (PVOID)atoi(strstr(CmdLine, "rdbase="));
+    gRamDiskSize = atoi(strstr(CmdLine, "rdsize="));
+}

Propchange: trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/reactos/boot/freeldr/freeldr/disk/ramdisk.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: trunk/reactos/boot/freeldr/freeldr/freeldr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/freeldr.c?rev=32128&r1=32127&r2=32128&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/freeldr.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/freeldr.c Tue Feb  5 04:29:49 2008
@@ -26,6 +26,8 @@
 
 	MachInit(CmdLine);
 
+	RamDiskInit(CmdLine);
+
 	DebugInit();
 
 	DbgPrint((DPRINT_WARNING, "BootMain() called.\n"));

Modified: trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild?rev=32128&r1=32127&r2=32128&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild (original)
+++ trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild Tue Feb  5 04:29:49 2008
@@ -19,6 +19,7 @@
 	<directory name="disk">
 		<file>disk.c</file>
 		<file>partition.c</file>
+		<file>ramdisk.c</file>
 	</directory>
 	<directory name="fs">
 		<file>ext2.c</file>

Modified: trunk/reactos/boot/freeldr/freeldr/include/freeldr.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/freeldr.h?rev=32128&r1=32127&r2=32128&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/freeldr.h (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/freeldr.h Tue Feb  5 04:29:49 2008
@@ -45,6 +45,7 @@
 #include <inffile.h>
 #include <video.h>
 #include <portio.h>
+#include <ramdisk.h>
 /* NDK, needed for ReactOS/Windows loaders */
 #include <ndk/rtlfuncs.h>
 #include <ndk/ldrtypes.h>

Added: trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h?rev=32128&view=auto
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h (added)
+++ trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h Tue Feb  5 04:29:49 2008
@@ -1,0 +1,33 @@
+/*
+ * PROJECT:         ReactOS Boot Loader
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            boot/freeldr/include/ramdisk.h
+ * PURPOSE:         Header file for ramdisk support
+ * PROGRAMMERS:     alex at winsiderss.com
+ */
+
+#ifndef _RAMDISK_
+#define _RAMDISK_
+
+//
+// Ramdisk Routines
+//
+VOID
+NTAPI
+RamDiskInit(
+    IN PCHAR CmdLine
+);
+
+VOID
+NTAPI
+RamDiskSwitchFromBios(
+    VOID
+);
+
+VOID
+NTAPI
+RamDiskCheckForVirtualFile(
+    VOID
+);
+
+#endif

Propchange: trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/reactos/boot/freeldr/freeldr/include/ramdisk.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: trunk/reactos/boot/freeldr/freeldr/reactos/arcname.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/reactos/arcname.c?rev=32128&r1=32127&r2=32128&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/reactos/arcname.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/arcname.c Tue Feb  5 04:29:49 2008
@@ -24,6 +24,25 @@
 BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, ULONG* BootDrive, ULONG* BootPartition)
 {
 	char *p;
+
+	//
+	// Detect ramdisk path
+	//
+	if (_strnicmp(ArcPath, "ramdisk(0)", 10) == 0)
+	{
+		//
+		// Magic value for ramdisks
+		//
+		*BootDrive = 0x49;
+		*BootPartition = 1;
+
+		//
+		// Get the path
+		//
+		p = ArcPath + 11;
+		strcpy(BootPath, p);
+		return TRUE;
+	}
 
 	if (_strnicmp(ArcPath, "multi(0)disk(0)", 15) != 0)
 		return FALSE;

Modified: trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c?rev=32128&r1=32127&r2=32128&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c Tue Feb  5 04:29:49 2008
@@ -707,6 +707,15 @@
 
 	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();
+
 	/*
 	 * Try to open system drive
 	 */




More information about the Ros-diffs mailing list