All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mikko Rapeli <mikko.rapeli@linaro.org>
To: Dmitry Baryshkov <dbaryshkov@gmail.com>
Cc: Michelle Lin <michelle.linto91@gmail.com>,
	openembedded-core@lists.openembedded.org
Subject: Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
Date: Tue, 28 Nov 2023 14:51:57 +0200	[thread overview]
Message-ID: <ZWXibQvpZls3Cg_g@nuoska> (raw)
In-Reply-To: <CALT56yM7fL9sSqW-mO64BoHz=SrJi8aOHCQqqbe64b+vpSSijw@mail.gmail.com>

Hi,

On Tue, Nov 28, 2023 at 02:32:14PM +0200, Dmitry Baryshkov wrote:
> On Sat, 2 Sept 2023 at 02:32, Michelle Lin <michelle.linto91@gmail.com> 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.linto91@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
> 
> Hmm, I have not noticed this before. This doesn't look generic enough.
> KERNEL_DEVICETREE can have several DT files and the first one is not
> in any way special. It should not be picked up for the UKI image.
> E.g. in our (meta-qcom / qcom-armv8a) case the KERNEL_DEVICETREE lists
> dtb for all supported machines, ranging from the old dragonboard410c
> up to the latest HDKs.

So all decice tree files should be looped in. I hope ukify.py supports
this but IMO it should.

Cheers,

-Mikko
 
> > +
> > +    # 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"
> > +
> >  SECTION = "base/shell"
> >
> >  inherit useradd pkgconfig meson perlnative update-rc.d update-alternatives qemu systemd gettext bash-completion manpages features_check
> > @@ -18,6 +21,8 @@ REQUIRED_DISTRO_FEATURES += "usrmerge"
> >  # that we don't build both udev and systemd in world builds.
> >  REQUIRED_DISTRO_FEATURES += "systemd"
> >
> > +REQUIRED_DISTRO_FEATURES:class-native = ""
> > +
> >  SRC_URI += " \
> >             file://touchscreen.rules \
> >             file://00-create-volatile.conf \
> > @@ -120,6 +125,8 @@ PACKAGECONFIG:remove:libc-musl = " \
> >  # https://github.com/seccomp/libseccomp/issues/347
> >  PACKAGECONFIG:remove:mipsarch = "seccomp"
> >
> > +PACKAGECONFIG:class-native = "serial-getty-generator openssl tpm2 efi"
> > +
> >  TARGET_CC_ARCH:append:libc-musl = " -D__UAPI_DEF_ETHHDR=0 -D_LARGEFILE64_SOURCE"
> >
> >  # Some of the dependencies are weak-style recommends - if not available at runtime,
> > @@ -260,6 +267,9 @@ EXTRA_OEMESON += "-Dkexec-path=${sbindir}/kexec \
> >                    -Dloadkeys-path=${bindir}/loadkeys \
> >                    -Dsetfont-path=${bindir}/setfont"
> >
> > +EXTRA_OEMESON:append:class-native = " -Dbootloader=true \
> > +                                      -Dman=false \
> > +                                    "
> >  # The 60 seconds is watchdog's default vaule.
> >  WATCHDOG_TIMEOUT ??= "60"
> >
> > @@ -380,6 +390,14 @@ do_install() {
> >      fi
> >  }
> >
> > +do_install:class-native() {
> > +       meson_do_install
> > +       install -d ${D}${bindir}
> > +       install -m 0755 ${S}/src/ukify/ukify.py ${D}${bindir}/ukify
> > +       install -d ${D}${prefix}/lib/systemd/tools
> > +       install -m 0755 ${B}/systemd-measure ${D}${prefix}/lib/systemd/tools
> > +}
> > +
> >  python populate_packages:prepend (){
> >      systemdlibdir = d.getVar("rootlibdir")
> >      do_split_packages(d, systemdlibdir, r'^lib(.*)\.so\.*', 'lib%s', 'Systemd %s library', extra_depends='', allow_links=True)
> > @@ -702,6 +720,9 @@ RRECOMMENDS:${PN} += "systemd-extra-utils \
> >                        ${@bb.utils.contains('PACKAGECONFIG', 'logind', 'pam-plugin-umask', '', d)} \
> >  "
> >
> > +RRECOMMENDS:${PN}:class-native = ""
> > +RDEPENDS:${PN}:class-native = ""
> > +
> >  INSANE_SKIP:${PN} += "dev-so libdir"
> >  INSANE_SKIP:${PN}-dbg += "libdir"
> >  INSANE_SKIP:${PN}-doc += " libdir"
> > @@ -852,3 +873,5 @@ pkg_postinst:udev-hwdb () {
> >  pkg_prerm:udev-hwdb () {
> >         rm -f $D${sysconfdir}/udev/hwdb.bin
> >  }
> > +
> > +BBCLASSEXTEND += "native"
> > --
> > 2.34.1
> >
> >
> > 
> >
> 
> 
> -- 
> With best wishes
> Dmitry

> 
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#191364): https://lists.openembedded.org/g/openembedded-core/message/191364
> Mute This Topic: https://lists.openembedded.org/mt/101106095/7159507
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [mikko.rapeli@linaro.org]
> -=-=-=-=-=-=-=-=-=-=-=-
> 



  reply	other threads:[~2023-11-28 12:52 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-01 23:32 [PATCH] uki: Add support for building Unified Kernel Images Michelle Lin
2023-09-02  1:04 ` [OE-core] " Alejandro Enedino Hernandez Samaniego
2023-09-02  6:53 ` Richard Purdie
2023-09-06 22:29   ` Alejandro Enedino Hernandez Samaniego
2023-11-20 12:48     ` Dmitry Baryshkov
2023-11-20 13:26       ` Bruce Ashfield
2023-11-22  1:06         ` Dmitry Baryshkov
2023-11-21 14:44   ` Erik Schilling
2023-11-22  1:09     ` Dmitry Baryshkov
2023-09-04  6:23 ` Mikko Rapeli
2023-11-16 11:01 ` Erik Schilling
2023-11-28 12:32 ` Dmitry Baryshkov
2023-11-28 12:51   ` Mikko Rapeli [this message]
2023-11-28 13:08     ` Dmitry Baryshkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZWXibQvpZls3Cg_g@nuoska \
    --to=mikko.rapeli@linaro.org \
    --cc=dbaryshkov@gmail.com \
    --cc=michelle.linto91@gmail.com \
    --cc=openembedded-core@lists.openembedded.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.