Skip to content

Commit 606b2d5

Browse files
committed
patina: Add EFI_RAM_DISK_PROTOCOL bindings
Adds sdk/patina/src/uefi_protocol/ram_disk.rs implementing the FFI binding for EFI_RAM_DISK_PROTOCOL per UEFI 2.10 section 13.16. Exposes the Protocol struct, RegisterFn / UnregisterFn type aliases, and the four well-known RamDiskType GUIDs (virtual disk, virtual CD, persistent variants). Used by the SRE flow to install the recovery WIM as a virtual block device after reading it out of the NVMe boot partition into RAM. Adds two unit tests covering the protocol GUID against the UEFI-spec value and the distinctness of the four RamDiskType GUIDs. Closes #65.
1 parent 73d7c9d commit 606b2d5

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

sdk/patina/src/uefi_protocol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
1010
pub mod decompress;
1111
pub mod performance_measurement;
12+
pub mod ram_disk;
1213
pub mod status_code;
1314

1415
use crate::BinaryGuid;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//! UEFI RAM Disk Protocol bindings (UEFI 2.10 §13.16).
2+
//!
3+
//! Used to install a contiguous range of system memory as a virtual block device the system
4+
//! firmware can boot from. The SRE flow uses this to boot the recovery WIM after reading it
5+
//! out of the NVMe boot partition into RAM.
6+
//!
7+
//! ## License
8+
//!
9+
//! Copyright (c) Microsoft Corporation.
10+
//!
11+
//! SPDX-License-Identifier: Apache-2.0
12+
//!
13+
use r_efi::efi;
14+
15+
use crate::uefi_protocol::ProtocolInterface;
16+
17+
/// Well-known `RamDiskType` GUID for a generic virtual disk.
18+
pub const RAM_DISK_VIRTUAL_DISK_GUID: efi::Guid =
19+
efi::Guid::from_fields(0x77ab535a, 0x45fc, 0x624b, 0x55, 0x60, &[0xf7, 0xb2, 0x81, 0xd1, 0xf9, 0x6e]);
20+
21+
/// Well-known `RamDiskType` GUID for a virtual CD (ISO9660) image.
22+
pub const RAM_DISK_VIRTUAL_CD_GUID: efi::Guid =
23+
efi::Guid::from_fields(0x3d5abd30, 0x4175, 0x87ce, 0x6d, 0x64, &[0xd2, 0xad, 0xe5, 0x23, 0xc4, 0xbb]);
24+
25+
/// Well-known `RamDiskType` GUID for a persistent virtual disk.
26+
pub const RAM_DISK_PERSISTENT_VIRTUAL_DISK_GUID: efi::Guid =
27+
efi::Guid::from_fields(0x5cea02c9, 0x4d07, 0x69d3, 0x26, 0x9f, &[0x44, 0x96, 0xfb, 0xe0, 0x96, 0xf9]);
28+
29+
/// Well-known `RamDiskType` GUID for a persistent virtual CD.
30+
pub const RAM_DISK_PERSISTENT_VIRTUAL_CD_GUID: efi::Guid =
31+
efi::Guid::from_fields(0x08018188, 0x42cd, 0xbb48, 0x10, 0x0f, &[0x53, 0x87, 0xd5, 0x3d, 0xed, 0x3d]);
32+
33+
/// FFI type for `EFI_RAM_DISK_REGISTER_RAMDISK`.
34+
///
35+
/// Installs a `[ram_disk_base, ram_disk_base + ram_disk_size)` memory range as a RAM disk of
36+
/// type `ram_disk_type`. When `parent_device_path` is null, the protocol creates a virtual
37+
/// device-path root; otherwise the new RAM disk is appended under the supplied path. On
38+
/// success the resulting device path is written to `*device_path` (caller-owned, do not free
39+
/// before calling `Unregister`).
40+
pub type RegisterFn = extern "efiapi" fn(
41+
ram_disk_base: u64,
42+
ram_disk_size: u64,
43+
ram_disk_type: *mut efi::Guid,
44+
parent_device_path: *mut efi::protocols::device_path::Protocol,
45+
device_path: *mut *mut efi::protocols::device_path::Protocol,
46+
) -> efi::Status;
47+
48+
/// FFI type for `EFI_RAM_DISK_UNREGISTER_RAMDISK`.
49+
///
50+
/// Removes a previously-installed RAM disk identified by the device path returned from
51+
/// `Register`. The backing memory is **not** freed by this call — the caller owns its
52+
/// lifetime.
53+
pub type UnregisterFn = extern "efiapi" fn(device_path: *mut efi::protocols::device_path::Protocol) -> efi::Status;
54+
55+
/// FFI binding for `EFI_RAM_DISK_PROTOCOL` per UEFI 2.10 §13.16.
56+
#[repr(C)]
57+
pub struct Protocol {
58+
pub register: RegisterFn,
59+
pub unregister: UnregisterFn,
60+
}
61+
62+
// SAFETY: Layout matches the UEFI 2.10 §13.16 protocol struct (two efiapi function pointers).
63+
// PROTOCOL_GUID matches the UEFI-spec value (AB38A0DF-6873-44A9-87E6-D4EB56148449).
64+
unsafe impl ProtocolInterface for Protocol {
65+
const PROTOCOL_GUID: crate::BinaryGuid = crate::BinaryGuid::from_string("AB38A0DF-6873-44A9-87E6-D4EB56148449");
66+
}
67+
68+
#[cfg(test)]
69+
mod tests {
70+
use super::*;
71+
use crate::uefi_protocol::ProtocolInterface;
72+
73+
#[test]
74+
fn protocol_guid_matches_uefi_spec() {
75+
// EFI_RAM_DISK_PROTOCOL_GUID per UEFI 2.10 §13.16.
76+
let expected =
77+
efi::Guid::from_fields(0xab38a0df, 0x6873, 0x44a9, 0x87, 0xe6, &[0xd4, 0xeb, 0x56, 0x14, 0x84, 0x49]);
78+
assert_eq!(
79+
*Protocol::PROTOCOL_GUID.0.as_bytes(),
80+
*expected.as_bytes(),
81+
"RAM Disk protocol GUID must match UEFI 2.10 §13.16"
82+
);
83+
}
84+
85+
#[test]
86+
fn ram_disk_type_guids_are_distinct() {
87+
let virtual_disk = *RAM_DISK_VIRTUAL_DISK_GUID.as_bytes();
88+
let virtual_cd = *RAM_DISK_VIRTUAL_CD_GUID.as_bytes();
89+
let persistent = *RAM_DISK_PERSISTENT_VIRTUAL_DISK_GUID.as_bytes();
90+
let persistent_cd = *RAM_DISK_PERSISTENT_VIRTUAL_CD_GUID.as_bytes();
91+
92+
assert_ne!(virtual_disk, virtual_cd);
93+
assert_ne!(virtual_disk, persistent);
94+
assert_ne!(virtual_disk, persistent_cd);
95+
assert_ne!(virtual_cd, persistent);
96+
assert_ne!(virtual_cd, persistent_cd);
97+
assert_ne!(persistent, persistent_cd);
98+
}
99+
}

0 commit comments

Comments
 (0)