rust-osdev/uefi-rs

`unsafe_protocol` is not necessary?

Closed this issue · 4 comments

I wrote a little stub loader for the Linux kernel which exposes an initrd for it.

I had to implement the EFI_LOAD_FILE2_PROTOCOL protocol with a struct as follows:

/// Implementation of the `EFI_LOAD_FILE2_PROTOCOL` protocol
///
/// Used to obtain files from arbitrary devices that are not boot options.
#[repr(C)]
#[uefi::proto::unsafe_protocol(EFI_LOADFILE2_PROTOCOL)] // XXX: Not needed?
pub struct LoadFile2Protocol {
    pub load_file: LoadFile2,
    initrd: &'static [u8],
}

It was not clear to me why unsafe_protocol was required, and inspecting the source in uefi-rs didn't reveal this being used. This GUID is unused, and the actual one that is used is the one passed to install_protocol_interface.

I deleted the line and my service still compiles and runs perfectly. Is this macro no longer required? Is it only for specific situations? The documentation indicates that it implements a couple of Traits, but the documentation for these traits doesn't specify when they are required either. Protocols work fine without them too.

I think what you want to do is already done in our tests:

struct CustomLoadFile2Protocol {

You can use the code as template. And yep, you don't need [uefi::proto::unsafe_protocol(EFI_LOADFILE2_PROTOCOL) as you can also get the UUID from uefi_raw::protocol::media::LoadFile2Protocol:GUID; you can also find this in the code linked above

I deleted the line and my service still compiles and runs perfectly. Is this macro no longer required? Is it only for specific situations?

The Protocol trait enables opening that protocol in Rust code. In your case you are only implementing the protocol in Rust code, and the Linux kernel is opening the protocol.

We should indeed make this clear in the documentation.

Closing now, as the docs have been updated.

Thanks!