diff mbox series

[v2,1/2] cdrtools-native: fix booting EFI ISO live failed

Message ID 20250426080352.2358278-1-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
In ISO live, if the size of efi.img > 32MB, and copy EFI application
(bootx64.efi) to efi.img behind of kernel and initrd, UEFI system
could not find EFI application bootx64.efi

Using QEMU+OVMF to boot ISO live image, press ESC to enter UEFI shell:
...
Shell> ls FS0:\
Directory of: FS0:\
04/05/2011  23:00          12,985,344  bzImage
04/05/2011  23:00 <DIR>         2,048  EFI
04/05/2011  23:00          20,494,696  initrd
04/05/2011  23:00                  26  startup.nsh
          3 File(s)  33,480,066 bytes
          1 Dir(s)

Shell> ls FS0:\EFI
Directory of: FS0:\EFI
          0 File(s)           0 bytes
          0 Dir(s)
...

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

$ 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  54079   53960 26.3M ef EFI (FAT-12/16/32)

According to page 11: `Figure 5 - Section Entry' in El Torito Bootable
CD-ROM Format Specification [1]. The sector count takes 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)

This commit truncate to 32MB if image size larger than 32MB, and
report a warning, then save the extra image sector count to
vendor unique selection criteria

After apply this commit, the partition table of EFI is truncated to 32M
$ 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)

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

Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
---
 .../cdrtools/cdrtools-native_3.01.bb          |  1 +
 ...ix-nsectors-exceeds-0xffff-situation.patch | 69 +++++++++++++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 meta/recipes-devtools/cdrtools/cdrtools/0001-fix-nsectors-exceeds-0xffff-situation.patch
diff mbox series

Patch

diff --git a/meta/recipes-devtools/cdrtools/cdrtools-native_3.01.bb b/meta/recipes-devtools/cdrtools/cdrtools-native_3.01.bb
index 085384064d0..428202c2585 100644
--- a/meta/recipes-devtools/cdrtools/cdrtools-native_3.01.bb
+++ b/meta/recipes-devtools/cdrtools/cdrtools-native_3.01.bb
@@ -15,6 +15,7 @@  SRC_URI = " \
 	file://0001-Don-t-set-uid-gid-during-install.patch \
 	file://riscv64-linux-gcc.rul \
 	file://gcc14-fix.patch \
+	file://0001-fix-nsectors-exceeds-0xffff-situation.patch \
 	"
 
 SRC_URI[md5sum] = "7d45c5b7e1f78d85d1583b361aee6e8b"
diff --git a/meta/recipes-devtools/cdrtools/cdrtools/0001-fix-nsectors-exceeds-0xffff-situation.patch b/meta/recipes-devtools/cdrtools/cdrtools/0001-fix-nsectors-exceeds-0xffff-situation.patch
new file mode 100644
index 00000000000..8b0fbb3fe6d
--- /dev/null
+++ b/meta/recipes-devtools/cdrtools/cdrtools/0001-fix-nsectors-exceeds-0xffff-situation.patch
@@ -0,0 +1,69 @@ 
+From ab6b5ee4c23099bf15ddd145fdf1ff4f5e34e802 Mon Sep 17 00:00:00 2001
+From: Hongxu Jia <hongxu.jia@windriver.com>
+Date: Sat, 26 Apr 2025 03:38:32 +0000
+Subject: [PATCH] fix nsectors exceeds 0xffff situation
+
+According to page 11: `Figure 5 - Section Entry' in El Torito Bootable
+CD-ROM Format Specification [1]. The sector count takes 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.
+
+In this patch, nsectors means sector count, if it exceeds 0xffff,
+truncate to 0xffff and set selection criteria type = 2, then save
+extra nsectors to vendor unique selection criteria
+
+[1]https://pdos.csail.mit.edu/6.828/2017/readings/boot-cdrom.pdf
+
+Upstream-Status: Inappropriate [upstream https://sourceforge.net/projects/cdrtools/ is not alive since 2019]
+
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+---
+ mkisofs/eltorito.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/mkisofs/eltorito.c b/mkisofs/eltorito.c
+index 5dd04bc..a391003 100644
+--- a/mkisofs/eltorito.c
++++ b/mkisofs/eltorito.c
+@@ -568,6 +568,34 @@ fill_boot_desc(boot_desc_entry, boot_entry)
+ 	fprintf(stderr, "Extent of boot images is %d\n",
+ 				get_733(de->isorec.extent));
+ #endif
++
++	// Boot sectors exceeds 0xffff
++	if (nsectors > 0xffff) {
++		unsigned int extra_nsectors = nsectors - 0xffff;
++
++		fprintf(stderr, "Warning: Boot sectors 0x%x(%u) exceeds 0xffff(65535), save extra %u to pad2\n",
++		    nsectors, nsectors, extra_nsectors);
++
++		// Set nsectors to maximum 0xffff(65535)
++		nsectors = 0xffff;
++
++		// Offset     : 0C byte
++		// Type       : Byte
++		// Description: Selection criteria type. This defines a vendor unique format
++		// for bytes 0D-1F.
++		// The following formats is reserved by Yocto:
++		// 2 - Save extra sector count to vendor unique selection criteria
++		boot_desc_entry->pad2[0] = 2;
++
++
++		// Offset     : 0D-0E-0F-10 byte
++		// Type       : D Word
++		// Description: Save extra sector count to vendor unique selection criteria.
++		// It takes 4 bytes in pad2, starting at pad2[1]
++		set_731(&boot_desc_entry->pad2[1], extra_nsectors);
++
++	}
++
+ 	set_721(boot_desc_entry->nsect, (unsigned int) nsectors);
+ 	set_731(boot_desc_entry->bootoff,
+ 		(unsigned int) get_733(de->isorec.extent));
+-- 
+2.44.1
+