diff mbox series

[v2,2/2] syslinux: improve isohybrid to process extra sector count for ISO 9660 image

Message ID 20250426080352.2358278-2-hongxu.jia@windriver.com
State New
Headers show
Series [v2,1/2] cdrtools-native: fix booting EFI ISO live failed | expand

Commit Message

Hongxu Jia April 26, 2025, 8:03 a.m. UTC
Due to commit [cdrtools-native: fix booting EFI ISO live failed]
applied to improve mkisofs to fix nsectors exceeds 0xffff situation
which set selection criteria type = 2 and save extra nsectors to
vendor unique selection criteria

In following case, add 64MB extra space to bootable image efi.img,
and the partition table of EFI is truncated to 32M

$ echo 'IMAGE_FSTYPES:pn-core-image-minimal = " live"' >> conf/local.conf
$ echo 'MACHINE_FEATURES:append = " efi pcbios"' >> conf/local.conf
$ echo '# 64MB extra space to bootable image efi.img' >> conf/local.conf
$ echo 'BOOTIMG_EXTRA_SPACE = "65535"' >> conf/local.conf
$ bitbake core-image-minimal
$ fdisk -l tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.iso
...
Device                                                                 Boot Start    End Sectors  Size Id Type
tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.iso1 *        0 376831  376832  184M  0 Empty
tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.iso2        120  65654   65535   32M ef EFI (FAT-12/16/32)

After applying this patch to process extra sector count, the partition
table of EFI is 90.3M

$ fdisk -l tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.iso
...
Device                                                                 Boot Start    End Sectors  Size Id Type
tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.iso1 *        0 376831  376832  184M  0 Empty
tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.iso2        120 185151  185032 90.3M ef EFI (FAT-12/16/32)

[1]https://pdos.csail.mit.edu/6.828/2017/readings/boot-cdrom.pdf

Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
---
 ...-count-from-section-entry-for-EFI-ca.patch | 104 ++++++++++++++++++
 .../syslinux/syslinux_6.04-pre2.bb            |   1 +
 2 files changed, 105 insertions(+)
 create mode 100644 meta/recipes-devtools/syslinux/syslinux/0001-Add-extra-sector-count-from-section-entry-for-EFI-ca.patch
diff mbox series

Patch

diff --git a/meta/recipes-devtools/syslinux/syslinux/0001-Add-extra-sector-count-from-section-entry-for-EFI-ca.patch b/meta/recipes-devtools/syslinux/syslinux/0001-Add-extra-sector-count-from-section-entry-for-EFI-ca.patch
new file mode 100644
index 00000000000..5422d9b2dea
--- /dev/null
+++ b/meta/recipes-devtools/syslinux/syslinux/0001-Add-extra-sector-count-from-section-entry-for-EFI-ca.patch
@@ -0,0 +1,104 @@ 
+From 79a26046d178ae132cb88ba75de7141bd169ff16 Mon Sep 17 00:00:00 2001
+From: Hongxu Jia <hongxu.jia@windriver.com>
+Date: Sat, 26 Apr 2025 10:45:08 +0800
+Subject: [PATCH] Add extra sector count from section entry for EFI catalogue
+
+According to page 11: `Figure 5 - Section Entry' in El Torito Bootable
+CD-ROM Format Specification [1]. The sector count tooks 2 byte which
+means max sector count is 0xffff (65535), for 512-byte sector, the
+size of bootable image is no more than 32MB (65536 * 512 / 1024 / 1024)
+
+If the size of efi.img > 32MB, the partition table will be truncated
+in ISO, which caused UEFI system or grub-efi read efi.img broken
+occasionally.
+
+This patch extend efi_count, mac_count and count to 4 byte int, if
+Yocto defines `Selection criteria type = 2', add extra sector count
+to original sector count as total count; for other situation, still use
+original sector count as usual
+
+[1]https://pdos.csail.mit.edu/6.828/2017/readings/boot-cdrom.pdf
+
+Upstream-Status: Inappropriate [Yocto specific]
+
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+---
+ utils/isohybrid.c | 48 ++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 43 insertions(+), 5 deletions(-)
+
+diff --git a/utils/isohybrid.c b/utils/isohybrid.c
+index a9e38d4..1bbfd45 100644
+--- a/utils/isohybrid.c
++++ b/utils/isohybrid.c
+@@ -76,7 +76,7 @@ uint32_t de_lba = 0;
+ uint16_t de_seg = 0, de_count = 0, de_mbz2 = 0;
+ uint8_t de_boot = 0, de_media = 0, de_sys = 0, de_mbz1 = 0;
+ uint32_t efi_lba = 0, mac_lba = 0;
+-uint16_t efi_count = 0, mac_count = 0;
++uint32_t efi_count = 0, mac_count = 0;
+ uint8_t efi_boot = 0, efi_media = 0, efi_sys = 0;
+ 
+ int apm_parts = 3;
+@@ -552,17 +552,55 @@ read_efi_section(const uint8_t *buf)
+ }
+ 
+ int
+-read_efi_catalogue(const uint8_t *buf, uint16_t *count, uint32_t *lba)
++read_efi_catalogue(const uint8_t *buf, uint32_t *count, uint32_t *lba)
+ {
++    uint16_t _count = 0;
++
++    // Jump to offset 6 byte
+     buf += 6;
+ 
+-    memcpy(count, buf, 2);
+-    *count = lendian_short(*count);
++    *count = 0;
++
++    // Offset     : 6-7 byte
++    // Type       : Word
++    // Description: Sector Count, the number of virtual/emulated sectors
++    // the system will store at Load Segment during the initial boot procedure
++    memcpy(&_count, buf, 2);
++    _count = lendian_short(_count);
+     buf += 2;
+ 
++    // Offset     : 8-0B byte
++    // Type       : D Word
++    // Description: Load RBA. This is the start address of the virtual disk. CD’s use
++    // Relative/Logical block addressing.
+     memcpy(lba, buf, 4);
+     *lba = lendian_int(*lba);
+-    buf += 6;
++    buf += 4;
++
++    // Offset     : 0C byte
++    // Type       : Byte
++    // Description: Selection criteria type. This defines a vendor unique format
++    // for bytes 0D-1F.
++    // The following formats have currently been assigned:
++    // 0 - No selection criteria
++    // 1 - Language and Version Information (IBM)
++    // 2 - Save extra sector count to vendor unique selection criteria (Yocto)
++    // 3-FF - Reserved
++    unsigned char slection_criteria_type = *buf;
++    buf += 1;
++
++    // Offset     : 0D-0E-0F-10 byte
++    // Type       : D Word
++    // Description: Selection criteria type = 2, reserved by Yocto,
++    // save extra sector count to vendor unique selection criteria
++    if (slection_criteria_type == 2) {
++        memcpy(count, buf, 4);
++        *count = lendian_int(*count);
++        buf += 4;
++    }
++
++    // total count = sector count + extra sector count
++    *count += _count;
+ 
+     return 0;
+ }
+-- 
+2.34.1
+
diff --git a/meta/recipes-devtools/syslinux/syslinux_6.04-pre2.bb b/meta/recipes-devtools/syslinux/syslinux_6.04-pre2.bb
index 7cf737170c3..2522205fa1c 100644
--- a/meta/recipes-devtools/syslinux/syslinux_6.04-pre2.bb
+++ b/meta/recipes-devtools/syslinux/syslinux_6.04-pre2.bb
@@ -23,6 +23,7 @@  SRC_URI = "https://www.zytor.com/pub/syslinux/Testing/6.04/syslinux-${PV}.tar.xz
            file://0013-remove-clean-script.patch \
            file://0014-Fix-reproducibility-issues.patch \
            file://0001-ext2_fs.h-do-not-carry-an-outdated-copy.patch \
+           file://0001-Add-extra-sector-count-from-section-entry-for-EFI-ca.patch \
            "
 
 SRC_URI[md5sum] = "2b31c78f087f99179feb357da312d7ec"