- Plug in RAM disk boot support (kernel-side)

svn path=/trunk/; revision=34202
This commit is contained in:
ReactOS Portable Systems Group 2008-06-30 02:15:48 +00:00
parent 662c3b62fe
commit 3cc3ad057f
3 changed files with 289 additions and 0 deletions

View file

@ -56,6 +56,30 @@
//
#define IO_METHOD_FROM_CTL_CODE(c) (c & 0x00000003)
//
// Bugcheck codes for RAM disk booting
//
//
// No LoaderXIPRom descriptor was found in the loader memory list
//
#define RD_NO_XIPROM_DESCRIPTOR 1
//
// Unable to open the RAM disk driver (ramdisk.sys or \Device\Ramdisk)
//
#define RD_NO_RAMDISK_DRIVER 2
//
// FSCTL_CREATE_RAM_DISK failed
//
#define RD_FSCTL_FAILED 3
//
// Unable to create GUID string from binary GUID
//
#define RD_GUID_CONVERT_FAILED 4
//
// Unable to create symbolic link pointing to the RAM disk device
//
#define RD_SYMLINK_CREATE_FAILED 5
//
// Packet Types when piggybacking on the IRP Overlay
//
@ -986,6 +1010,15 @@ IopDeleteIoCompletion(
PVOID ObjectBody
);
//
// Ramdisk Routines
//
NTSTATUS
NTAPI
IopStartRamdisk(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
//
// Global I/O Data
//

View file

@ -0,0 +1,255 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: ntoskrnl/io/iomgr/ramdisk.c
* PURPOSE: Allows booting from RAM disk
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#include <initguid.h>
#include <ntddrdsk.h>
#define NDEBUG
#include <debug.h>
/* DATA ***********************************************************************/
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, IopStartRamdisk)
#endif
/* FUNCTIONS ******************************************************************/
NTSTATUS
NTAPI
IopStartRamdisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
NTSTATUS Status;
PCHAR CommandLine, Offset, OffsetValue, Length, LengthValue;
HANDLE DriverHandle;
RAMDISK_CREATE_INPUT RamdiskCreate;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING GuidString, SymbolicLinkName, ObjectName, DeviceString;
PLIST_ENTRY ListHead, NextEntry;
OBJECT_ATTRIBUTES ObjectAttributes;
WCHAR SourceString[54];
//
// Scan memory descriptors
//
MemoryDescriptor = NULL;
ListHead = &LoaderBlock->MemoryDescriptorListHead;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
//
// Get the descriptor
//
MemoryDescriptor = CONTAINING_RECORD(NextEntry,
MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry);
//
// Needs to be a ROM/RAM descriptor
//
if (MemoryDescriptor->MemoryType == LoaderXIPRom) break;
//
// Keep trying
//
NextEntry = NextEntry->Flink;
}
//
// Nothing found?
//
if (NextEntry == ListHead)
{
//
// Bugcheck -- no data
//
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
RD_NO_XIPROM_DESCRIPTOR,
STATUS_INVALID_PARAMETER,
0,
0);
}
//
// Setup the input buffer
//
RtlZeroMemory(&RamdiskCreate, sizeof(RamdiskCreate));
RamdiskCreate.Version = sizeof(RamdiskCreate);
RamdiskCreate.DiskType = FILE_DEVICE_CD_ROM_FILE_SYSTEM;
RamdiskCreate.BasePage = MemoryDescriptor->BasePage;
RamdiskCreate.DiskOffset = 0;
RamdiskCreate.DiskLength = MemoryDescriptor->PageCount << PAGE_SHIFT;
RamdiskCreate.DiskGuid = RAMDISK_BOOTDISK_GUID;
RamdiskCreate.DriveLetter = L'C';
RamdiskCreate.Options.Fixed = TRUE;
//
// Check for commandline parameters
//
CommandLine = LoaderBlock->LoadOptions;
if (CommandLine)
{
//
// Make everything upper case
//
_strupr(CommandLine);
//
// Check for offset parameter
//
Offset = strstr(CommandLine, "RDIMAGEOFFSET");
if (Offset)
{
//
// Get to the actual value
//
OffsetValue = strstr(Offset, "=");
if (OffsetValue)
{
//
// Set the offset
//
RamdiskCreate.DiskOffset = atol(OffsetValue + 1);
}
}
//
// Reduce the disk length
//
RamdiskCreate.DiskLength -= RamdiskCreate.DiskOffset;
//
// Check for length parameter
//
Length = strstr(CommandLine, "RDIMAGELENGTH");
if (Length)
{
//
// Get to the actual value
//
LengthValue = strstr(Length, "=");
if (LengthValue)
{
//
// Set the offset
//
RamdiskCreate.DiskLength = _atoi64(LengthValue + 1);
}
}
}
//
// Setup object attributes
//
RtlInitUnicodeString(&ObjectName, L"\\Device\\Ramdisk");
InitializeObjectAttributes(&ObjectAttributes,
&ObjectName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
//
// Open a handle to the driver
//
Status = ZwOpenFile(&DriverHandle,
GENERIC_ALL,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!(NT_SUCCESS(Status)) || !(NT_SUCCESS(IoStatusBlock.Status)))
{
//
// Bugcheck -- no driver
//
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
RD_NO_RAMDISK_DRIVER,
IoStatusBlock.Status,
0,
0);
}
//
// Send create command
//
Status = ZwDeviceIoControlFile(DriverHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
FSCTL_CREATE_RAM_DISK,
&RamdiskCreate,
sizeof(RamdiskCreate),
NULL,
0);
ZwClose(DriverHandle);
if (!(NT_SUCCESS(Status)) || !(NT_SUCCESS(IoStatusBlock.Status)))
{
//
// Bugcheck -- driver failed
//
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
RD_FSCTL_FAILED,
IoStatusBlock.Status,
0,
0);
}
//
// Convert the GUID
//
Status = RtlStringFromGUID(&RamdiskCreate.DiskGuid, &GuidString);
if (!NT_SUCCESS(Status))
{
//
// Bugcheck -- GUID convert failed
//
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
RD_GUID_CONVERT_FAILED,
Status,
0,
0);
}
//
// Build the symbolic link name and target
//
_snwprintf(SourceString,
sizeof(SourceString),
L"\\Device\\Ramdisk%wZ",
&GuidString);
SymbolicLinkName.Length = 38;
SymbolicLinkName.MaximumLength = 38 + sizeof(UNICODE_NULL);
SymbolicLinkName.Buffer = L"\\ArcName\\ramdisk(0)";
//
// Create the symbolic link
//
RtlInitUnicodeString(&DeviceString, SourceString);
Status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceString);
RtlFreeUnicodeString(&GuidString);
if (!NT_SUCCESS(Status))
{
//
// Bugcheck -- symlink create failed
//
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
RD_SYMLINK_CREATE_FAILED,
Status,
0,
0);
}
//
// We made it
//
return STATUS_SUCCESS;
}

View file

@ -256,6 +256,7 @@
<file>iowork.c</file>
<file>irp.c</file>
<file>irq.c</file>
<file>ramdisk.c</file>
<file>rawfs.c</file>
<file>remlock.c</file>
<file>util.c</file>