diff mbox series

meta: u-boot: Provide option to install & deploy EFI capsules

Message ID 20250418152706.447180-1-w.egorov@phytec.de
State New
Headers show
Series meta: u-boot: Provide option to install & deploy EFI capsules | expand

Commit Message

Wadim Egorov April 18, 2025, 3:27 p.m. UTC
Add support for installing and deploying EFI capsule update archives,
which provide a standardized container for firmware update data.

By default, the feature is disabled. To enable it, set UBOOT_CAPSULE or
SPL_CAPSULE to the appropriate capsule file (e.g., uboot-capsule.bin or
tiboot3-capsule.bin).

This option is especially useful when a U-Boot build also generates
capsule binaries alongside the regular U-Boot binaries.

Signed-off-by: Wadim Egorov <w.egorov@phytec.de>
---
 meta/classes-recipe/uboot-config.bbclass |  16 +++
 meta/recipes-bsp/u-boot/u-boot.inc       | 146 +++++++++++++++++++++++
 2 files changed, 162 insertions(+)

Comments

Ross Burton April 24, 2025, 10:47 a.m. UTC | #1
On 18 Apr 2025, at 16:27, Wadim Egorov via lists.openembedded.org <w.egorov=phytec.de@lists.openembedded.org> wrote:
> Add support for installing and deploying EFI capsule update archives,
> which provide a standardized container for firmware update data.
> 
> By default, the feature is disabled. To enable it, set UBOOT_CAPSULE or
> SPL_CAPSULE to the appropriate capsule file (e.g., uboot-capsule.bin or
> tiboot3-capsule.bin).
> 
> This option is especially useful when a U-Boot build also generates
> capsule binaries alongside the regular U-Boot binaries.

meta-arm has a uefi_capsule class[1] which is similar but more generic: it’s an IMAGE_TYPE so you can give it arbitrary content.  Let’s not have two implementations: can you compare your implementation with the uefi_capsule class? Are they complementary or can we move uefi_capsule to core and extend it as needed?

Thanks,
Ross

[1] https://git.yoctoproject.org/meta-arm/tree/meta-arm/classes/uefi_capsule.bbclass
Wadim Egorov April 24, 2025, 1:25 p.m. UTC | #2
Am 24.04.25 um 13:47 schrieb Ross Burton:
> On 18 Apr 2025, at 16:27, Wadim Egorov via lists.openembedded.org <w.egorov=phytec.de@lists.openembedded.org> wrote:
>> Add support for installing and deploying EFI capsule update archives,
>> which provide a standardized container for firmware update data.
>>
>> By default, the feature is disabled. To enable it, set UBOOT_CAPSULE or
>> SPL_CAPSULE to the appropriate capsule file (e.g., uboot-capsule.bin or
>> tiboot3-capsule.bin).
>>
>> This option is especially useful when a U-Boot build also generates
>> capsule binaries alongside the regular U-Boot binaries.
> 
> meta-arm has a uefi_capsule class[1] which is similar but more generic: it’s an IMAGE_TYPE so you can give it arbitrary content.  Let’s not have two implementations: can you compare your implementation with the uefi_capsule class? Are they complementary or can we move uefi_capsule to core and extend it as needed?

I looked at the uefi_capsule class, but I was thinking I would rather 
use the artifacts that U-Boots binman tool produces.

Many K3 platform–based boards in U-Boot already generate capsules with 
binman. If we skip binman, those boards would need to keep metadata like 
the GUID in more than one place and likely make extra changes to feed 
uefi_capsule class.

IMO, U-Boot project knows best how to package its artifacts, so keeping 
those details in binman makes sense. Apart from that, both 
implementations could give us more or less identical results.

Regards,
Wadim

> 
> Thanks,
> Ross
> 
> [1] https://git.yoctoproject.org/meta-arm/tree/meta-arm/classes/uefi_capsule.bbclass
diff mbox series

Patch

diff --git a/meta/classes-recipe/uboot-config.bbclass b/meta/classes-recipe/uboot-config.bbclass
index f44605cb6a..b435e4d32f 100644
--- a/meta/classes-recipe/uboot-config.bbclass
+++ b/meta/classes-recipe/uboot-config.bbclass
@@ -52,6 +52,22 @@  SPL_BINARYNAME ?= "${@removesuffix(d.getVar("SPL_BINARYFILE"), "." + d.getVar("S
 SPL_IMAGE ?= "${SPL_BINARYNAME}-${MACHINE}-${PV}-${PR}${SPL_DELIMITER}${SPL_SUFFIX}"
 SPL_SYMLINK ?= "${SPL_BINARYNAME}-${MACHINE}${SPL_DELIMITER}${SPL_SUFFIX}"
 
+# Some versions of U-Boot also generate UEFI capsule update archives used for
+# updating the bootloader. These archives must be deployed alongside the
+# U-Boot binaries. For versions that support capsule updates, the following
+# variables can be set to enable packaging of the capsules.
+UBOOT_CAPSULE ?= ""
+UBOOT_CAPSULE_SUFFIX ?= "bin"
+UBOOT_CAPSULE_BINARYNAME ?= "${@os.path.splitext(d.getVar("UBOOT_CAPSULE"))[0]}"
+UBOOT_CAPSULE_IMAGE ?= "${UBOOT_CAPSULE_BINARYNAME}-${MACHINE}-${PV}-${PR}.${UBOOT_CAPSULE_SUFFIX}"
+UBOOT_CAPSULE_SYMLINK ?= "${UBOOT_CAPSULE_BINARYNAME}-${MACHINE}.${UBOOT_CAPSULE_SUFFIX}"
+
+SPL_CAPSULE ?= ""
+SPL_CAPSULE_SUFFIX ?= "bin"
+SPL_CAPSULE_BINARYNAME ?= "${@os.path.splitext(d.getVar("SPL_CAPSULE"))[0]}"
+SPL_CAPSULE_IMAGE ?= "${SPL_CAPSULE_BINARYNAME}-${MACHINE}-${PV}-${PR}.${SPL_CAPSULE_SUFFIX}"
+SPL_CAPSULE_SYMLINK ?= "${SPL_CAPSULE_BINARYNAME}-${MACHINE}.${SPL_CAPSULE_SUFFIX}"
+
 # Additional environment variables or a script can be installed alongside
 # u-boot to be used automatically on boot.  This file, typically 'uEnv.txt'
 # or 'boot.scr', should be packaged along with u-boot as well as placed in the
diff --git a/meta/recipes-bsp/u-boot/u-boot.inc b/meta/recipes-bsp/u-boot/u-boot.inc
index 9464736b84..e1ea62e979 100644
--- a/meta/recipes-bsp/u-boot/u-boot.inc
+++ b/meta/recipes-bsp/u-boot/u-boot.inc
@@ -176,6 +176,48 @@  do_install () {
         fi
     fi
 
+    if [ -n "${UBOOT_CAPSULE}" ]
+    then
+        if [ -n "${UBOOT_CONFIG}" ]
+        then
+            for config in ${UBOOT_MACHINE}; do
+                i=$(expr $i + 1);
+                for type in ${UBOOT_CONFIG}; do
+                    j=$(expr $j + 1);
+                    if [ $j -eq $i ]
+                    then
+                        uboot_install_capsule_config $config $type
+                    fi
+                done
+                unset j
+            done
+            unset i
+        else
+            uboot_install_capsule
+        fi
+    fi
+
+    if [ -n "${SPL_CAPSULE}" ]
+    then
+        if [ -n "${UBOOT_CONFIG}" ]
+        then
+            for config in ${UBOOT_MACHINE}; do
+                i=$(expr $i + 1);
+                for type in ${UBOOT_CONFIG}; do
+                    j=$(expr $j + 1);
+                    if [ $j -eq $i ]
+                    then
+                        uboot_install_spl_capsule_config $config $type
+                    fi
+                done
+                unset j
+            done
+            unset i
+        else
+            uboot_install_spl_capsule
+        fi
+    fi
+
     if [ -n "${UBOOT_ENV}" ]
     then
         install -m 644 ${B}/${UBOOT_ENV_BINARY} ${D}/boot/${UBOOT_ENV_IMAGE}
@@ -231,6 +273,34 @@  uboot_install_elf () {
     ln -sf ${UBOOT_ELF_IMAGE} ${D}/boot/${UBOOT_ELF_BINARY}
 }
 
+uboot_install_capsule_config () {
+    config=$1
+    type=$2
+
+    install -m 644 ${B}/${config}/${UBOOT_CAPSULE} ${D}/boot/${UBOOT_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${UBOOT_CAPSULE_SUFFIX}
+    ln -sf ${UBOOT_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${UBOOT_CAPSULE_SUFFIX} ${D}/boot/${UBOOT_CAPSULE}-${type}
+    ln -sf ${UBOOT_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${UBOOT_CAPSULE_SUFFIX} ${D}/boot/${UBOOT_CAPSULE}
+}
+
+uboot_install_capsule () {
+    install -m 644 ${B}/${UBOOT_CAPSULE} ${D}/boot/${UBOOT_CAPSULE_IMAGE}
+    ln -sf ${UBOOT_CAPSULE_IMAGE} ${D}/boot/${UBOOT_CAPSULE}
+}
+
+uboot_install_spl_capsule_config () {
+    config=$1
+    type=$2
+
+    install -m 644 ${B}/${config}/${SPL_CAPSULE} ${D}/boot/${SPL_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${SPL_CAPSULE_SUFFIX}
+    ln -sf ${SPL_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${SPL_CAPSULE_SUFFIX} ${D}/boot/${SPL_CAPSULE}-${type}
+    ln -sf ${SPL_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${SPL_CAPSULE_SUFFIX} ${D}/boot/${SPL_CAPSULE}
+}
+
+uboot_install_spl_capsule () {
+    install -m 644 ${B}/${SPL_CAPSULE} ${D}/boot/${SPL_CAPSULE_IMAGE}
+    ln -sf ${SPL_CAPSULE_IMAGE} ${D}/boot/${SPL_CAPSULE}
+}
+
 uboot_install_spl_config () {
     config=$1
     type=$2
@@ -309,6 +379,47 @@  do_deploy () {
         fi
     fi
 
+    if [ -n "${UBOOT_CAPSULE}" ]
+    then
+        if [ -n "${UBOOT_CONFIG}" ]
+        then
+            for config in ${UBOOT_MACHINE}; do
+                i=$(expr $i + 1);
+                for type in ${UBOOT_CONFIG}; do
+                    j=$(expr $j + 1);
+                    if [ $j -eq $i ]
+                    then
+                        uboot_deploy_capsule_config $config $type
+                    fi
+                done
+                unset j
+            done
+            unset i
+        else
+            uboot_deploy_capsule
+        fi
+    fi
+
+    if [ -n "${SPL_CAPSULE}" ]
+     then
+        if [ -n "${UBOOT_CONFIG}" ]
+        then
+            for config in ${UBOOT_MACHINE}; do
+                i=$(expr $i + 1);
+                for type in ${UBOOT_CONFIG}; do
+                    j=$(expr $j + 1);
+                    if [ $j -eq $i ]
+                    then
+                        uboot_deploy_spl_capsule_config $config $type
+                    fi
+                done
+                unset j
+            done
+            unset i
+        else
+            uboot_deploy_spl_capsule
+        fi
+    fi
 
      if [ -n "${SPL_BINARY}" ]
      then
@@ -405,6 +516,23 @@  uboot_deploy_elf () {
     ln -sf ${UBOOT_ELF_IMAGE} ${DEPLOYDIR}/${UBOOT_ELF_SYMLINK}
 }
 
+uboot_deploy_capsule_config () {
+    config=$1
+    type=$2
+
+    install -m 644 ${B}/${config}/${UBOOT_CAPSULE} ${DEPLOYDIR}/${UBOOT_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${UBOOT_CAPSULE_SUFFIX}
+    ln -sf ${UBOOT_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${UBOOT_CAPSULE_SUFFIX} ${DEPLOYDIR}/${UBOOT_CAPSULE}-${type}
+    ln -sf ${UBOOT_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${UBOOT_CAPSULE_SUFFIX} ${DEPLOYDIR}/${UBOOT_CAPSULE}
+    ln -sf ${UBOOT_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${UBOOT_CAPSULE_SUFFIX} ${DEPLOYDIR}/${UBOOT_CAPSULE_SYMLINK}-${type}
+    ln -sf ${UBOOT_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${UBOOT_CAPSULE_SUFFIX} ${DEPLOYDIR}/${UBOOT_CAPSULE_SYMLINK}
+}
+
+uboot_deploy_capsule () {
+    install -m 644 ${B}/${UBOOT_CAPSULE} ${DEPLOYDIR}/${UBOOT_CAPSULE_IMAGE}
+    ln -sf ${UBOOT_CAPSULE_IMAGE} ${DEPLOYDIR}/${UBOOT_CAPSULE}
+    ln -sf ${UBOOT_CAPSULE_IMAGE} ${DEPLOYDIR}/${UBOOT_CAPSULE_SYMLINK}
+}
+
 uboot_deploy_spl_config () {
     config=$1
     type=$2
@@ -423,4 +551,22 @@  uboot_deploy_spl () {
     ln -sf ${SPL_IMAGE} ${DEPLOYDIR}/${SPL_SYMLINK}
 }
 
+uboot_deploy_spl_capsule_config () {
+    config=$1
+    type=$2
+
+    install -m 644 ${B}/${config}/${SPL_CAPSULE} ${DEPLOYDIR}/${SPL_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${SPL_CAPSULE_SUFFIX}
+    rm -f ${DEPLOYDIR}/${SPL_CAPSULE_BINARYFILE} ${DEPLOYDIR}/${SPL_CAPSULE_SYMLINK}
+    ln -sf ${SPL_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${SPL_CAPSULE_SUFFIX} ${DEPLOYDIR}/${SPL_CAPSULE_BINARYFILE}-${type}
+    ln -sf ${SPL_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${SPL_CAPSULE_SUFFIX} ${DEPLOYDIR}/${SPL_CAPSULE_BINARYFILE}
+    ln -sf ${SPL_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${SPL_CAPSULE_SUFFIX} ${DEPLOYDIR}/${SPL_CAPSULE_SYMLINK}-${type}
+    ln -sf ${SPL_CAPSULE_BINARYNAME}-${type}-${PV}-${PR}.${SPL_CAPSULE_SUFFIX} ${DEPLOYDIR}/${SPL_CAPSULE_SYMLINK}
+}
+
+uboot_deploy_spl_capsule () {
+    install -m 644 ${B}/${SPL_CAPSULE} ${DEPLOYDIR}/${SPL_CAPSULE_IMAGE}
+    ln -sf ${SPL_CAPSULE_IMAGE} ${DEPLOYDIR}/${SPL_CAPSULE}
+    ln -sf ${SPL_CAPSULE_IMAGE} ${DEPLOYDIR}/${SPL_CAPSULE_SYMLINK}
+}
+
 addtask deploy before do_build after do_compile