mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
FmpDevicePkg: Improve library documentation
Adds a ReadMe.md to each library instance and updates FmpDevicePkg_ReadMe.md to reference available library documentation. Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
This commit is contained in:
parent
82cfea329c
commit
9377d47f1a
8 changed files with 273 additions and 9 deletions
|
|
@ -1,6 +1,6 @@
|
|||
## @file
|
||||
# Produce the Capsule Update Policy Protocol using the services of the Capsule
|
||||
# Update Policy Library.
|
||||
# Produce the Capsule Update Policy Protocol (EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL) using
|
||||
# the services of the Capsule Update Policy Library.
|
||||
#
|
||||
# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
|
|
|
|||
105
FmpDevicePkg/FmpDxe/ReadMe.md
Normal file
105
FmpDevicePkg/FmpDxe/ReadMe.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Firmware Management Protocol (FMP) DXE
|
||||
|
||||
For an overview of how FmpDxe fits into the overall FmpDevicePkg architecture, including capsule authentication, capsule
|
||||
versioning, device-specific dispatch, dependency evaluation, and update policy, see
|
||||
[FmpDevicePkg/Docs/FmpDevicePkg_ReadMe.md](../Docs/FmpDevicePkg_ReadMe.md).
|
||||
|
||||
This document tracks impactful design changes to FmpDxe for the benefit of capsule implementers and platform integrators
|
||||
to see when and why these changes were made.
|
||||
|
||||
---
|
||||
|
||||
## Design Changes
|
||||
|
||||
- **Date:** 07/20/2026
|
||||
- **Description/Rationale:** PopulateDescriptor () previously read the FmpControllerState NV variable multiple times
|
||||
per call through several getters such as GetVersionFromVariable () and GetLowestSupportedVersionFromVariable (),
|
||||
each independently invoking GetFmpControllerState (). This caused redundant GetVariable () calls and repeated
|
||||
failed-read debug messages when the variable did not yet exist.
|
||||
- **Changes:** The getter functions were renamed (for example, to GetVersionFromFmpControllerState ()) and
|
||||
simplified to pure field extractors that operate on a FMP_CONTROLLER_STATE pointer supplied by the caller instead of
|
||||
independently reading the variable. PopulateDescriptor () now calls GetFmpControllerState () once, passes the result
|
||||
to each getter, and frees it after the last use.
|
||||
- **Impact/Mitigation:**
|
||||
This is an internal implementation change local to FmpDxe. It does not modify the FmpDeviceLib, FmpDependencyLib,
|
||||
FmpDependencyCheckLib, FmpDependencyDeviceLib, or CapsuleUpdatePolicyLib APIs, so existing library instances are
|
||||
unaffected.
|
||||
|
||||
---
|
||||
|
||||
- **Date:** 09/24/2025
|
||||
- **Description/Rationale:** XDR-encoded certificate list handling in FmpDxe assumed the PublicKeyDataXdr buffer
|
||||
(populated from PcdFmpDevicePkcs7CertBufferXdr) is 4-byte aligned, which is not always the case. For example, if
|
||||
PublicKeyDataXdr = 0x02 and a certificate's length is 0x05, the correct offset to the next certificate is
|
||||
0x2 + align_up (0x5, 4) = 0xA, but the prior logic computed align_up (0x2 + 0x5, 4) = 0x8.
|
||||
- **Changes:** The offset calculation used to walk the XDR-encoded certificate list was corrected to align up each
|
||||
certificate's length independently rather than aligning the running (potentially already unaligned) offset.
|
||||
- **Impact/Mitigation:**
|
||||
Platforms that supply a PcdFmpDevicePkcs7CertBufferXdr value containing more than one certificate, where an earlier
|
||||
certificate's length is not a multiple of 4 bytes, will see corrected certificate parsing behavior.
|
||||
|
||||
---
|
||||
|
||||
- **Date:** 01/20/2022
|
||||
- **Description/Rationale:** CheckTheImageInternal () did not force ImageUpdatable to an invalid value when
|
||||
FmpDeviceCheckImageWithStatus () returned an error but left ImageUpdatable set to IMAGE_UPDATABLE_VALID. In addition,
|
||||
the FmpDeviceCheckImageWithStatus () LastAttemptStatus parameter description could be misread as meaning the value
|
||||
is only inspected when the function returns an error.
|
||||
- **Changes:** CheckTheImageInternal () now forces ImageUpdatable to IMAGE_UPDATABLE_INVALID if
|
||||
FmpDeviceCheckImageWithStatus () returns an error, and only validates/converts the returned LastAttemptStatus value
|
||||
when the image is not updatable so a valid LAST_ATTEMPT_STATUS_SUCCESS is not overwritten for an updatable image.
|
||||
The API documentation for FmpDeviceCheckImageWithStatus () was updated to remove the sentence limiting
|
||||
LastAttemptStatus inspection to error cases.
|
||||
- **Impact/Mitigation:**
|
||||
FmpDeviceLib instances should always set LastAttemptStatus to a value in the designated range (or
|
||||
LAST_ATTEMPT_STATUS_SUCCESS) whenever FmpDeviceCheckImageWithStatus () is called, not only when it returns an error.
|
||||
|
||||
---
|
||||
|
||||
- **Date:** 10/26/2021
|
||||
- **Description/Rationale:** FmpDxe used the deprecated EDKII_VARIABLE_LOCK_PROTOCOL (RequestToLock ()) to lock its
|
||||
NV variables.
|
||||
- **Changes:** FmpDxe was updated to lock its NV variables using EDKII_VARIABLE_POLICY_PROTOCOL and
|
||||
RegisterBasicVariablePolicy () from the new VariablePolicyHelperLib dependency. The module Depex was intended to
|
||||
change from gEdkiiVariableLockProtocolGuid to gEdkiiVariablePolicyProtocolGuid at the same time. This was missed and
|
||||
corrected in a follow-up fix on 07/09/2024.
|
||||
- **Impact/Mitigation:**
|
||||
Platforms must produce gEdkiiVariablePolicyProtocolGuid for FmpDxe to start. Platforms that only produce the
|
||||
deprecated gEdkiiVariableLockProtocolGuid protocol will need to update their variable services accordingly.
|
||||
|
||||
---
|
||||
|
||||
- **Date:** 06/15/2020
|
||||
- **Description/Rationale:** Extending on the more granular LastAttemptStatus support added in FmpDeviceSetImage (),
|
||||
FmpDeviceCheckImage () also has a LastAttemptStatus parameter added. An image check is always performed by a set
|
||||
image operation. A more granular status code from the check image path greatly improves overall error isolation when
|
||||
applying an image.
|
||||
- **Changes:** This change allows the FmpDeviceLib implementation to return a last attempt status code in the range
|
||||
LAST_ATTEMPT_STATUS_LIBRARY_ERROR_MIN_ERROR_CODE to LAST_ATTEMPT_STATUS_LIBRARY_ERROR_MAX_ERROR_CODE. Furthermore,
|
||||
an internal wrapper for CheckTheImage () in FmpDxe was added called CheckTheImageInternal (). This function can return
|
||||
a last attempt status code for an error in the driver prior to invoking FmpDeviceCheckImage (). These driver error
|
||||
codes will be in the range of LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL_VENDOR_RANGE_MIN to
|
||||
LAST_ATTEMPT_STATUS_DRIVER_ERROR_MAX_ERROR_CODE.
|
||||
- **Impact/Mitigation:**
|
||||
The change break the build for all FmpDeviceLib instances due to the API change. Each FmpDeviceLib should change to
|
||||
the new API definition and implement support to return unique values for LastAttemptStatus when appropriate.
|
||||
|
||||
---
|
||||
|
||||
- **Date:** 10/07/2019
|
||||
- **Description/Rationale:** Capsule update is the process where each OEM has a lot of interest. Especially when there
|
||||
is capsule update failure, it is helpful to gather more information of the failure. With existing implementations, the
|
||||
SetImage routine from FmpDxe driver, which performs most heavy lifting during capsule update, will only
|
||||
populate LastAttemptStatus with limited pre-defined error codes which could be consumed/inspected by the OS when it
|
||||
recovers and boots. Thus our proposal is to update the SetImage routine and leverage the
|
||||
LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL_VENDOR_RANGE range newly defined in UEFI Spec 2.8 Section 23.4, so that the
|
||||
error code will provide better granularity when viewing capsule update failure from OS device manager.
|
||||
- **Changes:** A few error codes (128 total) are reserved from LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL_VENDOR_RANGE
|
||||
range for FmpDxe driver usage, which ranges from thermal and power API failure to capsule payload header check failure.
|
||||
Furthermore, *an output pointer of the LastAttemptStatus is added as an input argument for FmpDeviceSetImage function
|
||||
in FmpDeviceLib to allow platform to provide their own platform specific error codes*.
|
||||
(SPI write failure, SVN checking failure, and more).
|
||||
- **Impact/Mitigation:**
|
||||
The italic text above will cause a breaking change for all the FmpDeviceLib instances due to API being modified. This
|
||||
is to provide better visibility to OEMs to decode capsule update failures more efficiently. Each FmpDeviceLib should
|
||||
change to the new API definition and populate proper LastAttemptStatus values when applicable.
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
## @file
|
||||
# Provides platform policy services used during a capsule update.
|
||||
#
|
||||
# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
|
||||
# This is a NULL instance used for building when an actual instance
|
||||
# is not needed.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.<BR>
|
||||
# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
## @file
|
||||
# Provides platform policy services used during a capsule update that uses the
|
||||
# services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL. If the
|
||||
# EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL is not available, then assume the
|
||||
# platform is in a state that supports a firmware update.
|
||||
# services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL.
|
||||
#
|
||||
# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
|
||||
# If the protocol is not found, CheckSystemPower(), CheckSystemThermal(),
|
||||
# and CheckSystemEnvironment() assume the platform state supports a
|
||||
# capsule update, while IsLowestSupportedVersionCheckRequired() and
|
||||
# IsLockFmpDeviceAtLockEventGuidRequired() default to TRUE so the lowest
|
||||
# supported version check and FMP device locking are still performed.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.<BR>
|
||||
# Copyright (c) 2018-2019, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@
|
|||
# Provides FMP capsule dependency check services when updating the firmware
|
||||
# image of a FMP device.
|
||||
#
|
||||
# This library locates each installed Firmware Management Protocol
|
||||
# instance, collects its image type and version, and uses
|
||||
# FmpDependencyLib to evaluate the dependency expression associated with
|
||||
# the firmware image being updated.
|
||||
#
|
||||
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
|
|
|||
|
|
@ -1,5 +1,18 @@
|
|||
## @file
|
||||
# Provides Fmp Capsule Dependency Expression support.
|
||||
# Provides FMP Capsule Dependency Expression support.
|
||||
#
|
||||
# This library validates a dependency expression, extracts a dependency
|
||||
# expression from a firmware image, and evaluates a dependency expression
|
||||
# against the versions of other installed Firmware Management Protocol
|
||||
# instances.
|
||||
#
|
||||
# A dependency expression is a byte stream of opcodes, as defined by the
|
||||
# FMP capsule dependency format in the UEFI Specification. EvaluateDependency()
|
||||
# in this library walks this byte stream and, when it encounters a PUSH_GUID
|
||||
# opcode, requires the caller to have supplied the matching FMP instance's
|
||||
# ImageTypeId and Version in the FmpVersions array. If a PUSH_GUID opcode refers
|
||||
# to an FMP instance that is not present in FmpVersions, the dependency expression
|
||||
# evaluates to FALSE.
|
||||
#
|
||||
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
# Provides firmware device specific services to support updates of a firmware
|
||||
# image stored in a firmware device.
|
||||
#
|
||||
# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
|
||||
# This is a NULL instance used for building when an actual instance is not needed.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.<BR>
|
||||
# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
|
|
|||
132
FmpDevicePkg/Readme.md
Normal file
132
FmpDevicePkg/Readme.md
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
# Firmware Management Protocol (FMP) Device Package
|
||||
|
||||
FmpDevicePkg provides the common resources necessary to manage the firmware on a given device. The
|
||||
[UEFI Specification](https://uefi.org/specifications) defines several elements used in the firmware management process
|
||||
that are implemented or depended upon in FmpDevicePkg such as:
|
||||
|
||||
1. [`EFI_FIRMWARE_MANAGEMENT_PROTOCOL`](https://github.com/tianocore/edk2/blob/HEAD/MdePkg/Include/Protocol/FirmwareManagement.h)
|
||||
2. Firmware Management Protocol dependency expression support
|
||||
3. FMP capsule format
|
||||
4. EFI System Resource Table (ESRT)
|
||||
|
||||
## Architecture
|
||||
|
||||
`FmpDxe` is the central driver in `FmpDevicePkg`. It produces the Firmware Management Protocol
|
||||
(`EFI_FIRMWARE_MANAGEMENT_PROTOCOL`) and coordinates with the supporting modules and libraries listed later in this
|
||||
document to carry out a firmware update. This section describes the high level design of that update flow.
|
||||
|
||||
### Capsule Authentication
|
||||
|
||||
The firmware update capsule must be signed. FmpDxe verifies the integrity of the capsule contents. The
|
||||
actual capsule data is preceded by an `EFI_FIRMWARE_IMAGE_AUTHENTICATION` structure. This structure contains a
|
||||
monotonic count and a `WIN_CERTIFICATE_UEFI_GUID` member that contains a signature that covers both the monotonic
|
||||
count and the capsule payload data. These two elements ensure replay protection across update operations and
|
||||
authentication. The certificate type used must be `EFI_CERT_TYPE_PKCS7_GUID`.
|
||||
|
||||
An EDK II implementation of signature verification is available in the following `FmpAuthenticationLib` instance:
|
||||
[SecurityPkg/Library/FmpAuthenticationLibPkcs7](https://github.com/tianocore/edk2/tree/master/SecurityPkg/Library/FmpAuthenticationLibPkcs7).
|
||||
|
||||
### Capsule Versioning
|
||||
|
||||
The capsule version should only be allowed to increment in value across updates to prevent rollback attacks. The
|
||||
`EFI_FIRMWARE_IMAGE_DESCRIPTOR` structure contains `Version` and `LowestSupportedImageVersion` fields that are used
|
||||
to check for compliance during firmware update. `Version` must be greater than or equal to `LowestSupportedImageVersion`
|
||||
in the current firmware and greater than `Version` of the current firmware.
|
||||
|
||||
`FmpDxe` performs this check directly. The value used for `LowestSupportedImageVersion` is the greatest of the
|
||||
build-time `PcdFmpDeviceBuildTimeLowestSupportedVersion` PCD value, the value returned by the `FmpDeviceLib`
|
||||
instance's `FmpDeviceGetLowestSupportedVersion()` function, and the lowest supported version most recently saved
|
||||
from an applied capsule's FMP Payload Header.
|
||||
|
||||
### Device-Specific Functionality During Update
|
||||
|
||||
A capsule can target firmware update to a diverse set of devices on a system. Each device might bring unique logic
|
||||
and requirements to the firmware update process. Therefore, a library class called `FmpDeviceLib` exists that allows
|
||||
for instances written specific to a particular device.
|
||||
|
||||
### Dependency Considerations
|
||||
|
||||
The UEFI Specification 2.8 version introduced support for expressing dependencies between components involved in a
|
||||
capsule update. For instance, FW`x` can require FW`y` to be at least version 2.0 to install. This information is
|
||||
primarily conveyed to `FmpDxe` through the `FmpDependencyCheckLib` and `FmpDependencyLib` library classes.
|
||||
|
||||
More information about the overall infrastructure is available in:
|
||||
|
||||
- The [UEFI Specification](https://uefi.org/specifications) - "Firmware Update and Reporting" section.
|
||||
- [TianoCore Wiki: FMP Capsule Dependency Introduction](https://www.tianocore.org/tianocore-wiki.github.io/development/tutorials-howto/fmp_capsule_dependency_introduction.html)
|
||||
|
||||
### Update Policy
|
||||
|
||||
A library class (`CapsuleUpdatePolicyLib`) is used to make platform-specific policy decisions available to the
|
||||
firmware update process. This includes information such as whether the system power/thermal state permits firmware
|
||||
to be updated. A few functions also exist to modify expected behavior such as ignoring the
|
||||
`LowestSupportedImageVersion` check or not locking the firmware device for update when the FMP lock event is signaled.
|
||||
It is important to note that the latter functions should only be used in very rare special cases such as during
|
||||
manufacturing flows.
|
||||
|
||||
## Package Organization
|
||||
|
||||
This section briefly describes the package modules and libraries.
|
||||
|
||||
### Modules
|
||||
|
||||
1. **CapsuleUpdatePolicyDxe**
|
||||
- **Purpose:** Produces the Capsule Update Policy Protocol using the services of the Capsule Update Policy Library.
|
||||
2. **FmpDxe** [readme](FmpDxe/Readme.md)
|
||||
- **Purpose:** Produces an instance of the Firmware Management Protocol (`EFI_FIRMWARE_MANAGEMENT_PROTOCOL`) that is
|
||||
used to support updates to a firmware image stored on a firmware device
|
||||
|
||||
### Libraries
|
||||
|
||||
1. **CapsuleUpdatePolicyLib**
|
||||
- **Purpose:** Provides platform policy services used during a capsule update.
|
||||
- **Instances:**
|
||||
1. CapsuleUpdatePolicyLibNull
|
||||
2. CapsuleUpdatePolicyLibOnProtocol
|
||||
2. **FmpDependencyCheckLib**
|
||||
- **Purpose:** Provides services to check that capsule dependencies are met during firmware update.
|
||||
- **Instances:**
|
||||
1. FmpDependencyCheckLib
|
||||
2. FmpDependencyCheckLibNull
|
||||
3. **FmpDependencyDeviceLib**
|
||||
- **Purpose:** Provides firmware device specific services to support saving dependency expressions to a firmware
|
||||
device and getting dependency expressions from a firmware device.
|
||||
- **Instances:**
|
||||
1. FmpDependencyDeviceLibNull
|
||||
4. **FmpDependencyLib**
|
||||
- **Purpose:** Provides functions used to manage dependencies between firmware components during the update of device firmware
|
||||
images.
|
||||
- **Instances:**
|
||||
1. FmpDependencyLib
|
||||
5. **FmpDeviceLib**
|
||||
- **Purpose:** Provides firmware device specific services to support firmware updates on a given device.
|
||||
- **Instances:**
|
||||
1. FmpDeviceLibNull
|
||||
6. **FmpPayloadHeaderLib**
|
||||
- **Purpose:** Provides services to retrieve values from a capsule FMP Payload Header.
|
||||
- **Instances:**
|
||||
1. FmpPayloadHeaderLibV1
|
||||
|
||||
## Further Reading
|
||||
|
||||
Several documents describe important elements involved in understanding `FmpDevicePkg`. Consult the following
|
||||
resource for more information on a particular topic.
|
||||
|
||||
1. `FmpDevicePkg` Overview
|
||||
1. The Readme documents in this package.
|
||||
2. [TianoCore Wiki: FmpDevicePkg](https://www.tianocore.org/tianocore-wiki.github.io/platforms-packages/core-packages/fmp_device_pkg.html)
|
||||
|
||||
2. UEFI Specification Definitions for Firmware Updating and Reporting
|
||||
1. [UEFI Specification - Firmware Update and Reporting](https://uefi.org/specifications)
|
||||
|
||||
3. Technical Overview of the EDK II Capsule Update and Recovery Flow
|
||||
1. [A Tour Beyond BIOS - Capsule Update and Recovery in EDK II](https://github.com/tianocore-docs/Docs/blob/master/White_Papers/A_Tour_Beyond_BIOS_Capsule_Update_and_Recovery_in_EDK_II.pdf)
|
||||
|
||||
4. Windows UEFI Firmware Update Resources
|
||||
1. [Windows UEFI Firmware Update Platform](https://docs.microsoft.com/windows-hardware/drivers/bringup/windows-uefi-firmware-update-platform)
|
||||
2. [Validating Windows UEFI Firmware Update Platform Functionality](https://docs.microsoft.com/windows-hardware/manufacture/desktop/validating-windows-uefi-firmware-update-platform-functionality)
|
||||
|
||||
5. NIST Guidelines for Authenticated Firmware Update
|
||||
1. [SP800-147](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-147.pdf)
|
||||
2. [SP800-147B](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-147B.pdf)
|
||||
3. [SP800-193](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-193.pdf)
|
||||
Loading…
Add table
Add a link
Reference in a new issue