0

I have need to make a RAM Disk during the DXE phase of UEFI. Beginning in version 2.6 of the UEFI spec, there is a RAM Disk protocol. I've successfully used this to make a RAM Disk. This RAM Disk must also have a FAT32 system on it.

I am building this FAT32 partition programmatically before I install the RAM Disk. From reading the spec, it seems that firmware (i.e. black magic), ".. automatically adds an EFI_DISK_IO_PROTOCOL to any EFI_BLOCK_IO_PROTOCOL interface that is produced." (This is discussed in this paragraph.) Digging through the RAM Disk DXE driver, it is the case that a BLOCK_IO_PROTOCOL is produced by firmware for any RAM Disk that is instantiated.

So, from the spec, it would seem that if a recognized file system format is present on a supported block device or disk I/O device, the firmware should automatically associate the requisite protocols for this. This isn't what is happening. Using QEMU to test my FW Volumes, when the UEFI Shell starts, I have mappings for the block devices but no FSn mappings:

BLK1: Alias(s):
   VirtualDisk(0x38B74018,0x3BB74017,0)
BLK2: Alias(s):
   VirtualDisk(0x38B74018,0x3BB74017,0)/HD(1,GPT,CF0C3344-CAF3-46C5-A72B-920DFD878FB2,0x800,0x17000)
...

I am instantiating my RAM Disk with

EFI_STATUS
EFIAPI
RegisterMyRd()
{
    EFI_STATUS stat;
    EFI_RAM_DISK_PROTOCOL *pRdProto;
    EFI_DEVICE_PATH_PROTOCOL *pRdPathProto;

    /* There is a static EFI_PHYSICAL_ADDRESS *pRamDisk for this compilation unit */

    stat = gBS->LocateProtocol(
        &gEfiRamDiskProtocolGuid,
        NULL,
        (VOID**)&pRdProto);
    ASSERT_EFI_ERROR(stat);

    stat = pRdProto->Register(
        (UINT64)pRamDisk,
        (UINT64)RAM_DISK_SIZE,  /* a define for 1024 * 1024 * 48 */
        &gEfiVirtualDiskGuid,
        NULL,
        &pRdPathProto);
    ASSERT_EFI_ERROR(stat);
    return stat;
}

So, my RAM Disk is made and the GUID Partition Table is even discovered. There are BLOCK_IO_PROTOCOL(s) instantiated, but for some reason when the Shell is invoked and the mappings are provided, there aren't any File System objects as expected. Though a 48MiB RD is kinda small, using that very same sized "disk" to QEMU works just fine, i.e. qemu-system-x86_64 ... -hda my_disk.img which results in an FS0: mapping for the "disk" on the PCI bus.

Must I add an EFI_SIMPLE_FILE_SYSTEM_PROTOCOL onto the device handle for the RAM Disk? Does that imply implementing my own functions for OpenVolume() and then the many for EFI_FILE_PROTOCOL?

Andrew Falanga
  • 2,274
  • 4
  • 26
  • 51
  • Was a DiskIO protocol installed at the ram disk handle (shell commands devices and openinfo)? Have you tried to connect the drivers after creating the ram disk (shell command connect [-r])? – MiSimon Apr 25 '23 at 06:13
  • @MiSimon I believe that, from the spec, the `DiskIoProtocol` is produced for each `BlockIoProtocol` that is produced. From the link I provided, "The firmware automatically adds an EFI_DISK_IO_PROTOCOL interface to any EFI_BLOCK_IO_PROTOCOL interface that is produced." The DXE RAM Disk driver _does make a BLOCK_IO_PROTOCOL_. I will attempt to verify that a DISK_IO proto is also on the handle. – Andrew Falanga Apr 25 '23 at 15:23
  • @MiSimon I have verified that an `EFI_DISK_IO_PROTOCOL` instance _is installed on the handle_ for the RAM Disk. The method used: `gBS->LocateHandleBuffer(ByProtocol, &gEfiDiskIoProtocolGuid, ...)` and then check that the RAM Disk handle was in the returned list of handles. However, that same process shows that, indeed, an `EFI_SIMPLE_FILE_SYSTEM_PROTOCOL` is not on the RAM Disk. – Andrew Falanga Apr 26 '23 at 19:09

1 Answers1

0

For the sake of completeness, I'm answering my own question. There hasn't been any traction on this, except the comments.

I did find the solution. My interpretation of the spec is correct. When things are laid out correctly, the firmware does make file system protocols for this object automatically. This last statement even alludes to the problem.

Succinctly, I had the FAT32 system misaligned with information about where it would be. Now comes the more in depth answer.

The UEFI (a.k.a. firmware) makes a Block I/O protocol for both the entire drive and for the partition defined in the GPT see this section for details. It was the second block that was being misaligned. I was getting the BLKn device for both the entire RAM Disk and the GUID Partition Table, but the File System was missing.

After placing the FAT32 structure (see the spec) in the LBA that the GUID Partition Array Entry claimed it would be, the expected file system mapping is present FS0.

Because I was using QEMU for development, I did careful scrutiny of the "hard drive" (a file made with parted and mkdosfs -F 32) passed to the VM with -hda fs0_disk.img.

Thank you to @MiSimon for the question about whether EFI_DISK_IO_PROTOCOL objects were on the RAM Disk. This question helped to point me in the right direction.

Andrew Falanga
  • 2,274
  • 4
  • 26
  • 51