Add UEFI FMP capsule generation-related recipes#1751
Add UEFI FMP capsule generation-related recipes#1751ricardosalveti merged 7 commits intoqualcomm-linux:masterfrom
Conversation
e3d1784 to
8910cf6
Compare
|
We should also coordinate with the debian efforts here (@lool / @basak-qcom / @gagath), since the generation and usage should be similar. |
quaresmajose
left a comment
There was a problem hiding this comment.
With the use of some recipes from meta-arm we should move the news ones who depend on them to dynamic layers bucause meta-arm layer is optional.
8910cf6 to
bf4d648
Compare
19eff2f to
7250f77
Compare
|
I've addressed most of the comments; please take another look.
I've tried to address it in a bit different way (not sure if it might be consdered as correct approach, but CI pipelines don't fail anymore) in: commit f531d46e58b5e1ca529fc07d1ad239c1b36e3f10
Author: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Date: Mon Mar 16 14:42:19 2026 +0100
firmware-qcom-capsule: skip when meta-arm layer is absent
edk2-basetools-native (GenFfs, GenFv, GenerateCapsule.py) is only
provided by meta-arm. Without it capsule assembly cannot complete.
Move the edk2-basetools-native DEPENDS out of cbsp-boot-utilities-native
into a dynamic-layers bbappend so it is only pulled in when meta-arm is
active. Add a python() guard to firmware-qcom-capsule that raises
SkipRecipe when meta-arm is not in BBFILE_COLLECTIONS, giving a clear
error instead of an unresolvable dependency chain.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com> |
…toolkit
Add a new native recipe that fetches cbsp-boot-utilities [1] and installs the
uefi_capsule_generation/ Python scripts to the native sysroot under
${datadir}/cbsp-boot-utilities/.
[1] https://github.com/quic/cbsp-boot-utilities
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
bfcb106 to
b1b261e
Compare
b1b261e to
9d578b9
Compare
9d578b9 to
01e1bd9
Compare
|
Can you add one extra entry at https://github.com/qualcomm-linux/meta-qcom/blob/master/.github/workflows/build-yocto.yml#L278 so we can build-test this in our CI as well? Fine to build for just one machine for now (and nodistro is probably enough). |
|
@ricardosalveti done! |
quaresmajose
left a comment
There was a problem hiding this comment.
I don't know if my suggestions will work, but I think they simplified things and removed some inline Python that's always heavy for Bitbake to parse.
Test run workflowTest jobs for commit 02fa764
All jobs summary
|
Add test keys to ci/test-keys/ so they are clearly scoped to CI/development
use and not accidentally treated as a default for production builds.
Add ci/capsule-test-keys.yml, a kas overlay that sets CAPSULE_ROOT_CER,
CAPSULE_CERT_PEM, CAPSULE_ROOT_PUB and CAPSULE_SUB_PUB to the test keys.
Keys are located via META_QCOM_DIR (added to conf/layer.conf), which
captures the layer root at parse time and is independent of the kas
project-directory layout.
The test keys under ci/test-keys/ were generated with the following
procedure:
export FMP_ROOT_CERT_SUBJECT="/CN=OEM Root CA/O=FMP/OU=OEM Key/L=San Diego/ST=California/C=US"
export FMP_CA_CERT_SUBJECT="/CN=OEM Intermediate CA/O=FMP/OU=OEM Key/L=San Diego/ST=California/C=US"
export FMP_USER_CERT_SUBJECT="/CN=OEM User/O=FMP/OU=OEM Key/L=San Diego/ST=California/C=US"
export FMP_KEY_PASSWORD="testpassword"
mkdir -p demoCA
mkdir -p demoCA/newcerts
touch demoCA/index.txt
echo 01 > demoCA/serial
cp ${REP_ROOT}/.github/opensslroot.cfg ./
dd if=/dev/urandom of=randfile bs=256 count=1 > /dev/null 2>&1
openssl genrsa -aes256 -passout "pass:${FMP_KEY_PASSWORD}" -out QcFMPRoot.key 2048
openssl req -new -x509 -config opensslroot.cfg -subj "${FMP_ROOT_CERT_SUBJECT}" -days 3650 \
-passin "pass:${FMP_KEY_PASSWORD}" -key QcFMPRoot.key -out QcFMPRoot.crt
openssl x509 -in QcFMPRoot.crt -out QcFMPRoot.cer -outform DER
openssl x509 -inform DER -in QcFMPRoot.cer -outform PEM -out QcFMPRoot.pub.pem
openssl genrsa -aes256 -passout "pass:${FMP_KEY_PASSWORD}" -out QcFMPSub.key 2048
openssl req -new -config opensslroot.cfg -subj "${FMP_CA_CERT_SUBJECT}" \
-passin "pass:${FMP_KEY_PASSWORD}" -key QcFMPSub.key -out QcFMPSub.csr
openssl ca -config opensslroot.cfg -extensions v3_ca -batch \
-in QcFMPSub.csr -days 3650 -out QcFMPSub.crt -cert QcFMPRoot.crt \
-passin "pass:${FMP_KEY_PASSWORD}" -keyfile QcFMPRoot.key
openssl x509 -in QcFMPSub.crt -out QcFMPSub.cer -outform DER
openssl x509 -inform DER -in QcFMPSub.cer -outform PEM -out QcFMPSub.pub.pem
openssl genrsa -aes256 -passout "pass:${FMP_KEY_PASSWORD}" -out QcFMPCert.key 2048
openssl req -new -config opensslroot.cfg -subj "${FMP_USER_CERT_SUBJECT}" \
-passin "pass:${FMP_KEY_PASSWORD}" -key QcFMPCert.key -out QcFMPCert.csr
openssl ca -config opensslroot.cfg -batch -in QcFMPCert.csr -days 3650 \
-out QcFMPCert.crt -cert QcFMPSub.crt -passin "pass:${FMP_KEY_PASSWORD}" -keyfile QcFMPSub.key
openssl x509 -in QcFMPCert.crt -out QcFMPCert.cer -outform DER
openssl x509 -inform DER -in QcFMPCert.cer -outform PEM -out QcFMPCert.pub.pem
openssl pkcs12 -export -passout "pass:${FMP_KEY_PASSWORD}" -out QcFMPCert.pfx \
-passin "pass:${FMP_KEY_PASSWORD}" -inkey QcFMPCert.key -in QcFMPCert.crt
openssl pkcs12 -passin "pass:${FMP_KEY_PASSWORD}" -in QcFMPCert.pfx -nodes \
-out QcFMPCert.pem
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Add a qcom-capsule class and a firmware-qcom-capsule reference
recipe that automates UEFI FMP capsule creation for Qualcomm platforms,
replacing the manual workflow described in the cbsp-boot-utilities README.md.
The qcom-capsule class carries all build logic and configurable variables
so that customers can produce their own capsule recipe by simply
inheriting the class and setting the required variables.
All Python capsule-generation scripts are consumed from the native sysroot
via cbsp-boot-utilities-native (${STAGING_DATADIR_NATIVE}/cbsp-boot-utilities/).
EDK2 host tools (GenFfs, GenFv, GenerateCapsule.py) are consumed from
edk2-basetools-native. Neither the class nor the recipe has source of
its own.
The class:
- Consumes pre-built NHLOS firmware images from QCOM_BOOT_FIRMWARE
via do_compile[depends] on do_deploy
- Auto-detects the post-DDR DTB for XBLConfig cert injection by parsing
the xblconfig_parser.py dump output (XBLCONFIG_DTB overrides when set
explicitly); the cert-patched binary is deployed as xbl_config-patched.elf
- Requires OEM PKI material (CAPSULE_ROOT_CER, CAPSULE_CERT_PEM,
CAPSULE_ROOT_PUB, CAPSULE_SUB_PUB) to be set explicitly; the build
fails fast with bbfatal if they are unset
- Deploys the resulting FMP capsule as <pn>.cap
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Extend image_types_qcom.bbclass so that when QCOM_CAPSULE_FIRMWARE is set, the resulting capsule is: - depended on via do_image_qcomflash[depends] += '...:do_deploy' - copied into the qcomflash tarball alongside the other firmware images - pulled into the rootfs via IMAGE_INSTALL:append so the capsule is also available on-device (e.g. for fwupd / LVFS delivery) When QCOM_CAPSULE_FIRMWARE is empty (the default), behaviour is unchanged. Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Use a runtime virtual-package indirection so customers can swap in their own capsule recipe without touching qcom-common.inc. Recommend the capsule package into the rootfs from qcom-common.inc via MACHINE_EXTRA_RRECOMMENDS, gated on the VIRTUAL-RUNTIME provider being set (no-op when capsule generation is disabled). Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Add ci/capsule.yml, a kas overlay that opts-in to UEFI FMP capsule generation by selecting firmware-qcom-capsule as the virtual/qcom-capsule-firmware provider. Keeping this out of the machine include files allows CI configurations to build capsules explicitly rather than unconditionally on every machine. Usage: kas build ci/base.yml:ci/<machine>.yml:ci/capsule.yml kas build ci/base.yml:ci/<machine>.yml:ci/capsule.yml:ci/capsule-test-keys.yml Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Add a rb3gen2-core-kit matrix entry that builds with meta-arm, ci/capsule.yml and ci/capsule-test-keys.yml so the capsule generation path is exercised on every PR. nodistro is used since capsule build does not depend on distro features. Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
0799447
02fa764 to
0799447
Compare
Test run workflowTest jobs for commit 0799447
All jobs summary
|
Introduces
edk2-basetools-nativeto build the required EDK2 host tools (GenFfs,GenFv) and firmware-qcom-capsulewhich fetches capsule scripts fromcbsp-boot-utilities, consumes boot binaries from virtual/bootbins, and produces a signed FMP capsule. The capsule is wired into the qcomflash image via a newQCOM_CAPSULE_FIRMWAREvariable following the same pattern asQCOM_BOOT_FIRMWARE.Test PKI keys are provided vi for development and CI; production builds should override
CAPSULE_ROOT_CER,CAPSULE_CERT_PEM,CAPSULE_ROOT_PUB, andCAPSULE_SUB_PUBwith keys from a secure source.