Skip to content

doc/uefi: improve Protocol documentation #1612

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions book/src/how_to/protocols.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Using Protocols

## About UEFI Protocols

UEFI protocols are a structured collection of functions and/or data. Please
head to the module documentation in [uefi-raw] for more technical information.

[uefi-raw]: https://docs.rs/uefi-raw/latest/uefi_raw/protocol/index.html

## Usage in uefi-rs

To open a protocol, you must first get a handle, then open a protocol
on that handle. See [Handles and Protocols] for an overview of what
these terms mean.
Expand Down
1 change: 1 addition & 0 deletions uefi-raw/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
## Changed
- `DevicePathProtocol` now derives
`Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash`
- Improved documentation for device paths and their usages


# uefi-raw - 0.10.0 (2025-02-07)
Expand Down
23 changes: 20 additions & 3 deletions uefi-raw/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,26 @@

//! Protocol definitions.
//!
//! Protocols are sets of related functionality identified by a unique
//! ID. They can be implemented by a UEFI driver or occasionally by a
//! UEFI application.
//! # TL;DR
//! Technically, a protocol is a `C` struct holding functions and/or data, with
//! an associated [`GUID`].
//!
//! # About
//! UEFI protocols are a structured collection of functions and/or data,
//! identified by a [`GUID`], which defines an interface between components in
//! the UEFI environment, such as between drivers, applications, or firmware
//! services.
//!
//! Protocols are central to UEFI’s handle-based object model, and they provide
//! a clean, extensible way for components to discover and use services from one
//! another.
//!
//! Implementation-wise, a protocol is a `C` struct holding function pointers
//! and/or data. Please note that some protocols may use [`core::ptr::null`] as
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicholasbishop I'd like to add more about protocol interfaces being null; why can they be null and when is this valid? Can you help?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the issue where it was first brought to our attention that the interface could be null: #859

So LoadedImageDevicePath on an image created with a null device path is one way, but probably not the only way to end up with a null interface.

//! interface. For example, the device path protocol can be implemented but
//! return `null`.
//!
//! [`GUID`]: crate::Guid

pub mod ata;
pub mod block;
Expand Down
3 changes: 2 additions & 1 deletion uefi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@
- The `Display` impl for `CStr8` now excludes the trailing null character.
- `VariableKeys` initializes with a larger name buffer to work around firmware
bugs on some devices.
- The UEFI `allocator::Allocator` has been optimized for page-aligned
- The UEFI `allocator::Allocator` has been optimized for page-aligned
allocations.
- Improved documentation for device paths and their usages


# uefi - 0.34.1 (2025-02-07)
Expand Down
17 changes: 9 additions & 8 deletions uefi/src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,9 +819,10 @@ pub fn protocols_per_handle(handle: Handle) -> Result<ProtocolsPerHandle> {
})
}

/// Locates the handle of a device on the device path that supports the specified protocol.
/// Locates the handle of a device on the [`DevicePath`] that supports the
/// specified [`Protocol`].
///
/// The `device_path` is updated to point at the remaining part of the [`DevicePath`] after
/// The `device_path` is updated to point at the remaining part of it after
/// the part that matched the protocol. For example, it can be used with a device path
/// that contains a file path to strip off the file system portion of the device path,
/// leaving the file path and handle to the file system driver needed to access the file.
Expand Down Expand Up @@ -925,7 +926,7 @@ pub fn locate_handle_buffer(search_ty: SearchType) -> Result<HandleBuffer> {
})
}

/// Returns all the handles implementing a certain protocol.
/// Returns all the handles implementing a certain [`Protocol`].
///
/// # Errors
///
Expand Down Expand Up @@ -1004,7 +1005,7 @@ pub fn get_handle_for_protocol<P: ProtocolPointer + ?Sized>() -> Result<Handle>
.ok_or_else(|| Status::NOT_FOUND.into())
}

/// Opens a protocol interface for a handle.
/// Opens a [`Protocol`] interface for a handle.
///
/// See also [`open_protocol_exclusive`], which provides a safe subset of this
/// functionality.
Expand Down Expand Up @@ -1067,7 +1068,7 @@ pub unsafe fn open_protocol<P: ProtocolPointer + ?Sized>(
})
}

/// Opens a protocol interface for a handle in exclusive mode.
/// Opens a [`Protocol`] interface for a handle in exclusive mode.
///
/// If successful, a [`ScopedProtocol`] is returned that will automatically
/// close the protocol interface when dropped.
Expand Down Expand Up @@ -1095,7 +1096,7 @@ pub fn open_protocol_exclusive<P: ProtocolPointer + ?Sized>(
}
}

/// Tests whether a handle supports a protocol.
/// Tests whether a handle supports a [`Protocol`].
///
/// Returns `Ok(true)` if the handle supports the protocol, `Ok(false)` if not.
///
Expand Down Expand Up @@ -1494,7 +1495,7 @@ impl Deref for ProtocolsPerHandle {
}

/// A buffer returned by [`locate_handle_buffer`] that contains an array of
/// [`Handle`]s that support the requested protocol.
/// [`Handle`]s that support the requested [`Protocol`].
#[derive(Debug, Eq, PartialEq)]
pub struct HandleBuffer {
count: usize,
Expand All @@ -1515,7 +1516,7 @@ impl Deref for HandleBuffer {
}
}

/// An open protocol interface. Automatically closes the protocol
/// An open [`Protocol`] interface. Automatically closes the protocol
/// interface on drop.
///
/// Most protocols have interface data associated with them. `ScopedProtocol`
Expand Down
9 changes: 6 additions & 3 deletions uefi/src/proto/console/gop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,13 @@ use uefi_raw::protocol::console::{

pub use uefi_raw::protocol::console::PixelBitmask;

/// Provides access to the video hardware's frame buffer.
/// Graphics Output [`Protocol`] (GOP). Provides access to the video hardware's
/// frame buffer.
///
/// The GOP can be used to set the properties of the frame buffer,
/// and also allows the app to access the in-memory buffer.
/// The GOP can be used to set the properties of the framebuffer, and also
/// allows the app to access the in-memory buffer.
///
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(GraphicsOutputProtocol::GUID)]
Expand Down
6 changes: 5 additions & 1 deletion uefi/src/proto/console/pointer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ use crate::proto::unsafe_protocol;
use crate::{Event, Result, Status, StatusExt};
use uefi_raw::protocol::console::SimplePointerProtocol;

/// Provides information about a pointer device.
/// Simple Pointer [`Protocol`]. Provides information about a pointer device.
///
/// Pointer devices are mouses, touchpads, and touchscreens.
///
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(SimplePointerProtocol::GUID)]
Expand Down
4 changes: 3 additions & 1 deletion uefi/src/proto/console/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ pub use uefi_raw::protocol::console::serial::{
ControlBits, Parity, SerialIoMode as IoMode, StopBits,
};

/// Provides access to a serial I/O device.
/// Serial IO [`Protocol`]. Provides access to a serial I/O device.
///
/// This can include standard UART devices, serial ports over a USB interface,
/// or any other character-based communication device.
///
/// Since UEFI drivers are implemented through polling, if you fail to regularly
/// check for input/output, some data might be lost.
///
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(SerialIoProtocol::GUID)]
Expand Down
4 changes: 3 additions & 1 deletion uefi/src/proto/console/text/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use crate::{Char16, Event, Result, Status, StatusExt};
use core::mem::MaybeUninit;
use uefi_raw::protocol::console::{InputKey, SimpleTextInputProtocol};

/// Interface for text-based input devices.
/// Simple Text Input [`Protocol`]. Interface for text-based input devices.
///
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(SimpleTextInputProtocol::GUID)]
Expand Down
3 changes: 2 additions & 1 deletion uefi/src/proto/console/text/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{CStr16, Result, ResultExt, Status, StatusExt};
use core::fmt;
use uefi_raw::protocol::console::{SimpleTextOutputMode, SimpleTextOutputProtocol};

/// Interface for text-based output devices.
/// Simple Text Output [`Protocol`]. Interface for text-based output devices.
///
/// It implements the fmt::Write trait, so you can use it to print text with
/// standard Rust constructs like the `write!()` and `writeln!()` macros.
Expand All @@ -22,6 +22,7 @@ use uefi_raw::protocol::console::{SimpleTextOutputMode, SimpleTextOutputProtocol
/// [`system::stdout`]: crate::system::with_stdout
/// [`system::stderr`]: crate::system::with_stderr
/// [`boot`]: crate::boot#accessing-protocols
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(SimpleTextOutputProtocol::GUID)]
Expand Down
8 changes: 8 additions & 0 deletions uefi/src/proto/debug/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub use exception::ExceptionType;
mod context;
mod exception;

/// Debug support [`Protocol`].
///
/// The debugging support protocol allows debuggers to connect to a UEFI machine.
/// It is expected that there will typically be two instances of the EFI Debug Support protocol in the system.
/// One associated with the native processor instruction set (IA-32, x64, ARM, RISC-V, or Itanium processor
Expand All @@ -31,6 +33,8 @@ mod exception;
/// one for any given instruction set.
///
/// NOTE: OVMF only implements this protocol interface for the virtual EBC processor
///
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(C)]
#[unsafe_protocol("2755590c-6f3c-42fa-9ea4-a3ba543cda25")]
Expand Down Expand Up @@ -178,8 +182,12 @@ pub enum ProcessorArch: u32 => {
RISCV_128 = 0x5128,
}}

/// Debug Port [`Protocol`].
///
/// The debug port protocol abstracts the underlying debug port
/// hardware, whether it is a regular Serial port or something else.
///
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(C)]
#[unsafe_protocol("eba4e8d2-3858-41ec-a281-2647ba9660d0")]
Expand Down
11 changes: 7 additions & 4 deletions uefi/src/proto/device_path/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

//! Device Path protocol
//! Helpers to work with UEFI Device Paths and the Device Path Protocol.
//!
//! A UEFI device path is a very flexible structure for encoding a
//! programmatic path such as a hard drive or console.
//! The main export of this module is [`DevicePath`].
//!
//! A device path is made up of a packed list of variable-length nodes of
//! various types. The entire device path is terminated with an
Expand Down Expand Up @@ -400,7 +399,7 @@ impl ToOwned for DevicePathInstance {
}
}

/// Device path protocol.
/// Device Path [`Protocol`].
///
/// Can be used on any device handle to obtain generic path/location information
/// concerning the physical device or logical device. If the handle does not
Expand All @@ -413,6 +412,7 @@ impl ToOwned for DevicePathInstance {
///
/// [module-level documentation]: crate::proto::device_path
/// [`END_ENTIRE`]: DeviceSubType::END_ENTIRE
/// [`Protocol`]: uefi::proto::Protocol
#[repr(C, packed)]
#[unsafe_protocol(uefi_raw::protocol::device_path::DevicePathProtocol::GUID)]
#[derive(Eq, Pointee)]
Expand Down Expand Up @@ -729,12 +729,15 @@ pub enum NodeConversionError {
UnsupportedType,
}

/// Loaded Image Device Path [`Protocol`].
///
/// Protocol for accessing the device path that was passed in to [`load_image`]
/// when loading a PE/COFF image.
///
/// The layout of this type is the same as a [`DevicePath`].
///
/// [`load_image`]: crate::boot::load_image
/// [`Protocol`]: uefi::proto::Protocol
#[repr(transparent)]
#[unsafe_protocol("bc62157e-3e33-4fec-9920-2d3b36d750df")]
#[derive(Debug, Pointee)]
Expand Down
8 changes: 8 additions & 0 deletions uefi/src/proto/device_path/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ pub struct DisplayOnly(pub bool);
#[derive(Clone, Copy, Debug)]
pub struct AllowShortcuts(pub bool);

/// Device Path to Text [`Protocol`].
///
/// Protocol for converting a [`DevicePath`] or `DevicePathNode`] to a string.
///
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(DevicePathToTextProtocol::GUID)]
Expand Down Expand Up @@ -99,7 +103,11 @@ impl DevicePathToText {
}
}

/// Device Path from Text [`Protocol`].
///
/// Protocol for converting a string to a [`DevicePath`] or `DevicePathNode`].
///
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol("05c99a21-c70f-4ad2-8a5f-35df3343f51e")]
Expand Down
6 changes: 6 additions & 0 deletions uefi/src/proto/driver/component_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use core::fmt::{self, Debug, Display, Formatter};
use core::{ptr, slice};
use uefi_raw::protocol::driver::ComponentName2Protocol;

/// Component Name1 [`Protocol`].
///
/// Protocol that provides human-readable names for a driver and for each of the
/// controllers that the driver is managing.
///
Expand All @@ -27,6 +29,7 @@ use uefi_raw::protocol::driver::ComponentName2Protocol;
///
/// [ISO 639-2]: https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
/// [RFC 4646]: https://www.rfc-editor.org/rfc/rfc4646
/// [`Protocol`]: uefi::proto::Protocol
#[deprecated = "deprecated in UEFI 2.1; use ComponentName2 where possible"]
#[unsafe_protocol(ComponentName2Protocol::DEPRECATED_COMPONENT_NAME_GUID)]
#[derive(Debug)]
Expand Down Expand Up @@ -85,6 +88,8 @@ impl ComponentName1 {
}
}

/// Component Name2 [`Protocol`].
///
/// Protocol that provides human-readable names for a driver and for each of the
/// controllers that the driver is managing.
///
Expand All @@ -99,6 +104,7 @@ impl ComponentName1 {
///
/// [ISO 639-2]: https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
/// [RFC 4646]: https://www.rfc-editor.org/rfc/rfc4646
/// [`Protocol`]: uefi::proto::Protocol
#[unsafe_protocol(ComponentName2Protocol::GUID)]
#[derive(Debug)]
#[repr(transparent)]
Expand Down
8 changes: 7 additions & 1 deletion uefi/src/proto/loaded_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ use core::ffi::c_void;
use core::{mem, slice};
use uefi_raw::protocol::loaded_image::LoadedImageProtocol;

/// The LoadedImage protocol. This can be opened on any image handle using the `HandleProtocol` boot service.
/// The Loaded Image [`Protocol`].
///
/// This can be opened on any image handle using [`boot::open_protocol`],
/// for example.
///
/// [`Protocol`]: uefi::proto::Protocol
/// [`boot::open_protocol`]: uefi::boot::open_protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(LoadedImageProtocol::GUID)]
Expand Down
4 changes: 3 additions & 1 deletion uefi/src/proto/media/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use crate::{Result, StatusExt};

pub use uefi_raw::protocol::block::{BlockIoProtocol, Lba};

/// The Block I/O protocol.
/// Block I/O [`Protocol`].
///
/// [`Protocol`]: uefi::proto::Protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(BlockIoProtocol::GUID)]
Expand Down
Loading
Loading