From: Alexandre Belloni <alexandre.belloni@bootlin.com>
To: Andrey Popov <andrey.popov@yadro.com>
Cc: openembedded-core@lists.openembedded.org
Subject: Re: [OE-core] [PATCH v3] image-live: Add support for building EFI-bootable ISO images for non-x86-based archs
Date: Sat, 2 Dec 2023 20:03:28 +0100 [thread overview]
Message-ID: <20231202190328142d6d70@mail.local> (raw)
In-Reply-To: <20231130161624.1833206-1-andrey.popov@yadro.com>
Hello,
This fails on the AB:
https://autobuilder.yoctoproject.org/typhoon/#/builders/58/builds/8051/steps/12/logs/errors
ERROR: Nothing PROVIDES 'libisoburn-native'.
On 30/11/2023 19:16:24+0300, Andrey Popov wrote:
> Since syslinux is only compatible with platforms that use x86-based
> CPUs, this change allows creation of bootable ISO images for other
> EFI-compatible platforms by replacing invocation of the isohybrid
> tool for those platforms with a python script that creates MBR
> partition table with a single entry that points to a bootable
> EFI image placed inside the ISO image.
>
> Signed-off-by: Andrey Popov <andrey.popov@yadro.com>
> ---
> meta/classes-recipe/image-live.bbclass | 124 ++++++++++++++++++-------
> 1 file changed, 92 insertions(+), 32 deletions(-)
>
> diff --git a/meta/classes-recipe/image-live.bbclass b/meta/classes-recipe/image-live.bbclass
> index 95dd44a..c01bc71 100644
> --- a/meta/classes-recipe/image-live.bbclass
> +++ b/meta/classes-recipe/image-live.bbclass
> @@ -2,15 +2,15 @@
> #
> # SPDX-License-Identifier: MIT
>
> -# Creates a bootable image using syslinux, your kernel and an optional
> +# Creates a bootable image using syslinux (for x86), your kernel and an optional
> # initrd
>
> #
> # End result is two things:
> #
> -# 1. A .hddimg file which is an msdos filesystem containing syslinux, a kernel,
> -# an initrd and a rootfs image. These can be written to harddisks directly and
> -# also booted on USB flash disks (write them there with dd).
> +# 1. A .hddimg file which is an msdos filesystem containing syslinux (for x86),
> +# a kernel, an initrd and a rootfs image. These can be written to harddisks
> +# directly and also booted on USB flash disks (write them there with dd).
> #
> # 2. A CD .iso image
>
> @@ -18,6 +18,10 @@
> # in syslinux. Actions based on the label are then performed (e.g. installing to
> # an hdd)
>
> +# Since some versions of isohybrid are still looking for the isolinux.bin inside
> +# the target image, if machine does not have pcbios feature defined we have to
> +# use our own method to create EFI-bootable MBR.
> +
> # External variables (also used by syslinux.bbclass)
> # ${INITRD} - indicates a list of filesystem images to concatenate and use as an initrd (optional)
> # ${HDDIMG_ID} - FAT image volume-id
> @@ -29,8 +33,12 @@ do_bootimg[depends] += "dosfstools-native:do_populate_sysroot \
> mtools-native:do_populate_sysroot \
> cdrtools-native:do_populate_sysroot \
> virtual/kernel:do_deploy \
> - ${MLPREFIX}syslinux:do_populate_sysroot \
> - syslinux-native:do_populate_sysroot \
> + ${@bb.utils.contains('MACHINE_FEATURES', 'pcbios', \
> + d.getVar('MLPREFIX') + 'syslinux:do_populate_sysroot \
> + syslinux-native:do_populate_sysroot', '', d)} \
> + ${@bb.utils.contains('MACHINE_FEATURES', 'efi', \
> + bb.utils.contains('MACHINE_FEATURES', 'pcbios', \
> + '', 'libisoburn-native:do_populate_sysroot', d), '', d)} \
> ${@'%s:do_image_%s' % (d.getVar('PN'), d.getVar('LIVE_ROOTFS_TYPE').replace('-', '_')) if d.getVar('ROOTFS') else ''} \
> "
>
> @@ -66,19 +74,65 @@ COMPACT_ISODIR = "${S}/iso.z"
> ISOLINUXDIR ?= "/isolinux"
> ISO_BOOTIMG = "isolinux/isolinux.bin"
> ISO_BOOTCAT = "isolinux/boot.cat"
> -MKISOFS_OPTIONS = "-no-emul-boot -boot-load-size 4 -boot-info-table"
> +MKISOFS_BOOT_OPTIONS = "-no-emul-boot -boot-load-size 4 -boot-info-table"
>
> BOOTIMG_VOLUME_ID ?= "boot"
> BOOTIMG_EXTRA_SPACE ?= "512"
>
> +def compute_chs(sector_z):
> + C = int(sector_z / (63 * 255))
> + H = int((sector_z % (63 * 255)) / 63)
> + # convert zero-based sector to CHS format
> + S = int(sector_z % 63) + 1
> + # munge accord to partition table format
> + S = (S & 0x3f) | (((C >> 8) & 0x3) << 6)
> + C = (C & 0xFF)
> + return (C, H, S)
> +
> +def mk_efi_part_table(iso, start, length):
> + from struct import pack
> +
> + # Compute starting and ending CHS addresses for the partition entry.
> + (s_C, s_H, s_S) = compute_chs(start)
> + (e_C, e_H, e_S) = compute_chs(start + length - 1)
> +
> + # Write the 66 byte partition table to bytes 0x1BE through 0x1FF in
> + # sector 0 of the .ISO.
> + #
> + # See the partition table format here:
> + # http://en.wikipedia.org/wiki/Master_boot_record#Sector_layout
> + f = open(iso, 'r+b')
> + f.seek(0x1BE)
> + f.write(pack("<8BLL48xH", 0x80, s_H, s_S, s_C,
> + 0xEF, e_H, e_S, e_C, start, length, 0xAA55))
> + f.close()
> +
> +def install_efi_part_table(iso_img):
> + import subprocess
> +
> + find_efi_img_cmd = "xorriso -indev %s -find /efi.img \
> + -name efi.img -exec report_lba --" % iso_img
> + ret = subprocess.run(find_efi_img_cmd.split(), capture_output=True)
> + efi_img_start = -1
> + efi_img_length = -1
> + for line in ret.stdout.decode(encoding='utf-8').split("\n"):
> + if "File data lba:" in line and "/efi.img" in line:
> + file_stat = line[14:].split(',')
> + efi_img_start = int(file_stat[1].strip()) * 4
> + efi_img_length = int(int(file_stat[3].strip()) / 512)
> + break
> + if (efi_img_start < 0) or (efi_img_length < 0):
> + bb.fatal("Failed to determine /efi.img attributes")
> + mk_efi_part_table(iso_img, efi_img_start, efi_img_length)
> +
> populate_live() {
> - populate_kernel $1
> + populate_kernel $1
> if [ -s "${ROOTFS}" ]; then
> install -m 0644 ${ROOTFS} $1/rootfs.img
> fi
> }
>
> -build_iso() {
> +build_iso_base() {
> # Only create an ISO if we have an INITRD and the live or iso image type was selected
> if [ -z "${INITRD}" ] || [ "${@bb.utils.contains_any('IMAGE_FSTYPES', 'live iso', '1', '0', d)}" != "1" ]; then
> bbnote "ISO image will not be created."
> @@ -103,14 +157,6 @@ build_iso() {
> build_fat_img ${EFIIMGDIR} ${ISODIR}/efi.img
> fi
>
> - # EFI only
> - if [ "${PCBIOS}" != "1" ] && [ "${EFI}" = "1" ] ; then
> - # Work around bug in isohybrid where it requires isolinux.bin
> - # In the boot catalog, even though it is not used
> - mkdir -p ${ISODIR}/${ISOLINUXDIR}
> - install -m 0644 ${STAGING_DATADIR}/syslinux/isolinux.bin ${ISODIR}${ISOLINUXDIR}
> - fi
> -
> # We used to have support for zisofs; this is a relic of that
> mkisofs_compress_opts="-r"
>
> @@ -128,26 +174,40 @@ build_iso() {
> fi
> fi
>
> - if [ "${PCBIOS}" = "1" ] && [ "${EFI}" != "1" ] ; then
> - # PCBIOS only media
> - mkisofs -V ${BOOTIMG_VOLUME_ID} \
> - -o ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso \
> - -b ${ISO_BOOTIMG} -c ${ISO_BOOTCAT} \
> - $mkisofs_compress_opts \
> - ${MKISOFS_OPTIONS} $mkisofs_iso_level ${ISODIR}
> + if [ "${PCBIOS}" = "1" ]; then
> + if [ "${EFI}" = "1" ]; then
> + # EFI+PCBIOS
> + mkisofs -A ${BOOTIMG_VOLUME_ID} -V ${BOOTIMG_VOLUME_ID} \
> + -o ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso \
> + -b ${ISO_BOOTIMG} -c ${ISO_BOOTCAT} \
> + $mkisofs_compress_opts ${MKISOFS_BOOT_OPTIONS} $mkisofs_iso_level \
> + -eltorito-alt-boot -eltorito-platform efi \
> + -b efi.img -no-emul-boot \
> + ${ISODIR}
> + isohybrid_args="-u"
> + else
> + # PCBIOS only
> + mkisofs -V ${BOOTIMG_VOLUME_ID} \
> + -o ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso \
> + -b ${ISO_BOOTIMG} -c ${ISO_BOOTCAT} \
> + $mkisofs_compress_opts \
> + ${MKISOFS_BOOT_OPTIONS} $mkisofs_iso_level ${ISODIR}
> + fi
> +
> + isohybrid $isohybrid_args ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso
> else
> - # EFI only OR EFI+PCBIOS
> mkisofs -A ${BOOTIMG_VOLUME_ID} -V ${BOOTIMG_VOLUME_ID} \
> - -o ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso \
> - -b ${ISO_BOOTIMG} -c ${ISO_BOOTCAT} \
> - $mkisofs_compress_opts ${MKISOFS_OPTIONS} $mkisofs_iso_level \
> - -eltorito-alt-boot -eltorito-platform efi \
> - -b efi.img -no-emul-boot \
> + -o ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso \
> + $mkisofs_compress_opts $mkisofs_iso_level \
> ${ISODIR}
> - isohybrid_args="-u"
> fi
> +}
>
> - isohybrid $isohybrid_args ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso
> +python build_iso() {
> + bb.build.exec_func("build_iso_base", d)
> + if d.getVar("PCBIOS") != "1" and d.getVar("EFI") == "1":
> + install_efi_part_table(d.getVar("IMGDEPLOYDIR") + "/" + \
> + d.getVar("IMAGE_NAME") + ".iso")
> }
>
> build_fat_img() {
> --
> 2.34.1
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#191512): https://lists.openembedded.org/g/openembedded-core/message/191512
> Mute This Topic: https://lists.openembedded.org/mt/102896781/3617179
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [alexandre.belloni@bootlin.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
next prev parent reply other threads:[~2023-12-02 19:03 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-30 16:16 [PATCH v3] image-live: Add support for building EFI-bootable ISO images for non-x86-based archs Andrey Popov
2023-12-02 19:03 ` Alexandre Belloni [this message]
2023-12-04 13:33 ` Andrey Popov
2023-12-04 14:35 ` [OE-core] " Alexander Kanavin
2023-12-04 14:46 ` Andrey Popov
2023-12-05 9:43 ` [OE-core] " Alexander Kanavin
2023-12-04 14:13 ` Alexander Kanavin
2023-12-04 14:26 ` Andrey Popov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231202190328142d6d70@mail.local \
--to=alexandre.belloni@bootlin.com \
--cc=andrey.popov@yadro.com \
--cc=openembedded-core@lists.openembedded.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox