From 179fef684b84838fe8c4b69ccced029b59626367 Mon Sep 17 00:00:00 2001 From: Viswanath Kraleti Date: Wed, 3 Jan 2024 11:09:28 +0530 Subject: [PATCH 1/4] linux-yocto: Don't generate UKI as part of kernel build Generation of UKI needs Kernel Image to be available along with initrd and other packages like os-release. It is convenient to have UKI generation as part of an image rather than kernel build. Signed-off-by: Viswanath Kraleti --- recipes-kernel/linux/linux-linaro-qcom.inc | 1 - recipes-kernel/linux/linux-yocto_%.bbappend | 5 ----- 2 files changed, 6 deletions(-) diff --git a/recipes-kernel/linux/linux-linaro-qcom.inc b/recipes-kernel/linux/linux-linaro-qcom.inc index 3fefca2..f7c1c96 100644 --- a/recipes-kernel/linux/linux-linaro-qcom.inc +++ b/recipes-kernel/linux/linux-linaro-qcom.inc @@ -25,7 +25,6 @@ KERNEL_DEFCONFIG:arm ?= "${S}/arch/arm/configs/qcom_defconfig" KERNEL_CONFIG_FRAGMENTS += "${S}/kernel/configs/distro.config" inherit linux-qcom-bootimg -inherit ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'uki', '', d)} kernel_conf_variable() { sed -e "/CONFIG_$1[ =]/d;" -i ${B}/.config diff --git a/recipes-kernel/linux/linux-yocto_%.bbappend b/recipes-kernel/linux/linux-yocto_%.bbappend index 193f3be..2255db6 100644 --- a/recipes-kernel/linux/linux-yocto_%.bbappend +++ b/recipes-kernel/linux/linux-yocto_%.bbappend @@ -12,8 +12,3 @@ SRC_URI:append:qcom = " \ QCOM_BOOTIMG = "" QCOM_BOOTIMG:qcom = "linux-qcom-bootimg" inherit ${QCOM_BOOTIMG} - -# For UKI (linux.efi) -QCOM_UKI = "" -QCOM_UKI:qcom = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'uki', '', d)}" -inherit ${QCOM_UKI} From 708e9feb34f98316aefc3ce1865a497b734075a9 Mon Sep 17 00:00:00 2001 From: Viswanath Kraleti Date: Wed, 10 Jan 2024 12:55:11 +0530 Subject: [PATCH 2/4] qcom-common.inc: Drop EFILINUXDIR variable Oe-core's image-uefi.conf defined EFI_UKI_PATH to point to the uki inside an esp image. Use this variable in place of EFILINUXDIR. Also, renamed a few other EFI variables for readability. Signed-off-by: Viswanath Kraleti --- classes/uki.bbclass | 6 +++--- conf/machine/include/qcom-common.inc | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/classes/uki.bbclass b/classes/uki.bbclass index 32913db..deee4a1 100644 --- a/classes/uki.bbclass +++ b/classes/uki.bbclass @@ -66,9 +66,9 @@ python do_uki() { ukify_cmd += " --stub %s" % stub # Custom UKI name - output_dir = d.getVar('D') + "/" + d.getVar('EFILINUXDIR') + output_dir = d.getVar('D') + "/" + d.getVar('EFI_UKI_PATH') os.makedirs(output_dir, exist_ok=True) - output = output_dir + "/" + d.getVar('EFILINUXIMG') + output = output_dir + "/" + d.getVar('EFI_LINUX_IMG') ukify_cmd += " --output=%s" % output # Set env to determine where bitbake should look for dynamic libraries @@ -86,5 +86,5 @@ python () { } FILES:${KERNEL_PACKAGE_NAME}-uki = " \ - /${EFILINUXDIR}/${EFILINUXIMG} \ + /${EFI_UKI_PATH}/${EFI_LINUX_IMG} \ " diff --git a/conf/machine/include/qcom-common.inc b/conf/machine/include/qcom-common.inc index c64656c..8d5db76 100644 --- a/conf/machine/include/qcom-common.inc +++ b/conf/machine/include/qcom-common.inc @@ -44,12 +44,11 @@ EFI_PROVIDER = "systemd-boot" # Install packages at root of ESP EFI_PREFIX = "" -# Location of Kernel and dtb inside ESP -EFILINUXDIR ?= "${EFI_PREFIX}EFI/Linux" -EFIDTBDIR ?= "${EFI_PREFIX}dtb" +# Location of dtb inside ESP +EFI_DTB_DIR ?= "${EFI_PREFIX}dtb" # Unified Kernel Image (UKI) name -EFILINUXIMG ?= "linux-${MACHINE}.efi" +EFI_LINUX_IMG ?= "linux-${MACHINE}.efi" # Place dtb at EFIDTDIR to seamlessly package -KERNEL_DTBDEST = "${EFIDTBDIR}" +KERNEL_DTBDEST = "${EFI_DTB_DIR}" From bf8c2a94b36a8500423e51aa88ad959d8cbcb542 Mon Sep 17 00:00:00 2001 From: Viswanath Kraleti Date: Tue, 16 Jan 2024 22:55:33 +0530 Subject: [PATCH 3/4] qcom-common.inc: Add 'Image' to KERNEL_IMAGETYPES UKI generation needs uncompressed kernel image. Specifying 'Image' in KERNEL_IMAGETYPES ensures uncompressed kernel image is always built. Signed-off-by: Viswanath Kraleti --- conf/machine/include/qcom-common.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conf/machine/include/qcom-common.inc b/conf/machine/include/qcom-common.inc index 8d5db76..da57da8 100644 --- a/conf/machine/include/qcom-common.inc +++ b/conf/machine/include/qcom-common.inc @@ -52,3 +52,6 @@ EFI_LINUX_IMG ?= "linux-${MACHINE}.efi" # Place dtb at EFIDTDIR to seamlessly package KERNEL_DTBDEST = "${EFI_DTB_DIR}" + +# UKI generation needs uncompressed Kernel image +KERNEL_IMAGETYPES:append = " Image" From 5b2106aa902ef7c9839bb44d7e7ec41d832eba5e Mon Sep 17 00:00:00 2001 From: Viswanath Kraleti Date: Wed, 10 Jan 2024 15:52:00 +0530 Subject: [PATCH 4/4] recipes-kernel: Add linux-qcom-uki recipe linux-qcom-uki recipe generates UKI by combining UEFI stub, kernel image, initrd, os-release, optional dtb and other metadata like kernel cmdline. Drop uki.bbclass as linux-qcom-uki is taking care of UKI generation. Signed-off-by: Viswanath Kraleti --- classes/uki.bbclass | 90 ------------------------- recipes-kernel/images/esp-qcom-image.bb | 2 +- recipes-kernel/images/linux-qcom-uki.bb | 89 ++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 91 deletions(-) delete mode 100644 classes/uki.bbclass create mode 100644 recipes-kernel/images/linux-qcom-uki.bb diff --git a/classes/uki.bbclass b/classes/uki.bbclass deleted file mode 100644 index deee4a1..0000000 --- a/classes/uki.bbclass +++ /dev/null @@ -1,90 +0,0 @@ -# This bbclass repacks kernel image as a UKI (Unified Kernel Image) -# Composed by -# - an UEFI stub, from systemd-boot -# - the kernel Image -# - an initramfs -# - other metadata like kernel cmdline - -DEPENDS:append = " \ - systemd-boot-native \ - python3-native \ - python3-pefile-native \ - " - -require conf/image-uefi.conf - -inherit python3native - -do_install[depends] += " \ - systemd-boot:do_deploy \ - " -do_install[depends] += "${@ '${INITRAMFS_IMAGE}:do_image_complete' if d.getVar('INITRAMFS_IMAGE') else ''}" -do_uki[dirs] = "${B}" -do_install[postfuncs] += "do_uki" - -python do_uki() { - import glob - import subprocess - - # Construct the ukify command - ukify_cmd = ("ukify build") - - deploy_dir_image = d.getVar('DEPLOY_DIR_IMAGE') - - # Ramdisk - if d.getVar('INITRAMFS_IMAGE'): - initrd_image = d.getVar('INITRAMFS_IMAGE') + "-" + d.getVar('MACHINE') - baseinitrd = os.path.join(d.getVar('INITRAMFS_DEPLOY_DIR_IMAGE'), initrd_image) - for img in (".cpio.gz", ".cpio.lz4", ".cpio.lzo", ".cpio.lzma", ".cpio.xz", ".cpio"): - if os.path.exists(baseinitrd + img): - initrd = baseinitrd + img - break - if not initrd: - bb.fatal("initrd= must be specified to create unified kernel image.") - ukify_cmd += " --initrd=%s" % initrd - - # Kernel Image. - # Note: systemd-boot can't handle compressed kernel image. - kernel_image = d.getVar('B') + "/" + d.getVar('KERNEL_OUTPUT_DIR') + "/Image" - kernel_version = d.getVar('KERNEL_VERSION') - if not os.path.exists(kernel_image): - bb.fatal("linux= must be specified to create unified kernel image.") - ukify_cmd += " --linux=%s --uname %s" % (kernel_image, kernel_version) - - # Kernel cmdline - cmdline = "%s" %(d.getVar('KERNEL_CMDLINE_EXTRA')) - ukify_cmd += " --cmdline='%s'" % (cmdline) - - # Architecture - target_arch = d.getVar('EFI_ARCH') - ukify_cmd += " --efi-arch %s" % target_arch - - # Stub - stub = "%s/linux%s.efi.stub" % (deploy_dir_image, target_arch) - if not os.path.exists(stub): - bb.fatal("stub must be specified to create unified kernel image %s" %stub) - ukify_cmd += " --stub %s" % stub - - # Custom UKI name - output_dir = d.getVar('D') + "/" + d.getVar('EFI_UKI_PATH') - os.makedirs(output_dir, exist_ok=True) - output = output_dir + "/" + d.getVar('EFI_LINUX_IMG') - ukify_cmd += " --output=%s" % output - - # Set env to determine where bitbake should look for dynamic libraries - env = os.environ.copy() # get the env variables - env['LD_LIBRARY_PATH'] = d.expand("${RECIPE_SYSROOT_NATIVE}/usr/lib/systemd:${LD_LIBRARY_PATH}") - - # Run the ukify command - subprocess.check_call(ukify_cmd, env=env, shell=True) -} - -# Support uki as a package -python () { - if not bb.data.inherits_class('nopackages', d): - d.appendVar("PACKAGES", " ${KERNEL_PACKAGE_NAME}-uki") -} - -FILES:${KERNEL_PACKAGE_NAME}-uki = " \ - /${EFI_UKI_PATH}/${EFI_LINUX_IMG} \ -" diff --git a/recipes-kernel/images/esp-qcom-image.bb b/recipes-kernel/images/esp-qcom-image.bb index 2646422..2749752 100644 --- a/recipes-kernel/images/esp-qcom-image.bb +++ b/recipes-kernel/images/esp-qcom-image.bb @@ -4,7 +4,7 @@ COMPATIBLE_HOST = '(x86_64.*|arm.*|aarch64.*)-(linux.*)' PACKAGE_INSTALL = " \ kernel-devicetree \ - kernel-uki \ + linux-qcom-uki \ systemd-boot \ systemd-bootconf \ " diff --git a/recipes-kernel/images/linux-qcom-uki.bb b/recipes-kernel/images/linux-qcom-uki.bb new file mode 100644 index 0000000..0d34b60 --- /dev/null +++ b/recipes-kernel/images/linux-qcom-uki.bb @@ -0,0 +1,89 @@ +SUMMARY = "Qualcomm linux kernel UKI creation" + +DESCRIPTION = "Pack kernel image as a UKI (Unified Kernel Image) \ +by combining UEFI stub from systemd-boot, the kernel Image, initramfs, \ +optional dtb, osrelease info and other metadata like kernel cmdline." + +LICENSE = "BSD-3-Clause-Clear" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause-Clear;md5=7a434440b651f4a472ca93716d01033a" + +COMPATIBLE_HOST = '(arm.*|aarch64.*)-(linux.*)' + +inherit python3native image-artifact-names linux-kernel-base + +DEPENDS = " systemd-boot-native python3-native python3-pefile-native \ + os-release systemd-boot virtual/kernel " + +require conf/image-uefi.conf + +KERNEL_VERSION = "${@get_kernelversion_file('${STAGING_KERNEL_BUILDDIR}')}" + +do_configure[depends] += " \ + systemd-boot:do_deploy \ + virtual/kernel:do_deploy \ + " +do_configure[depends] += "${@ '${INITRAMFS_IMAGE}:do_image_complete' if d.getVar('INITRAMFS_IMAGE') else ''}" + +do_compile() { + # Construct the ukify command + ukify_cmd="" + + # Ramdisk + if [ -n "${INITRAMFS_IMAGE}" ]; then + initrd="" + for img in ${INITRAMFS_FSTYPES}; do + if [ -e "${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img" ]; then + initrd="${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img" + break + fi + done + [ -f $initrd ] && echo "Creating UKI with $initrd" || bbfatal "$initrd is not a valid initrd to create UKI." + ukify_cmd="$ukify_cmd --initrd=$initrd" + fi + + # Kernel Image + # Note: systemd-boot can't handle compressed kernel image. + kernel_image="${DEPLOY_DIR_IMAGE}/Image" + [ -f $kernel_image ] && echo "Creating UKI with $kernel_image" || bbfatal "No valid kernel image to create UKI. Add 'Image' to KERNEL_IMAGETYPES." + ukify_cmd="$ukify_cmd --linux=$kernel_image" + + # Kernel version + ukify_cmd="$ukify_cmd --uname ${KERNEL_VERSION}" + + # Kernel cmdline + if [ -n "${KERNEL_CMDLINE_EXTRA}" ]; then + ukify_cmd="$ukify_cmd --cmdline='${KERNEL_CMDLINE_EXTRA}'" + fi + + # Architecture + ukify_cmd="$ukify_cmd --efi-arch ${EFI_ARCH}" + + # OS-release + osrelease="${RECIPE_SYSROOT}${libdir}/os-release" + ukify_cmd="$ukify_cmd --os-release @$osrelease" + + # Stub + stub="${DEPLOY_DIR_IMAGE}/linux${EFI_ARCH}.efi.stub" + [ -f $stub ] && echo "Creating UKI with $stub" || bbfatal "$stub is not a valid stub to create UKI." + ukify_cmd="$ukify_cmd --stub $stub" + + # Output + mkdir -p "${B}${EFI_UKI_PATH}" + output="${B}${EFI_UKI_PATH}/${EFI_LINUX_IMG}" + rm -f $output + ukify_cmd="$ukify_cmd --output=$output" + + # Call ukify to generate uki. + echo "ukify cmd:$ukify_cmd" + ukify build $ukify_cmd +} + +do_install() { + install -Dm 0755 ${B}${EFI_UKI_PATH}/${EFI_LINUX_IMG} ${D}${EFI_UKI_PATH}/${EFI_LINUX_IMG} +} + +FILES:${PN} = "${EFI_UKI_PATH}/${EFI_LINUX_IMG}" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +SKIP_RECIPE[linux-qcom-uki] ?= "${@bb.utils.contains('KERNEL_IMAGETYPES', 'Image', '', 'systemd-boot needs uncompressed kernel image. Add "Image" to KERNEL_IMAGETYPES.', d)}"