mirror of
https://github.com/reactos/reactos.git
synced 2024-08-13 06:37:06 +00:00
[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
This commit is contained in:
parent
84625e3ee4
commit
02db465a10
|
@ -71,7 +71,6 @@ BOOLEAN
|
||||||
ArmDiskGetDriveGeometry(IN ULONG DriveNumber,
|
ArmDiskGetDriveGeometry(IN ULONG DriveNumber,
|
||||||
OUT PGEOMETRY Geometry)
|
OUT PGEOMETRY Geometry)
|
||||||
{
|
{
|
||||||
ASSERT(gRamDiskBase == NULL);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,15 +80,13 @@ ArmDiskReadLogicalSectors(IN ULONG DriveNumber,
|
||||||
IN ULONG SectorCount,
|
IN ULONG SectorCount,
|
||||||
IN PVOID Buffer)
|
IN PVOID Buffer)
|
||||||
{
|
{
|
||||||
ASSERT(gRamDiskBase == NULL);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
ArmDiskGetCacheableBlockCount(IN ULONG DriveNumber)
|
ArmDiskGetCacheableBlockCount(IN ULONG DriveNumber)
|
||||||
{
|
{
|
||||||
ASSERT(gRamDiskBase == NULL);
|
return 0;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PCONFIGURATION_COMPONENT_DATA
|
PCONFIGURATION_COMPONENT_DATA
|
||||||
|
@ -191,12 +188,11 @@ MachInit(IN PCCH CommandLine)
|
||||||
MachVtbl.HwDetect = ArmHwDetect;
|
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.DiskReadLogicalSectors = ArmDiskReadLogicalSectors;
|
||||||
MachVtbl.DiskGetDriveGeometry = ArmDiskGetDriveGeometry;
|
MachVtbl.DiskGetDriveGeometry = ArmDiskGetDriveGeometry;
|
||||||
MachVtbl.DiskGetCacheableBlockCount = ArmDiskGetCacheableBlockCount;
|
MachVtbl.DiskGetCacheableBlockCount = ArmDiskGetCacheableBlockCount;
|
||||||
RamDiskSwitchFromBios();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now set default disk handling routines -- we don't need to override
|
// Now set default disk handling routines -- we don't need to override
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS Boot Loader
|
* PROJECT: ReactOS Boot Loader
|
||||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
* 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
|
* PURPOSE: Implements routines to support booting from a RAM Disk
|
||||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||||
|
* Hervé Poussineau
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
|
@ -16,78 +17,108 @@
|
||||||
|
|
||||||
PVOID gRamDiskBase;
|
PVOID gRamDiskBase;
|
||||||
ULONG gRamDiskSize;
|
ULONG gRamDiskSize;
|
||||||
|
ULONG gRamDiskOffset;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
FORCEINLINE
|
static LONG RamDiskClose(ULONG FileId)
|
||||||
PVOID
|
|
||||||
RamDiskGetDataAtOffset(IN PVOID Offset)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Return data from our RAM Disk
|
// Nothing to do
|
||||||
//
|
//
|
||||||
ASSERT(((ULONG_PTR)gRamDiskBase + (ULONG_PTR)Offset) <
|
return ESUCCESS;
|
||||||
((ULONG_PTR)gRamDiskBase + (ULONG_PTR)gRamDiskSize));
|
|
||||||
return (PVOID)((ULONG_PTR)gRamDiskBase + (ULONG_PTR)(Offset));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
static LONG RamDiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
|
||||||
RamDiskGetCacheableBlockCount(IN ULONG Reserved)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Allow 32KB transfers (64 sectors), emulating BIOS LBA
|
// Give current seek offset and ram disk size to caller
|
||||||
//
|
//
|
||||||
ASSERT(Reserved == 0x49);
|
RtlZeroMemory(Information, sizeof(FILEINFORMATION));
|
||||||
return 64;
|
Information->EndingAddress.LowPart = gRamDiskSize;
|
||||||
|
Information->CurrentAddress.LowPart = gRamDiskOffset;
|
||||||
|
|
||||||
|
return ESUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
static LONG RamDiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
|
||||||
RamDiskGetDriveGeometry(IN ULONG Reserved,
|
|
||||||
OUT PGEOMETRY Geometry)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Should never be called when the caller expects valid Geometry!
|
// Always return success, as contents are already in memory
|
||||||
//
|
//
|
||||||
ASSERT(Reserved == 0x49);
|
return ESUCCESS;
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
static LONG RamDiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
|
||||||
RamDiskReadLogicalSectors(IN ULONG Reserved,
|
|
||||||
IN ULONGLONG SectorNumber,
|
|
||||||
IN ULONG SectorCount,
|
|
||||||
IN PVOID Buffer)
|
|
||||||
{
|
{
|
||||||
PVOID StartAddress;
|
PVOID StartAddress;
|
||||||
ULONG Length;
|
|
||||||
ASSERT(Reserved == 0x49);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get actual pointers and lengths
|
// Get actual pointer
|
||||||
//
|
//
|
||||||
StartAddress = (PVOID)((ULONG_PTR)SectorNumber * 512);
|
StartAddress = (PVOID)((ULONG_PTR)gRamDiskBase + gRamDiskOffset);
|
||||||
Length = SectorCount * 512;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Don't allow reads past our image
|
// 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
|
// Do the read
|
||||||
//
|
//
|
||||||
RtlCopyMemory(Buffer, RamDiskGetDataAtOffset(StartAddress), Length);
|
RtlCopyMemory(Buffer, StartAddress, N);
|
||||||
return TRUE;
|
*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
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
RamDiskLoadVirtualFile(IN PCHAR FileName)
|
RamDiskLoadVirtualFile(IN PCHAR FileName)
|
||||||
{
|
{
|
||||||
PFILE RamFile;
|
ULONG RamFile;
|
||||||
ULONG TotalRead, ChunkSize;
|
ULONG TotalRead, ChunkSize, Count;
|
||||||
PCHAR MsgBuffer = "Loading ramdisk...";
|
PCHAR MsgBuffer = "Loading ramdisk...";
|
||||||
ULONG PercentPerChunk, Percent;
|
ULONG PercentPerChunk, Percent;
|
||||||
|
FILEINFORMATION Information;
|
||||||
|
LARGE_INTEGER Position;
|
||||||
|
LONG ret;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Display progress
|
// Display progress
|
||||||
|
@ -95,25 +126,45 @@ RamDiskLoadVirtualFile(IN PCHAR FileName)
|
||||||
UiDrawProgressBarCenter(1, 100, MsgBuffer);
|
UiDrawProgressBarCenter(1, 100, MsgBuffer);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Try opening the ramdisk file (this assumes the boot volume was opened)
|
// Try opening the ramdisk file
|
||||||
//
|
//
|
||||||
RamFile = FsOpenFile(FileName);
|
ret = ArcOpen(FileName, OpenReadOnly, &RamFile);
|
||||||
if (RamFile)
|
if (ret == ESUCCESS)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Get the file size
|
// Get the file size
|
||||||
//
|
//
|
||||||
gRamDiskSize = FsGetFileSize(RamFile);
|
ret = ArcGetFileInformation(RamFile, &Information);
|
||||||
if (!gRamDiskSize) return;
|
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
|
// Allocate memory for it
|
||||||
//
|
//
|
||||||
ChunkSize = 8 * 1024 * 1024;
|
ChunkSize = 8 * 1024 * 1024;
|
||||||
Percent = PercentPerChunk = 100 / (gRamDiskSize / ChunkSize);
|
Percent = PercentPerChunk = 100 / (gRamDiskSize / ChunkSize);
|
||||||
gRamDiskBase = MmAllocateMemory(gRamDiskSize);
|
gRamDiskBase = MmAllocateMemory(gRamDiskSize);
|
||||||
if (!gRamDiskBase) return;
|
if (!gRamDiskBase)
|
||||||
|
{
|
||||||
|
UiMessageBox("Failed to allocate memory for RAM disk\n");
|
||||||
|
ArcClose(RamFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Read it in chunks
|
// Read it in chunks
|
||||||
//
|
//
|
||||||
|
@ -139,43 +190,34 @@ RamDiskLoadVirtualFile(IN PCHAR FileName)
|
||||||
//
|
//
|
||||||
// Copy the contents
|
// Copy the contents
|
||||||
//
|
//
|
||||||
|
Position.HighPart = 0;
|
||||||
if (!FsReadFile(RamFile,
|
Position.LowPart = TotalRead;
|
||||||
ChunkSize,
|
ret = ArcSeek(RamFile, &Position, SeekAbsolute);
|
||||||
NULL,
|
if (ret == ESUCCESS)
|
||||||
(PVOID)((ULONG_PTR)gRamDiskBase + TotalRead)))
|
|
||||||
{
|
{
|
||||||
//
|
ret = ArcRead(RamFile,
|
||||||
// Fail
|
(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");
|
UiMessageBox("Failed to read ramdisk\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
ArcClose(RamFile);
|
||||||
|
|
||||||
VOID
|
// Register a new device for the ramdisk
|
||||||
NTAPI
|
FsRegisterDevice("ramdisk(0)", &RamDiskVtbl);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,6 @@
|
||||||
//
|
//
|
||||||
// Ramdisk Routines
|
// Ramdisk Routines
|
||||||
//
|
//
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
RamDiskSwitchFromBios(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
RamDiskLoadVirtualFile(
|
RamDiskLoadVirtualFile(
|
||||||
|
|
|
@ -746,15 +746,6 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||||
|
|
||||||
UiDrawStatusText("Loading...");
|
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 */
|
/* Get boot path */
|
||||||
if (strchr(SystemPath, '\\') != NULL)
|
if (strchr(SystemPath, '\\') != NULL)
|
||||||
strcpy(szBootPath, strchr(SystemPath, '\\'));
|
strcpy(szBootPath, strchr(SystemPath, '\\'));
|
||||||
|
|
|
@ -390,6 +390,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion)
|
||||||
CHAR FullPath[MAX_PATH], SystemRoot[MAX_PATH], BootPath[MAX_PATH];
|
CHAR FullPath[MAX_PATH], SystemRoot[MAX_PATH], BootPath[MAX_PATH];
|
||||||
CHAR FileName[MAX_PATH];
|
CHAR FileName[MAX_PATH];
|
||||||
CHAR BootOptions[256];
|
CHAR BootOptions[256];
|
||||||
|
PCHAR File;
|
||||||
PCHAR PathSeparator;
|
PCHAR PathSeparator;
|
||||||
PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
|
PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
|
||||||
BOOLEAN Status;
|
BOOLEAN Status;
|
||||||
|
@ -445,6 +446,28 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion)
|
||||||
strcpy(BootOptions, "");
|
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 */
|
/* Let user know we started loading */
|
||||||
UiDrawStatusText("Loading...");
|
UiDrawStatusText("Loading...");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue