From fb4e62fede2f1b85a308402b2c094784eabe1022 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 8 Apr 2025 09:29:52 +0200 Subject: [PATCH 1/2] doc: streamline device path documentation between uefi-raw and uefi --- uefi-raw/CHANGELOG.md | 1 + uefi-raw/src/protocol/device_path.rs | 49 +++++++++++++++++-- uefi/CHANGELOG.md | 3 +- uefi/src/proto/device_path/mod.rs | 71 +++++++++++++++------------- 4 files changed, 87 insertions(+), 37 deletions(-) diff --git a/uefi-raw/CHANGELOG.md b/uefi-raw/CHANGELOG.md index 3d0d44b0d..91ca0b2fa 100644 --- a/uefi-raw/CHANGELOG.md +++ b/uefi-raw/CHANGELOG.md @@ -19,6 +19,7 @@ ## Changed - `DevicePathProtocol` now derives `Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash` +- The documentation for UEFI device paths has been streamlined and improved. # uefi-raw - 0.10.0 (2025-02-07) diff --git a/uefi-raw/src/protocol/device_path.rs b/uefi-raw/src/protocol/device_path.rs index f72ccb7b7..4c255767d 100644 --- a/uefi-raw/src/protocol/device_path.rs +++ b/uefi-raw/src/protocol/device_path.rs @@ -1,5 +1,45 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 +//! The UEFI device path protocol, i.e., UEFI device paths. +//! +//! This module provides (generated) ABI-compatible bindings to all known device +//! path node types. +//! +//! # Terminology: Device Paths, Device Path Instances, and Device Path Nodes +//! An open UEFI device path [protocol], also called _device path_, is a +//! flexible and structured sequence of binary nodes that describe a route from +//! the UEFI root to a particular device, controller, or file. +//! +//! An entire device path can be made up of multiple device path instances, +//! and each instance is made up of multiple device path nodes. A device path +//! _may_ contain multiple device-path instances separated by [`END_INSTANCE`] +//! nodes, but typical paths contain only a single instance (in which case no +//! [`END_INSTANCE`] node is needed). The entire device path is terminated with +//! an [`END_ENTIRE`] node. +//! +//! Each node represents a step in the path: PCI device, partition, filesystem, +//! file path, etc. Each node represents a step in the path: PCI device, +//! partition, filesystem, file path, etc. +//! +//! Example of what a device path containing two instances (each comprised of +//! three nodes) might look like: +//! +//! ```text +//! ┌──────┬──────┬──────────────╥───────┬──────────┬────────────┐ +//! │ ACPI │ PCI │ END_INSTANCE ║ CDROM │ FILEPATH │ END_ENTIRE │ +//! └──────┴──────┴──────────────╨───────┴──────────┴────────────┘ +//! ↑ ↑ ↑ ↑ ↑ ↑ ↑ +//! ├─Node─╨─Node─╨─────Node─────╨─Node──╨───Node───╨────Node────┤ +//! ↑ ↑ ↑ +//! ├─── DevicePathInstance ─────╨────── DevicePathInstance ─────┤ +//! │ │ +//! └──────────────────── Entire DevicePath ─────────────────────┘ +//! ``` +//! +//! [`END_ENTIRE`]: DeviceSubType::END_ENTIRE +//! [`END_INSTANCE`]: DeviceSubType::END_INSTANCE +//! [protocol]: crate::protocol + mod device_path_gen; use crate::{guid, Boolean, Char16, Guid}; @@ -8,11 +48,12 @@ pub use device_path_gen::{acpi, bios_boot_spec, end, hardware, media, messaging} /// Device path protocol. /// -/// A device path contains one or more device path instances made up of -/// variable-length nodes. +/// Note that the fields in this struct define the fixed header at the start of +/// each node; a device path is typically larger than these four bytes. +/// +/// See the [module-level documentation] for more details. /// -/// Note that the fields in this struct define the header at the start of each -/// node; a device path is typically larger than these four bytes. +/// [module-level documentation]: self #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(C)] pub struct DevicePathProtocol { diff --git a/uefi/CHANGELOG.md b/uefi/CHANGELOG.md index fa9cb6218..c22d1cdf7 100644 --- a/uefi/CHANGELOG.md +++ b/uefi/CHANGELOG.md @@ -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. +- The documentation for UEFI device paths has been streamlined and improved. # uefi - 0.34.1 (2025-02-07) diff --git a/uefi/src/proto/device_path/mod.rs b/uefi/src/proto/device_path/mod.rs index d3e6bf049..67be4885e 100644 --- a/uefi/src/proto/device_path/mod.rs +++ b/uefi/src/proto/device_path/mod.rs @@ -1,28 +1,7 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 -//! Device Path protocol -//! -//! A UEFI device path is a very flexible structure for encoding a -//! programmatic path such as a hard drive or console. -//! -//! 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 -//! [`END_ENTIRE`] node. A device path _may_ contain multiple device-path -//! instances separated by [`END_INSTANCE`] nodes, but typical paths contain -//! only a single instance (in which case no `END_INSTANCE` node is needed). -//! -//! Example of what a device path containing two instances (each comprised of -//! three nodes) might look like: -//! -//! ```text -//! ┌──────┬─────┬──────────────╥───────┬──────────┬────────────┐ -//! │ ACPI │ PCI │ END_INSTANCE ║ CDROM │ FILEPATH │ END_ENTIRE │ -//! └──────┴─────┴──────────────╨───────┴──────────┴────────────┘ -//! ↑ ↑ ↑ -//! ├─── DevicePathInstance ────╨────── DevicePathInstance ─────┤ -//! │ │ -//! └─────────────────── Entire DevicePath ─────────────────────┘ -//! ``` +//! High-level wrappers for the UEFI device path [`Protocol`], i.e., +//! [UEFI device paths]. //! //! # Types //! @@ -74,6 +53,7 @@ //! [`Protocol`]: crate::proto::Protocol //! [`device_type`]: DevicePathNode::device_type //! [`sub_type`]: DevicePathNode::sub_type +//! [UEFI device paths]: uefi_raw::protocol::device_path pub mod build; pub mod text; @@ -92,7 +72,6 @@ use core::ffi::c_void; use core::fmt::{self, Debug, Display, Formatter}; use core::ops::Deref; use ptr_meta::Pointee; - use uefi_raw::protocol::device_path::DevicePathProtocol; #[cfg(feature = "alloc")] use { @@ -400,21 +379,49 @@ impl ToOwned for DevicePathInstance { } } -/// Device path protocol. +/// High-level representation of the UEFI [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 -/// logically map to a physical device, the handle may not necessarily support -/// the device path protocol. The device path describes the location of the -/// device the handle is for. The size of the Device Path can be determined from -/// the structures that make up the Device Path. +/// This type represents an entire device path, possibly consisting of multiple +/// [`DevicePathInstance`]s and [`DevicePathNode`]s. /// /// See the [module-level documentation] for more details. /// +/// # Usage +/// This type implements [`Protocol`] and therefore 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 logically map to a +/// physical device, the handle may not necessarily support the device path +/// protocol. The device path describes the location of the device the handle is +/// for. The size of the Device Path can be determined from the structures that +/// make up the Device Path. +/// +/// # Example +/// ```rust,no_run +/// use uefi::Handle; +/// use uefi::boot::{open_protocol_exclusive, ScopedProtocol}; +/// use uefi::proto::device_path::DevicePath; +/// use uefi::proto::device_path::text::{AllowShortcuts, DisplayOnly}; +/// use uefi::proto::loaded_image::LoadedImage; +/// +/// fn open_device_path(image_handle: Handle) { +/// let loaded_image = open_protocol_exclusive::(image_handle).unwrap(); +/// let device_handle = loaded_image.device().unwrap(); +/// let device_path: ScopedProtocol +/// = open_protocol_exclusive::(device_handle).unwrap(); +/// log::debug!( +/// "Device path: {}", +/// device_path.to_string(DisplayOnly(true), AllowShortcuts(true)).unwrap() +/// ); +/// } +/// ``` +/// /// [module-level documentation]: crate::proto::device_path /// [`END_ENTIRE`]: DeviceSubType::END_ENTIRE +/// [`DevicePathProtocol`]: uefi_raw::protocol::device_path::DevicePathProtocol +/// [`Protocol`]: uefi::proto::Protocol +/// [device path protocol]: uefi_raw::protocol::device_path #[repr(C, packed)] -#[unsafe_protocol(uefi_raw::protocol::device_path::DevicePathProtocol::GUID)] +#[unsafe_protocol(DevicePathProtocol::GUID)] #[derive(Eq, Pointee)] pub struct DevicePath { data: [u8], From ef6a8957f4ef05b90f2ee3fe8fec36040ceda91a Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Mon, 21 Apr 2025 14:05:26 +0200 Subject: [PATCH 2/2] doc: uefi: partially duplicate device path documentation The idea is that people should not always read the uefi-raw doc in any case. Therefore, a briefly simplified version of the uefi-raw doc is now also in uefi. See https://github.com/rust-osdev/uefi-rs/pull/1641#discussion_r2051529184 for a discussion. --- uefi/src/proto/device_path/mod.rs | 38 ++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/uefi/src/proto/device_path/mod.rs b/uefi/src/proto/device_path/mod.rs index 67be4885e..f5f8c51a5 100644 --- a/uefi/src/proto/device_path/mod.rs +++ b/uefi/src/proto/device_path/mod.rs @@ -1,7 +1,39 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 -//! High-level wrappers for the UEFI device path [`Protocol`], i.e., -//! [UEFI device paths]. +//! The UEFI device path [`Protocol`], i.e., UEFI device paths. +//! +//! This module provides high-level wrappers to work with UEFI device paths. +//! Please find additional low-level information in the +//! [device path section of `uefi-raw`]. +//! +//! # Terminology: Device Paths, Device Path Instances, and Device Path Nodes +//! An open UEFI device path [`Protocol`], also called _device path_, is a +//! flexible and structured sequence of binary nodes that describe a route from +//! the UEFI root to a particular device, controller, or file. +//! +//! An entire device path can be made up of multiple device path instances, +//! and each instance is made up of multiple device path nodes. A device path +//! _may_ contain multiple device-path instances, but typical paths contain only +//! a single instance. +//! +//! Each node represents a step in the path: PCI device, partition, filesystem, +//! file path, etc. Each node represents a step in the path: PCI device, +//! partition, filesystem, file path, etc. +//! +//! Example of what a device path containing two instances (each comprised of +//! three nodes) might look like: +//! +//! ```text +//! ┌──────┬──────┬──────────────╥───────┬──────────┬────────────┐ +//! │ ACPI │ PCI │ END_INSTANCE ║ CDROM │ FILEPATH │ END_ENTIRE │ +//! └──────┴──────┴──────────────╨───────┴──────────┴────────────┘ +//! ↑ ↑ ↑ ↑ ↑ ↑ ↑ +//! ├─Node─╨─Node─╨─────Node─────╨─Node──╨───Node───╨────Node────┤ +//! ↑ ↑ ↑ +//! ├─── DevicePathInstance ─────╨────── DevicePathInstance ─────┤ +//! │ │ +//! └──────────────────── Entire DevicePath ─────────────────────┘ +//! ``` //! //! # Types //! @@ -53,7 +85,7 @@ //! [`Protocol`]: crate::proto::Protocol //! [`device_type`]: DevicePathNode::device_type //! [`sub_type`]: DevicePathNode::sub_type -//! [UEFI device paths]: uefi_raw::protocol::device_path +//! [device path section of `uefi-raw`]: uefi_raw::protocol::device_path pub mod build; pub mod text;