On Mon, 20 Nov 2023 at 15:26, Bruce Ashfield <bruce.ashfi...@gmail.com> wrote: > > On Mon, Nov 20, 2023 at 7:49 AM Dmitry Baryshkov <dbarysh...@gmail.com> wrote: > > > > On Thu, 7 Sept 2023 at 01:29, Alejandro Hernandez Samaniego > > <a...@linux.microsoft.com> wrote: > > > > > > > > > On 9/2/23 00:53, Richard Purdie wrote: > > > > On Fri, 2023-09-01 at 23:32 +0000, Michelle Lin wrote: > > > >> Currently, there is not a class to support the building of unified > > > >> kernel > > > >> images. Adding a uki.bbclass to support the creation of UKIs. This > > > >> class calls > > > >> the systemd Ukify tool, which will combine the kernel/initrd/stub > > > >> components to > > > >> build the UKI. To sign the UKI (i.e. SecureBoot, TPM PCR signing), the > > > >> keys/cert > > > >> files are to be specified in a separate configuration file, and the > > > >> path to the > > > >> file is passed to the Ukify tool. UKIs are supported by UEFI and can > > > >> improve > > > >> security through predicted TPM PCR states, and reduce the build burden > > > >> due to > > > >> its single PE binary format. > > > >> > > > >> Signed-off-by: Michelle Lin <michelle.lint...@gmail.com> > > > >> --- > > > >> meta/classes/uki.bbclass | 140 > > > >> +++++++++++++++++++++++ > > > >> meta/recipes-core/systemd/systemd_254.bb | 23 ++++ > > > >> 2 files changed, 163 insertions(+) > > > >> create mode 100644 meta/classes/uki.bbclass > > > >> > > > >> diff --git a/meta/classes/uki.bbclass b/meta/classes/uki.bbclass > > > >> new file mode 100644 > > > >> index 0000000000..2eff387c75 > > > >> --- /dev/null > > > >> +++ b/meta/classes/uki.bbclass > > > >> @@ -0,0 +1,140 @@ > > > >> +# > > > >> +# Unified kernel image (UKI) class > > > >> +# > > > >> +# > > > >> +# This bbclass is designed to repack an Overlake image as a UKI, to > > > >> be booted on a qemuarm64 with SecureBoot > > > >> +# signing and embedded with TPM PCR measurements. > > > >> +# > > > >> +# The UKI is composed by: > > > >> +# - an UEFI stub > > > >> +# The linux kernel can generate a UEFI stub, however the one from > > > >> systemd-boot can fetch > > > >> +# the command line from a separate section of the EFI > > > >> application, avoiding the need to > > > >> +# rebuild the kernel. > > > >> +# - the kernel > > > >> +# - an initramfs > > > >> +# - other metadata (e.g. PCR measurements) > > > >> +# > > > >> +# > > > >> +# > > > >> + > > > >> +# List build time dependencies > > > >> +DEPENDS += "systemd-native \ > > > >> + sbsigntool-native \ > > > >> + virtual/${TARGET_PREFIX}binutils \ > > > >> + " > > > >> + > > > >> +REQUIRED_DISTRO_FEATURES += "usrmerge systemd" > > > >> + > > > >> +inherit features_check > > > >> +require ../conf/image-uefi.conf > > > >> + > > > >> +INITRD_IMAGE ?= "core-image-minimal-initramfs" > > > >> + > > > >> +INITRD_LIVE ?= "${@ ('${DEPLOY_DIR_IMAGE}/' + > > > >> d.getVar('INITRD_IMAGE') + '-${MACHINE}.cpio.gz') if > > > >> d.getVar('INITRD_IMAGE') else ''}" > > > >> + > > > >> +UKI_CONFIG_FILE ?= "${WORKDIR}/core-image-minimal-uki.conf" > > > >> +UKI_FILENAME ?= "${@ 'UKI.signed.efi' if d.getVar('UKI_CONFIG_FILE') > > > >> else 'UKI.unsigned.efi'}" > > > >> + > > > >> +do_uki[depends] += " \ > > > >> + systemd-boot:do_deploy \ > > > >> + virtual/kernel:do_deploy \ > > > >> + " > > > >> + > > > >> +# INITRD_IMAGE is added to INITRD_LIVE, which we use to create our > > > >> initrd, so depend on it if it is set > > > >> +# So we want to generate the initrd image if INITRD_IMAGE exists > > > >> +do_uki[depends] += "${@ '${INITRD_IMAGE}:do_image_complete' if > > > >> d.getVar('INITRD_IMAGE') else ''}" > > > >> + > > > >> +# ensure that the build directory is empty everytime we generate a > > > >> newly-created uki > > > >> +do_uki[cleandirs] = "${B}" > > > >> +# influence the build directory at the start of the builds > > > >> +do_uki[dirs] = "${B}" > > > >> + > > > >> +# we want to allow specifying files in SRC_URI, such as for signing > > > >> the UKI > > > >> +python () { > > > >> + d.delVarFlag("do_fetch","noexec") > > > >> + d.delVarFlag("do_unpack","noexec") > > > >> +} > > > >> + > > > >> +# main task > > > >> +python do_uki() { > > > >> + import glob > > > >> + import subprocess > > > >> + > > > >> + # Construct the ukify command > > > >> + ukify_cmd = ("ukify build") > > > >> + > > > >> + # Handle the creation of an initrd image by reading and > > > >> concatenating multiple cpio files. > > > >> + # If the INITRD_LIVE variable is defined and not empty, it opens > > > >> the necessary files, reads their contents, > > > >> + # and constructs a list. > > > >> + if d.getVar('INITRD_LIVE'): > > > >> + initrd_list = "" > > > >> + for cpio in d.getVar('INITRD_LIVE').split(): > > > >> + # get a list of initrds > > > >> + initrd_list += cpio + ' ' > > > >> + > > > >> + ukify_cmd += " --initrd=%s" % initrd_list > > > >> + else: > > > >> + bb.fatal("ERROR - Required argument: INITRD") > > > >> + > > > >> + deploy_dir_image = d.getVar('DEPLOY_DIR_IMAGE') > > > >> + > > > >> + # Kernel > > > >> + if d.getVar('KERNEL_IMAGETYPE'): > > > >> + kernel = "%s/%s" % (deploy_dir_image, > > > >> d.getVar('KERNEL_IMAGETYPE')) > > > >> + kernel_version = d.getVar('KERNEL_VERSION') > > > >> + if not os.path.exists(kernel): > > > >> + bb.fatal(f"ERROR: cannot find {kernel}.") > > > >> + > > > >> + ukify_cmd += " --linux=%s --uname %s" % (kernel, > > > >> kernel_version) > > > >> + else: > > > >> + bb.fatal("ERROR - Required argument: KERNEL") > > > >> + > > > >> + # 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(f"ERROR: cannot find {stub}.") > > > >> + ukify_cmd += " --stub %s" % stub > > > >> + > > > >> + # Add option for dtb > > > >> + if d.getVar('KERNEL_DEVICETREE'): > > > >> + first_dtb = d.getVar('KERNEL_DEVICETREE').split()[0] > > > >> + dtb_path = "%s/%s" % (deploy_dir_image, first_dtb) > > > >> + > > > >> + if not os.path.exists(dtb_path): > > > >> + bb.fatal(f"ERROR: cannot find {dtb_path}.") > > > >> + > > > >> + ukify_cmd += " --devicetree %s" % dtb_path > > > >> + > > > >> + # Add option to pass a config file to sign the UKI. > > > >> + if os.path.exists(d.getVar('UKI_CONFIG_FILE')): > > > >> + ukify_cmd += " --config=%s" % d.getVar('UKI_CONFIG_FILE') > > > >> + ukify_cmd += " --tools=%s%s/lib/systemd/tools" % > > > >> (d.getVar("RECIPE_SYSROOT_NATIVE"), d.getVar("prefix")) > > > >> + bb.note("Pulling keys from config file") > > > >> + else: > > > >> + bb.note("Generating unsigned UKI") > > > >> + > > > >> + # Custom UKI name > > > >> + output = " --output=%s" % d.getVar('UKI_FILENAME') > > > >> + ukify_cmd += " %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) > > > >> +} > > > >> + > > > >> +inherit deploy > > > >> + > > > >> +do_deploy () { > > > >> + # Copy generated UKI into DEPLOYDIR > > > >> + install ${B}/${UKI_FILENAME} ${DEPLOYDIR} > > > >> +} > > > >> + > > > >> +addtask uki before do_deploy do_image after do_rootfs > > > >> +addtask deploy before do_build after do_compile > > > >> \ No newline at end of file > > > >> diff --git a/meta/recipes-core/systemd/systemd_254.bb > > > >> b/meta/recipes-core/systemd/systemd_254.bb > > > >> index 8d5cf13095..65f132abb8 100644 > > > >> --- a/meta/recipes-core/systemd/systemd_254.bb > > > >> +++ b/meta/recipes-core/systemd/systemd_254.bb > > > >> @@ -6,6 +6,9 @@ PE = "1" > > > >> > > > >> DEPENDS = "intltool-native gperf-native libcap util-linux > > > >> python3-jinja2-native" > > > >> > > > >> +# The Ukify tool requires this module > > > >> +DEPENDS:append:class-native = " python3-pefile-native" > > > > Do we need to add this to OE-Core? I think this will cause current > > > > builds to fail? > > > > > > > > > I think you are right, there are some dependencies from this that are > > > not present in OE-core, this probably belongs in a different layer, at > > > least for the time being. > > > > I think that ukify is useful in OE-core. Having it in another layer > > would mean that we can not use it from the BSP layer. > > > > Can you elaborate on that first point ? That sounds like an internal > restriction / rule, so it really doesn't factor into whether or not > something needs to be in oe-core or not.
Hmm, maybe I misinterpreted the Yocyo compatibility requirements. Anyway, if we are allowed to use other layers, then it's even better. Thanks for pointing that out. > > The answer itself doesn't matter to me, I just didn't want someone > in the future to be searching and think that their BSP layer can > only use functionality from oe-core. > > Bruce > > > As the ukify is usable even without sbsign and pesign, I think we can > > do either of the following things: > > > > - Mark sbsign and pesign as recomendations instead of dependencies > > > > - Add PACAKGECONFIG for the signing support. If it is not enabled, > > replace sbsign and pesign support with the error message. > > > > -- > > With best wishes > > Dmitry > > > > > > > > > -- > - Thou shalt not follow the NULL pointer, for chaos and madness await > thee at its end > - "Use the force Harry" - Gandalf, Star Trek II -- With best wishes Dmitry
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#190996): https://lists.openembedded.org/g/openembedded-core/message/190996 Mute This Topic: https://lists.openembedded.org/mt/101106095/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-