Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport Tegra Capsule Update #1552

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions meta-lmp-base/recipes-core/systemd/systemd_%.bbappend
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,9 @@ do_install:append() {
fi

(cd ${D}${localstatedir}; rmdir -v --parents lib/systemd)

# systemd-bless-boot is manually invoked by ak-lite if fioefi is enabled
if [ "${@bb.utils.contains("MACHINE_FEATURES", "fioefi", "1", "0", d)}" = "1" ]; then
rm -f ${D}/${systemd_unitdir}/system/systemd-bless-boot.service
fi
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
From 377bc84f2f2283c7d56d6a15767b2accbc92776d Mon Sep 17 00:00:00 2001
From: Igor Opaniuk <[email protected]>
Date: Thu, 31 Oct 2024 15:16:29 +0100
Subject: [PATCH] sysroot: deploy systemd-boot efi to ESP partition

Add support for deploying systemd-boot to ESP partition.
Considering that default deployment has always index == 0, the filenames
in ESP for efi binaries are generated in this way:
deployment index path
0: /boot/EFI/BOOT/bootx64.efi
1: /boot/EFI/BOOT/bootx64-1.efi
2: /boot/EFI/BOOT/bootx64-2.efi

Upstream-Status: Inappropriate [lmp specific]
Signed-off-by: Igor Opaniuk <[email protected]>
---
src/libostree/ostree-sysroot-deploy.c | 55 ++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c
index 0df24df..2bfc62f 100644
--- a/src/libostree/ostree-sysroot-deploy.c
+++ b/src/libostree/ostree-sysroot-deploy.c
@@ -1909,6 +1909,19 @@ parse_os_release (const char *contents, const char *split)
return ret;
}

+/* Generate the boot efi app filename we will use in /boot/EFI/BOOT/ for this deployment.
+ */
+static char *
+bootefi_filename (OstreeSysroot *sysroot, const char* efiname, OstreeDeployment *deployment)
+{
+ guint index = ostree_deployment_get_index (deployment);
+
+ if (index == 0)
+ return g_strdup_printf ("%s.efi", efiname);
+ else
+ return g_strdup_printf ("%s-%d.efi", efiname, index);
+}
+
/* Generate the entry name we will use in /boot/loader/entries for this deployment.
* The provided n_deployments should be the total number of target deployments (which
* might be different from the cached value in the sysroot).
@@ -2007,6 +2020,13 @@ install_deployment_kernel (OstreeSysroot *sysroot, int new_bootversion,
g_autofree char *bootcsumdir = g_strdup_printf ("ostree/%s-%s", osname, bootcsum);
g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", new_bootversion);
g_autofree char *bootconf_name = bootloader_entry_name (sysroot, n_deployments, deployment);
+ const char *bootefidir = "EFI/BOOT";
+ const char *bootefi_srcpath = "usr/lib/systemd/boot/efi";
+ g_autoptr(GHashTable) bootefi_bins = g_hash_table_new (g_str_hash, g_str_equal);
+ const char *bootefi_srcfiles[] = {"systemd-bootaa64.efi", "systemd-bootx64.efi"};
+ const char *bootefi_dstfiles[] = {"bootaa64", "bootx64"};
+ g_hash_table_insert (bootefi_bins, (gpointer)bootefi_srcfiles[0], (gpointer)bootefi_dstfiles[0]);
+ g_hash_table_insert (bootefi_bins, (gpointer)bootefi_srcfiles[1], (gpointer)bootefi_dstfiles[1]);

if (!glnx_shutil_mkdir_p_at (sysroot->boot_fd, bootcsumdir, 0775, cancellable, error))
return FALSE;
@@ -2018,6 +2038,13 @@ install_deployment_kernel (OstreeSysroot *sysroot, int new_bootversion,
if (!glnx_shutil_mkdir_p_at (sysroot->boot_fd, bootconfdir, 0775, cancellable, error))
return FALSE;

+ if (!glnx_shutil_mkdir_p_at (sysroot->boot_fd, bootefidir, 0775, cancellable, error))
+ return FALSE;
+
+ glnx_autofd int bootefi_dfd = -1;
+ if (!glnx_opendirat (sysroot->boot_fd, bootefidir, TRUE, &bootefi_dfd, error))
+ return FALSE;
+
OstreeRepo *repo = ostree_sysroot_repo (sysroot);

const char *bootprefix = repo->enable_bootprefix ? "/boot/" : "/";
@@ -2036,6 +2063,32 @@ install_deployment_kernel (OstreeSysroot *sysroot, int new_bootversion,
return FALSE;
}

+ glnx_autofd int legacy_dfd = glnx_opendirat_with_errno (deployment_dfd, bootefi_srcpath, TRUE);
+ if (legacy_dfd >= 0)
+ {
+ GLNX_HASH_TABLE_FOREACH_IT (bootefi_bins, it, const char *, bootefi_srcfile, const char *, bootefi_dst)
+ {
+ g_autofree char *bootefi_file = bootefi_filename(sysroot, bootefi_dst, deployment);
+ if (fstatat (legacy_dfd, bootefi_srcfile, &stbuf, 0) == 0)
+ {
+ if (!glnx_fstatat_allow_noent (bootefi_dfd, bootefi_file, &stbuf, 0,
+ error))
+ return FALSE;
+
+ /* Drop the old file */
+ if (errno != ENOENT)
+ {
+ if (!glnx_shutil_rm_rf_at (bootefi_dfd, bootefi_file, cancellable, error))
+ return FALSE;
+ }
+
+ if (!install_into_boot (repo, sepolicy, legacy_dfd, bootefi_srcfile,
+ bootefi_dfd, bootefi_file, cancellable, error))
+ return FALSE;
+ }
+ }
+ glnx_close_fd (&legacy_dfd);
+ }
/* If we have an initramfs, then install it into
* /boot/ostree/osname-${bootcsum} if it doesn't exist already.
*/
@@ -2153,7 +2206,7 @@ install_deployment_kernel (OstreeSysroot *sysroot, int new_bootversion,

/* search for legacy directory for additional files to copy to /boot/ostree/$os-$bootcsum/ */
const char legacy_path[] = "usr/lib/ostree-boot";
- glnx_autofd int legacy_dfd = glnx_opendirat_with_errno (deployment_dfd, legacy_path, TRUE);
+ legacy_dfd = glnx_opendirat_with_errno (deployment_dfd, legacy_path, TRUE);
if (legacy_dfd >= 0)
{
if (fstatat (legacy_dfd, ".ostree-bootcsumdir-source", &stbuf, 0) == 0)
--
2.43.0

1 change: 1 addition & 0 deletions meta-lmp-base/recipes-extended/ostree/ostree_%.bbappend
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ SRC_URI:append = " \
file://0005-ostree-decrease-default-grub.cfg-timeout-and-set-def.patch \
file://0006-Add-support-systemd-boot-automatic-boot-assesment.patch \
file://0007-sort-key.patch \
file://0008-sysroot-deploy-systemd-boot-efi-to-ESP-partition.patch \
"

PACKAGECONFIG:remove = "static"
1 change: 1 addition & 0 deletions meta-lmp-base/recipes-samples/images/lmp-image-common.inc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ CORE_IMAGE_BASE_INSTALL += " \
# Additional packages when sota is available
CORE_IMAGE_BASE_INSTALL:append:sota = " \
ostree-recovery-initramfs \
${@bb.utils.contains('MACHINE_FEATURES', 'fioefi', 'fioefi', '' , d)} \
"

# Configure NSS ALTFILES based on NSS_ALT_TYPES
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
SUMMARY = "Aktualizr configuration snippet to enable Foundries.IO UEFI Capsule updates"
HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
SECTION = "base"
LICENSE = "MPL-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"

inherit allarch

SRC_URI = "file://sota-fioefi-env.toml"

PV = "1.0"

S = "${WORKDIR}"

do_install() {
install -m 0700 -d ${D}${libdir}/sota/conf.d
install -m 0644 ${WORKDIR}/sota-fioefi-env.toml ${D}${libdir}/sota/conf.d/30-rollback.toml
}

FILES:${PN} = " \
${libdir}/sota/conf.d \
${libdir}/sota/conf.d/30-rollback.toml \
"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[bootloader]
rollback_mode = "fioefi"
5 changes: 3 additions & 2 deletions meta-lmp-base/recipes-sota/aktualizr/aktualizr_%.bbappend
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ SRC_URI:append:lmp = " \
file://tmpfiles.conf \
"

PACKAGECONFIG += "${@bb.utils.filter('MACHINE_FEATURES', 'fiovb', d)} libfyaml"
PACKAGECONFIG[fiovb] = ",,,optee-fiovb aktualizr-fiovb-env-rollback"
PACKAGECONFIG += "${@bb.utils.filter('MACHINE_FEATURES', 'fiovb', d)} ${@bb.utils.filter('MACHINE_FEATURES', 'fioefi', d)} libfyaml"
PACKAGECONFIG[fiovb] = ",,,optee-fiovb aktualizr-fiovb-env-rollback,,fioefi"
PACKAGECONFIG[fioefi] = ",,,fioefi aktualizr-fioefi-env-rollback,,fiovb"
PACKAGECONFIG[ubootenv] = ",,u-boot-fw-utils,u-boot-fw-utils u-boot-default-env aktualizr-uboot-env-rollback"
PACKAGECONFIG[libfyaml] = ",,,libfyaml"
PACKAGECONFIG[aklite-offline] = "-DBUILD_AKLITE_OFFLINE=ON,-DBUILD_AKLITE_OFFLINE=OFF,"
Expand Down
83 changes: 83 additions & 0 deletions meta-lmp-base/recipes-sota/fioefi/fioefi/fioefi.sh.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/bin/sh
#
# Copyright (C) 2024 Foundries.IO
#
# SPDX-License-Identifier: MIT
#
set -e

scriptName="$(basename "$0")"
BLS_DIR=/boot/loader/entries

error_exit() {
if [ -n "${1}" ] ; then
echo "ERROR: ${1}"
else
echo "ERROR: Command execution failure"
fi
exit 1
}

debug() {
if [ -n "${1}" ] ; then
echo "DEBUG: ${1}"
else
echo "DEBUG: Command execution failure"
fi
}

matches() {
input="$1"
pattern="$2"
echo "$input" | grep -q "$pattern"
}

get_target_sysroot () {
if ls $BLS_DIR/ostree-2*.conf &>/dev/null; then
bls_id=2
else
bls_id=1
fi

sysroot_path=$(cat $BLS_DIR/ostree-${bls_id}*.conf | grep "options "| awk '{split($0,a,"ostree="); print a[2]}')
echo "$sysroot_path"
}

if [ -z "${FIO_OSTREE_TARGET_SYSROOT}" ]; then
# Try to parse it from the target sysroot boot entry
FIO_OSTREE_TARGET_SYSROOT=$(get_target_sysroot)
fi

@@INCLUDE_SOC_FUNCTIONS@@

# SoC-agnostic functions. Create fioefi_soc.sh.in with SoC-specific
# implementation
getenv() {
exit 0
}

setenv() {
rc=0

if [ "${1}" = "upgrade_available" ]; then
if [ "${2}" = "0" ]; then
/usr/lib/systemd/systemd-bless-boot good || rc=1
fi
fi

exit $rc
}

if matches "$scriptName" "printenv"; then
if type 'getenv_soc' 2>/dev/null | grep -q 'function'; then
getenv_soc "${1}"
else
getenv "${1}"
fi
elif matches "$scriptName" "setenv"; then
if type 'setenv_soc' 2>/dev/null | grep -q 'function'; then
setenv_soc "${1}" "${2}"
else
setenv "${1}" "${2}"
fi
fi
24 changes: 24 additions & 0 deletions meta-lmp-base/recipes-sota/fioefi/fioefi_0.1.bb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SUMMARY = "Foundries.IO UEFI Firmware Update control script"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://fioefi.sh.in"
RDEPENDS:${PN}:append = " lmp-boot-firmware"

S = "${WORKDIR}"
B = "${WORKDIR}/build"

do_compile() {
# Check if the file wasn't created by soc-specific do_compile() prepend
if [ ! -e ${B}/fioefi ]; then
sed -e 's/@@INCLUDE_SOC_FUNCTIONS@@//g' ${S}/fioefi.sh.in > ${B}/fioefi
fi
}

do_install () {
install -d ${D}${bindir}
install -m 0755 ${B}/fioefi ${D}${bindir}/fioefi
ln -sf fioefi ${D}${bindir}/fioefi_printenv
ln -sf fioefi ${D}${bindir}/fioefi_setenv
ln -sf fioefi ${D}${bindir}/fioefi_delenv
}
11 changes: 10 additions & 1 deletion meta-lmp-bsp/conf/machine/include/lmp-machine-custom.inc
Original file line number Diff line number Diff line change
Expand Up @@ -762,18 +762,27 @@ DISTRO_FEATURES:append:tegra = " opengl"
DISTRO_FEATURES_DEFAULT:remove:tegra = "modsign"
PREFERRED_PROVIDER_virtual/kernel:tegra ?= "linux-tegra"
IMAGE_TEGRAFLASH_FS_TYPE:sota:tegra = "${@bb.utils.contains('TEGRA_EXTERNAL_ROOTFS_WIC', '1', 'wic.gz', 'ota-ext4', d)}"
IMAGE_TEGRAFLASH_ESPIMG:sota:tegra = "${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.ota-esp"
IMAGE_FSTYPES:remove:tegra = "${@bb.utils.contains('TEGRA_EXTERNAL_ROOTFS_WIC', '1', '', 'wic wic.gz wic.bmap', d)}"
TEGRA_ESP_IMAGE:sota:tegra = ""
TEGRA_INITRAMFS_FSTYPES:tegra = ""
INITRD_IMAGE:tegra = ""
IMAGE_TEGRAFLASH_KERNEL:tegra = "${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}"
WKS_FILE:tegra:sota ?= "efidisk-sota.wks.in"
IMAGE_ROOTFS_SIZE:tegra = "65536"
PREFERRED_PROVIDER_virtual/bootloader:tegra ?= "edk2-firmware-tegra"
TEGRA_UEFI_CAPSULE_INSTALL_DIR:tegra = ""
EFI_PROVIDER:sota:tegra = "systemd-boot"
OSTREE_LOADER_LINK:tegra = "0"
OSTREE_BOOTLOADER:tegra ?= "syslinux"
OSTREE_BOOTLOADER:tegra = "none"
OSTREE_DEPLOY_DEVICETREE:tegra = "1"
OSTREE_SPLIT_BOOT:sota:tegra = "1"
PREFERRED_PROVIDER_virtual/optee-os:tegra = "optee-os"
MACHINE_FEATURES:append:tegra = " optee"
SOTA_CLIENT_FEATURES:remove:sota:tegra = "ubootenv"
MACHINE_FEATURES:append:sota:tegra = " fioefi"
LMP_BOOT_FIRMWARE_FILES:append:sota:tegra = " tegra-bl.cap"
IMAGE_BOOT_FILES:sota:tegra = "systemd-bootaa64.efi;EFI/BOOT/bootaa64.efi"
## jetson-agx-xavier-devkit (tegra194)
OSTREE_KERNEL_ARGS:tegra194 ?= "\${cbootargs} ${OSTREE_KERNEL_ARGS_COMMON} rootwait mminit_loglevel=4 console=tty0 console=ttyTCU0,115200 fbcon=map:0 video=efifb:off sdhci_tegra.en_boot_part_access=1"
## jetson-agx-orin-devkit (tegra234)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
TEGRA_INSTALL_DEPENDS ?= ""
TEGRA_INSTALL_DEPENDS:tegra = "tegra-uefi-capsules:do_install"
do_install[depends] += "${TEGRA_INSTALL_DEPENDS}"

inherit l4t_version

def get_dec_bsp_version(bsp_version):
verparts = bsp_version.split('.')
return int(verparts[0])<<16 | int(verparts[1])<<8 | int(verparts[2])

LMP_BOOT_FIRMWARE_VERSION:tegra = "${@get_dec_bsp_version(d.getVar('L4T_VERSION'))}"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SYSTEMD_AUTO_ENABLE:${PN} = "${@bb.utils.contains("MACHINE_FEATURES", "fioefi", "disable", "enable", d)}"
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
NVIDIA_ESPMOUNT = ""
ESPMOUNT = "/boot"
NVIDIA_ESPMOUNT = ""
41 changes: 41 additions & 0 deletions meta-lmp-bsp/recipes-sota/fioefi/fioefi/tegra/fioefi-soc.sh.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
CAPSULE_FILE="tegra-bl.cap"
CAPSULE_PATH="${FIO_OSTREE_TARGET_SYSROOT}/usr/lib/firmware"
EFI_CAPSULE_DIR=/boot/EFI/UpdateCapsule
ESRT_FW_VERSION=/sys/firmware/efi/esrt/entries/entry0/fw_version

getenv_soc() {
rc=0

if [ "${1}" = "bootfirmware_version" ]; then
if [ -e "$ESRT_FW_VERSION" ]; then
cat $ESRT_FW_VERSION || rc=1
else
error_exit "Can't obtain boot firmware version"
fi
fi

exit $rc
}

setenv_soc() {
rc=0

if [ "${1}" = "bootupgrade_available" ]; then
if [ -e "$CAPSULE_PATH/$CAPSULE_FILE" ]; then
mkdir -p $EFI_CAPSULE_DIR
cp $CAPSULE_PATH/$CAPSULE_FILE $EFI_CAPSULE_DIR || rc=1
oe4t-set-uefi-OSIndications || rc=1
else
error_exit "$CAPSULE_PATH/$CAPSULE_FILE doesn't exist"
fi
fi
if [ "${1}" = "upgrade_available" ]; then
if [ "${2}" = "0" ]; then
# nvbootctrl can report errors which is expected
/usr/sbin/nvbootctrl verify || rc=0
/usr/lib/systemd/systemd-bless-boot good || rc=1
fi
fi

exit $rc
}
12 changes: 12 additions & 0 deletions meta-lmp-bsp/recipes-sota/fioefi/fioefi_%.bbappend
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"

SRC_URI:append = " file://fioefi-soc.sh.in"

RDEPENDS:${PN}:append:tegra = " setup-nv-boot-control"

do_compile:prepend() {
sed -e '/@@INCLUDE_SOC_FUNCTIONS@@/ {' -e 'r ${S}/fioefi-soc.sh.in' -e 'd' -e '}' \
${S}/fioefi.sh.in > ${B}/fioefi
}

COMPATIBLE_MACHINE = "(tegra)"