All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] uki: Add support for building Unified Kernel Images
@ 2023-09-01 23:32 Michelle Lin
  2023-09-02  1:04 ` [OE-core] " Alejandro Enedino Hernandez Samaniego
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Michelle Lin @ 2023-09-01 23:32 UTC (permalink / raw)
  To: openembedded-core; +Cc: Michelle Lin

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
+
+    # 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



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-09-01 23:32 [PATCH] uki: Add support for building Unified Kernel Images Michelle Lin
@ 2023-09-02  1:04 ` Alejandro Enedino Hernandez Samaniego
  2023-09-02  6:53 ` Richard Purdie
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Alejandro Enedino Hernandez Samaniego @ 2023-09-02  1:04 UTC (permalink / raw)
  To: openembedded-core

[-- Attachment #1: Type: text/plain, Size: 9671 bytes --]

Acked-by: Alejandro Hernandez<alhe@linux.microsoft.com>

On 9/1/23 17:32, 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.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
> +
> +    # 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"
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#187017):https://lists.openembedded.org/g/openembedded-core/message/187017
> Mute This Topic:https://lists.openembedded.org/mt/101106095/4354175
> Group Owner:openembedded-core+owner@lists.openembedded.org
> Unsubscribe:https://lists.openembedded.org/g/openembedded-core/unsub  [alhe@linux.microsoft.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>

[-- Attachment #2: Type: text/html, Size: 10717 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  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-21 14:44   ` Erik Schilling
  2023-09-04  6:23 ` Mikko Rapeli
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 14+ messages in thread
From: Richard Purdie @ 2023-09-02  6:53 UTC (permalink / raw)
  To: Michelle Lin, openembedded-core

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.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
> +
> +    # 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?

> +
>  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"

We've long avoided a systemd-native recipe as the meaning can be easily
confused and I'm not thrilled to be adding one now.

Perhaps this should be as a separate systemd-tools-native recipe to
make it clear this isn't full systemd?

How much of systemd does this recipe compile?

Cheers,

Richard




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  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-04  6:23 ` Mikko Rapeli
  2023-11-16 11:01 ` Erik Schilling
  2023-11-28 12:32 ` Dmitry Baryshkov
  4 siblings, 0 replies; 14+ messages in thread
From: Mikko Rapeli @ 2023-09-04  6:23 UTC (permalink / raw)
  To: Michelle Lin; +Cc: openembedded-core

Hi,

On Fri, Sep 01, 2023 at 11:32:31PM +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.

Thanks, I'm interesting in using this. Could you add a oeqa selftest for this
class too? Something which builds a UKI image and then does something to verify it
is what's expected, maybe full boot with e.g. qemu is too hard to do?

Cheers,

-Mikko


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  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-21 14:44   ` Erik Schilling
  1 sibling, 1 reply; 14+ messages in thread
From: Alejandro Enedino Hernandez Samaniego @ 2023-09-06 22:29 UTC (permalink / raw)
  To: Richard Purdie, Michelle Lin, openembedded-core


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.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
>> +
>> +    # 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.


Alejandro

>
>> +
>>   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"
> We've long avoided a systemd-native recipe as the meaning can be easily
> confused and I'm not thrilled to be adding one now.
>
> Perhaps this should be as a separate systemd-tools-native recipe to
> make it clear this isn't full systemd?
>
> How much of systemd does this recipe compile?
>
> Cheers,
>
> Richard
>
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#187021): https://lists.openembedded.org/g/openembedded-core/message/187021
> Mute This Topic: https://lists.openembedded.org/mt/101106095/4354175
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [alhe@linux.microsoft.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-09-01 23:32 [PATCH] uki: Add support for building Unified Kernel Images Michelle Lin
                   ` (2 preceding siblings ...)
  2023-09-04  6:23 ` Mikko Rapeli
@ 2023-11-16 11:01 ` Erik Schilling
  2023-11-28 12:32 ` Dmitry Baryshkov
  4 siblings, 0 replies; 14+ messages in thread
From: Erik Schilling @ 2023-11-16 11:01 UTC (permalink / raw)
  To: Michelle Lin, openembedded-core; +Cc: Mikko Rapeli

On Sat Sep 2, 2023 at 1:32 AM CEST, 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.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

Thanks a lot for submitting this!

We are very interested into this. Do you have plans to respin this?

Happy to help where possible :).

- Erik


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-09-06 22:29   ` Alejandro Enedino Hernandez Samaniego
@ 2023-11-20 12:48     ` Dmitry Baryshkov
  2023-11-20 13:26       ` Bruce Ashfield
  0 siblings, 1 reply; 14+ messages in thread
From: Dmitry Baryshkov @ 2023-11-20 12:48 UTC (permalink / raw)
  To: Alejandro Hernandez Samaniego
  Cc: Richard Purdie, Michelle Lin, openembedded-core

On Thu, 7 Sept 2023 at 01:29, Alejandro Hernandez Samaniego
<alhe@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.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
> >> +
> >> +    # 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.

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


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-11-20 12:48     ` Dmitry Baryshkov
@ 2023-11-20 13:26       ` Bruce Ashfield
  2023-11-22  1:06         ` Dmitry Baryshkov
  0 siblings, 1 reply; 14+ messages in thread
From: Bruce Ashfield @ 2023-11-20 13:26 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Alejandro Hernandez Samaniego, Richard Purdie, Michelle Lin,
	openembedded-core

On Mon, Nov 20, 2023 at 7:49 AM Dmitry Baryshkov <dbaryshkov@gmail.com> wrote:
>
> On Thu, 7 Sept 2023 at 01:29, Alejandro Hernandez Samaniego
> <alhe@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.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
> > >> +
> > >> +    # 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.

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
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#190876): https://lists.openembedded.org/g/openembedded-core/message/190876
> Mute This Topic: https://lists.openembedded.org/mt/101106095/1050810
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [bruce.ashfield@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>


-- 
- Thou shalt not follow the NULL pointer, for chaos and madness await
thee at its end
- "Use the force Harry" - Gandalf, Star Trek II


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-09-02  6:53 ` Richard Purdie
  2023-09-06 22:29   ` Alejandro Enedino Hernandez Samaniego
@ 2023-11-21 14:44   ` Erik Schilling
  2023-11-22  1:09     ` Dmitry Baryshkov
  1 sibling, 1 reply; 14+ messages in thread
From: Erik Schilling @ 2023-11-21 14:44 UTC (permalink / raw)
  To: Richard Purdie, Michelle Lin, openembedded-core
  Cc: Alejandro Hernandez Samaniego, Mikko Rapeli

> > +BBCLASSEXTEND += "native"
>
> We've long avoided a systemd-native recipe as the meaning can be easily
> confused and I'm not thrilled to be adding one now.
>
> Perhaps this should be as a separate systemd-tools-native recipe to
> make it clear this isn't full systemd?

There is another catch: ukify depends on sbsign for some options. Here,
this dependency is not expressed as RDEPENDS on the systemd
components but only on the uki class. That of course gets around the
meta-security-core dependency for systemd, but not sure how pretty that
is.

So we got:
* python3-pefile in meta-python
* sbsigntool in meta-signing-key [meta-security-core]

It looks like we have these options:

1. Add the systemd-tools (or however we call it) recipe and the uki
   class in meta-signing-key or friends.

   This might become a bit icky with different systemd recipes scattered
   over different repos...

2. Do not put a RDEPENDS += "sbsigntool" into the systemd-tools recipe.
   Move python3-pefile to oe-core.

   This means that some ukify options will fail. Users will need to add
   [R]DEPENDS on their recipes if they want signing. This would allow
   adding the systemd-tools recipe in oe-core while adding the rest in
   meta-security-core.

3. Also move the signing tools to oe-core.

   Next to the python module, this also requires to move sbsigntool
   to oe-core... In the end it allows to set the RDEPENDS in
   systemd-tools.

I got no particular strong feeling on any of those outcomes... Any
opinions? 🤔

- Erik



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-11-20 13:26       ` Bruce Ashfield
@ 2023-11-22  1:06         ` Dmitry Baryshkov
  0 siblings, 0 replies; 14+ messages in thread
From: Dmitry Baryshkov @ 2023-11-22  1:06 UTC (permalink / raw)
  To: Bruce Ashfield
  Cc: Alejandro Hernandez Samaniego, Richard Purdie, Michelle Lin,
	openembedded-core

On Mon, 20 Nov 2023 at 15:26, Bruce Ashfield <bruce.ashfield@gmail.com> wrote:
>
> On Mon, Nov 20, 2023 at 7:49 AM Dmitry Baryshkov <dbaryshkov@gmail.com> wrote:
> >
> > On Thu, 7 Sept 2023 at 01:29, Alejandro Hernandez Samaniego
> > <alhe@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.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
> > > >> +
> > > >> +    # 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
> >
> > -=-=-=-=-=-=-=-=-=-=-=-
> > Links: You receive all messages sent to this group.
> > View/Reply Online (#190876): https://lists.openembedded.org/g/openembedded-core/message/190876
> > Mute This Topic: https://lists.openembedded.org/mt/101106095/1050810
> > Group Owner: openembedded-core+owner@lists.openembedded.org
> > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [bruce.ashfield@gmail.com]
> > -=-=-=-=-=-=-=-=-=-=-=-
> >
>
>
> --
> - 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


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-11-21 14:44   ` Erik Schilling
@ 2023-11-22  1:09     ` Dmitry Baryshkov
  0 siblings, 0 replies; 14+ messages in thread
From: Dmitry Baryshkov @ 2023-11-22  1:09 UTC (permalink / raw)
  To: Erik Schilling
  Cc: Richard Purdie, Michelle Lin, openembedded-core,
	Alejandro Hernandez Samaniego, Mikko Rapeli

On Tue, 21 Nov 2023 at 16:44, Erik Schilling <erik.schilling@linaro.org> wrote:
>
> > > +BBCLASSEXTEND += "native"
> >
> > We've long avoided a systemd-native recipe as the meaning can be easily
> > confused and I'm not thrilled to be adding one now.
> >
> > Perhaps this should be as a separate systemd-tools-native recipe to
> > make it clear this isn't full systemd?
>
> There is another catch: ukify depends on sbsign for some options. Here,
> this dependency is not expressed as RDEPENDS on the systemd
> components but only on the uki class. That of course gets around the
> meta-security-core dependency for systemd, but not sure how pretty that
> is.
>
> So we got:
> * python3-pefile in meta-python
> * sbsigntool in meta-signing-key [meta-security-core]
>
> It looks like we have these options:
>
> 1. Add the systemd-tools (or however we call it) recipe and the uki
>    class in meta-signing-key or friends.
>
>    This might become a bit icky with different systemd recipes scattered
>    over different repos...
>
> 2. Do not put a RDEPENDS += "sbsigntool" into the systemd-tools recipe.
>    Move python3-pefile to oe-core.
>
>    This means that some ukify options will fail. Users will need to add
>    [R]DEPENDS on their recipes if they want signing. This would allow
>    adding the systemd-tools recipe in oe-core while adding the rest in
>    meta-security-core.
>
> 3. Also move the signing tools to oe-core.
>
>    Next to the python module, this also requires to move sbsigntool
>    to oe-core... In the end it allows to set the RDEPENDS in
>    systemd-tools.
>
> I got no particular strong feeling on any of those outcomes... Any
> opinions? 🤔

My vote would be or #3 (the cleanest way), then #2. #1 is out of
question from my point of view: there are perfect usecases for
uki.bbclass, which do not involve signing. Adding dependency on
meta-security-core looks like an overkill in this case.

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-09-01 23:32 [PATCH] uki: Add support for building Unified Kernel Images Michelle Lin
                   ` (3 preceding siblings ...)
  2023-11-16 11:01 ` Erik Schilling
@ 2023-11-28 12:32 ` Dmitry Baryshkov
  2023-11-28 12:51   ` Mikko Rapeli
  4 siblings, 1 reply; 14+ messages in thread
From: Dmitry Baryshkov @ 2023-11-28 12:32 UTC (permalink / raw)
  To: Michelle Lin; +Cc: openembedded-core

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.

> +
> +    # 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
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#187017): https://lists.openembedded.org/g/openembedded-core/message/187017
> Mute This Topic: https://lists.openembedded.org/mt/101106095/3618183
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [dbaryshkov@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>


-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-11-28 12:32 ` Dmitry Baryshkov
@ 2023-11-28 12:51   ` Mikko Rapeli
  2023-11-28 13:08     ` Dmitry Baryshkov
  0 siblings, 1 reply; 14+ messages in thread
From: Mikko Rapeli @ 2023-11-28 12:51 UTC (permalink / raw)
  To: Dmitry Baryshkov; +Cc: Michelle Lin, openembedded-core

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



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [OE-core] [PATCH] uki: Add support for building Unified Kernel Images
  2023-11-28 12:51   ` Mikko Rapeli
@ 2023-11-28 13:08     ` Dmitry Baryshkov
  0 siblings, 0 replies; 14+ messages in thread
From: Dmitry Baryshkov @ 2023-11-28 13:08 UTC (permalink / raw)
  To: Mikko Rapeli; +Cc: Michelle Lin, openembedded-core

On Tue, 28 Nov 2023 at 14:52, Mikko Rapeli <mikko.rapeli@linaro.org> wrote:
>
> 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.

My preference would be if we can skip them completely. I'd prefer to
be able to build the generic UKI image even if KERNEL_DEVICETREE is
defined (and maybe put DTs to the addons).

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


-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-11-28 13:09 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2023-11-28 13:08     ` Dmitry Baryshkov

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.