uefi-rs

repository·main·Indexed 23 days ago

https://github.com/rust-osdev/uefi-rs

A collection of Rust crates providing safe, high-level abstractions for the Unified Extensible Firmware Interface (UEFI). It includes the primary 'uefi' wrapper for convenient functionality, 'uefi-raw' for ABI-compatible types matching the UEFI Specification, 'uefi-macros' for reducing boilerplate, and 'uefi-test-runner' for integration testing in QEMU. The project supports x86_64, ia32, and aarch64 architectures.

Tokens
34.2K
Snippets
54
Records
186
Agent score
81%

What's inside uefi-rs

  1. Overview of uefi-rs crates

    main

    The uefi-rs repository is a collection of crates designed to provide safe and performant Rust abstractions for the Unified Extensible Firmware Interface (UEFI).

    Key components include:

    • uefi: The primary high-level wrapper providing safe, convenient abstractions for UEFI functionality.
    • uefi-raw: Provides raw ABI-compatible types that match the UEFI Specification. Use this for implementing firmware or creating low-level interfaces.
    • uefi-macros: Helper macros used by the uefi crate.
    • uefi-test-runner: A UEFI application used to run integration tests.
    • uefi-std-example: A minimal UEFI application implemented as a standard Rust binary.
  2. Introduction to creating a UEFI application in Rust

    main
    This tutorial provides a high-level overview of the workflow for developing a simple x86_64 UEFI application using uefi-rs. The goal is to create an application that prints a message to the console, pauses for a specified duration (e.g., 10 seconds), and then exits gracefully.
  3. Use the `uefi` crate for UEFI development

    main

    The uefi crate provides safe, convenient, and performant Rust abstractions for the Unified Extensible Firmware Interface (UEFI). It is designed for writing software that interacts with UEFI boot services, but it can also be used for specific tasks like parsing the UEFI memory map.

    To produce UEFI images, you must use a compatible Rust compiler target, such as x86_64-unknown-uefi.

  4. Use the HTTPS CA certificate database

    main
    The uefi-test-runner provides an HTTPS CA certificate database in the EFI signature list format. This database is a copy of the Mozilla Foundation CA certificate list (originally from CentOS Stream 9's /etc/pki/ca-trust/extracted/edk2/cacerts.bin) and is licensed under MIT AND GPL-2.0-or-later.
  5. Understand UEFI variable attributes

    main

    Variables are controlled by bit-flag attributes that determine their accessibility and persistence. When creating or accessing variables, you must consider these primary attributes:

    Access Control

    • BOOTSERVICE_ACCESS and RUNTIME_ACCESS: If both bits are set, the variable is accessible during both the Boot Services and Runtime stages. If only BOOTSERVICE_ACCESS is set, the variable becomes inaccessible after exiting boot services.

    Persistence

    • NON_VOLATILE:
      • If set: The variable is stored in non-volatile memory and persists across power cycles.
      • If not set: The variable is stored in normal memory and is lost when power is cycled.

    Warning: Use NON_VOLATILE storage sparingly. Non-volatile storage is often limited in size. Overfilling this storage can lead to system instability or even prevent the machine from booting on some UEFI implementations.

  6. Pointer mutability conventions in `uefi-raw`

    main

    In uefi-raw, pointer mutability is used for semantics rather than strictly enforcing Rust's safety rules. Follow these rules when interacting with the API:

    • Struct Fields: Pointer fields in structs should always be *mut. This ensures the types are usable for UEFI implementations that may need to mutate data.
    • Function Parameters:
      • Use *mut for OUT or IN OUT parameters.
      • Use *const for IN parameters if they are described as source data, though *mut is also acceptable.
    • Function Pointers: Must be unsafe and include an explicit ABI (typically efiapi). If a function pointer can be null, it is wrapped in an Option.
  7. Identify and use the EFI System Partition (ESP)

    main

    The EFI System Partition (ESP) is the UEFI version of a bootable partition. It is used to store boot files and is identified by a specific partition type GUID.

    Key characteristics of the ESP:

    • Partition Type GUID: c12a7328-f81f-11d2-ba4b-00a0c93ec93b
    • File System: Must always contain a FAT file system.
    • Boot Path: Standardized boot files are located under the \EFI\BOOT directory.
  8. Understand the UEFI boot stages

    main

    A UEFI system operates in three distinct phases. Understanding these is critical for knowing which uefi crate modules are available to your application at any given time:

    1. Platform Initialization: The earliest phase, handled by the hardware/firmware before the uefi crate takes control. This is outside the scope of uefi-rs.
    2. Boot Services: The phase where UEFI drivers and applications are loaded. During this stage, you have access to both the boot module and the runtime module. This stage ends when boot::exit_boot_services is called.
    3. Runtime: The phase active when an operating system (like Linux or Windows) is running. In this mode, UEFI functionality is limited. You cannot use functions from the boot module, but functions in the runtime module remain available. Once the system enters Runtime mode, it cannot return to Boot Services until a system reset occurs.
  9. Understand GPT (GUID Partition Table) structure

    main

    GPT is a modern partition table standard used by UEFI. It provides a precise specification and supports large disks and many partitions.

    A GPT disk is structured as follows:

    1. Primary Header: Located near the beginning of the disk.
    2. Partition Entry Array: Contains structures describing each partition (including a unique GUID, a partition type GUID, and start/end block addresses).
    3. Partition Data: The actual data for each partition, located between the entry arrays.
    4. Redundancy: A secondary copy of both the header and the partition entry array is stored at the end of the disk for recovery purposes.