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]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to