Splux Linux

source-based Linux using SPS

SPS · log · files · refs · tags · releases · people · languages · GitHub · commit

70adfea


mkiso: make the image bootable from USB, not just from virtual media

Date
Commit70adfea60415a7cd0b375d820f62d74266ef53d5
GitHubmirror

Parents

Stat

 bin/mkiso           | 65 ++++++++++++++++++++++++++++++++++++++++++++---------
 tests/test_mkiso.sh | 21 +++++++++++++++++
 2 files changed, 76 insertions(+), 10 deletions(-)

Diff

diff --git a/bin/mkiso b/bin/mkiso
index 121e9fd..9995ef1 100755
--- a/bin/mkiso
+++ b/bin/mkiso
@@ -1048,9 +1048,10 @@ mkiso_verify_plasma()
 	then
 		mkiso_miss="$mkiso_miss usr/bin/Xwayland"
 	fi
-	if ! ls "$mkiso_live"/usr/share/fonts/TTF/*.ttf >/dev/null 2>&1
+	if ! find "$mkiso_live/usr/share/fonts" -type f -name '*.ttf' \
+		-print -quit 2>/dev/null | grep -q .
 	then
-		mkiso_miss="$mkiso_miss usr/share/fonts/TTF"
+		mkiso_miss="$mkiso_miss TrueType fonts"
 	fi
 	[ -z "$mkiso_miss" ] ||
 		sps_die "$SPS_EX_PACKAGE" "plasma image missing:$mkiso_miss"
@@ -1421,7 +1422,9 @@ mkiso_copy_plasma()
 	# Host fontconfig prefers Liberation Sans. DejaVu alone leaves
 	# fc-match pointing at a file that is not on the disc.
 	for mkiso_font in /usr/share/fonts/TTF/DejaVu*.ttf \
-		/usr/share/fonts/TTF/Liberation*.ttf
+		/usr/share/fonts/TTF/Liberation*.ttf \
+		/usr/share/fonts/X11/dejavu/DejaVu*.ttf \
+		/usr/share/fonts/X11/liberation-fonts/Liberation*.ttf
 	do
 		[ -e "$mkiso_font" ] || continue
 		mkiso_copy_path "$mkiso_font"
@@ -1868,10 +1871,17 @@ if ! mksquashfs "$mkiso_live" "$mkiso_iso/live/filesystem.squashfs" \
 	-e boot tmp var/tmp var/cache
 then
 	printf '%s: zstd squashfs failed, trying xz\n' "$sps_prog" >&2
-	mksquashfs "$mkiso_live" "$mkiso_iso/live/filesystem.squashfs" \
+	if ! mksquashfs "$mkiso_live" "$mkiso_iso/live/filesystem.squashfs" \
 		-comp xz -noappend -no-progress -processors "$mkiso_squash_jobs" \
-		-e boot tmp var/tmp var/cache ||
-		sps_die "$SPS_EX_BUILD" "mksquashfs failed"
+		-e boot tmp var/tmp var/cache
+	then
+		printf '%s: xz squashfs failed, trying gzip\n' "$sps_prog" >&2
+		mksquashfs "$mkiso_live" "$mkiso_iso/live/filesystem.squashfs" \
+			-comp gzip -noappend -no-progress \
+			-processors "$mkiso_squash_jobs" \
+			-e boot tmp var/tmp var/cache ||
+			sps_die "$SPS_EX_BUILD" "mksquashfs failed"
+	fi
 fi
 
 # Initramfs: busybox + init + filesystem modules.
@@ -1971,6 +1981,8 @@ EOF
 # grub-install on a disk.
 command -v grub-mkimage >/dev/null 2>&1 ||
 	sps_die "$SPS_EX_PACKAGE" "grub-mkimage is required"
+mkiso_grub_pc_cmd=$(command -v grub-mkimage)
+mkiso_grub_efi_cmd=$mkiso_grub_pc_cmd
 mkiso_pc=
 mkiso_efi=
 for mkiso_gdir in /usr/lib64/grub /usr/lib/grub
@@ -1978,18 +1990,36 @@ do
 	[ -d "$mkiso_gdir/i386-pc" ] && mkiso_pc=$mkiso_gdir/i386-pc
 	[ -d "$mkiso_gdir/x86_64-efi" ] && mkiso_efi=$mkiso_gdir/x86_64-efi
 done
+if command -v brew >/dev/null 2>&1; then
+	mkiso_brew_pc=$(brew --prefix i686-elf-grub 2>/dev/null || :)
+	if [ -d "$mkiso_brew_pc/lib/i686-elf/grub/i386-pc" ]; then
+		mkiso_pc=$mkiso_brew_pc/lib/i686-elf/grub/i386-pc
+		if command -v i686-elf-grub-mkimage >/dev/null 2>&1; then
+			mkiso_grub_pc_cmd=$(command -v i686-elf-grub-mkimage)
+		fi
+	fi
+	mkiso_brew_efi=$(brew --prefix x86_64-elf-grub 2>/dev/null || :)
+	if [ -d "$mkiso_brew_efi/lib/x86_64-elf/grub/x86_64-efi" ]; then
+		mkiso_efi=$mkiso_brew_efi/lib/x86_64-elf/grub/x86_64-efi
+		if command -v x86_64-elf-grub-mkimage >/dev/null 2>&1; then
+			mkiso_grub_efi_cmd=$(command -v x86_64-elf-grub-mkimage)
+		fi
+	fi
+fi
 [ -n "$mkiso_pc" ] ||
 	sps_die "$SPS_EX_PACKAGE" "GRUB i386-pc modules not found"
 
 mkiso_grub_mods='iso9660 linux normal configfile echo search fat part_gpt part_msdos ext2 serial'
-grub-mkimage -O i386-pc -o "$mkiso_work/core.img" -p /boot/grub \
+"$mkiso_grub_pc_cmd" -d "$mkiso_pc" -O i386-pc \
+	-o "$mkiso_work/core.img" -p /boot/grub \
 	biosdisk $mkiso_grub_mods ||
 	sps_die "$SPS_EX_BUILD" "grub-mkimage (i386-pc) failed"
 cat "$mkiso_pc/cdboot.img" "$mkiso_work/core.img" >"$mkiso_iso/boot/grub/bios.img"
 
 mkdir -p "$mkiso_iso/EFI/BOOT"
 if [ -n "$mkiso_efi" ]; then
-	grub-mkimage -O x86_64-efi -o "$mkiso_iso/EFI/BOOT/BOOTX64.EFI" \
+	"$mkiso_grub_efi_cmd" -d "$mkiso_efi" -O x86_64-efi \
+		-o "$mkiso_iso/EFI/BOOT/BOOTX64.EFI" \
 		-p /boot/grub $mkiso_grub_mods ||
 		sps_die "$SPS_EX_BUILD" "grub-mkimage (x86_64-efi) failed"
 	truncate -s 8M "$mkiso_iso/boot/grub/efi.img"
@@ -2020,8 +2050,11 @@ if [ -f "$mkiso_iso/boot/grub/efi.img" ]; then
 		-b boot/grub/bios.img -no-emul-boot -boot-load-size 4 \
 		-boot-info-table --grub2-boot-info \
 		--grub2-mbr "$mkiso_pc/boot_hybrid.img" \
-		-eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot \
-		-isohybrid-gpt-basdat \
+		-append_partition 2 0xef "$mkiso_iso/boot/grub/efi.img" \
+		-eltorito-alt-boot \
+		-e --interval:appended_partition_2:all:: \
+		-no-emul-boot \
+		--mbr-force-bootable \
 		"$mkiso_iso" >"$mkiso_xorriso_log" 2>&1 ||
 		sps_die "$SPS_EX_BUILD" "xorriso failed (see $mkiso_xorriso_log)"
 else
@@ -2030,10 +2063,22 @@ else
 		-b boot/grub/bios.img -no-emul-boot -boot-load-size 4 \
 		-boot-info-table --grub2-boot-info \
 		--grub2-mbr "$mkiso_pc/boot_hybrid.img" \
+		--mbr-force-bootable \
 		"$mkiso_iso" >"$mkiso_xorriso_log" 2>&1 ||
 		sps_die "$SPS_EX_BUILD" "xorriso failed (see $mkiso_xorriso_log)"
 fi
 
+if [ -f "$mkiso_iso/boot/grub/efi.img" ] &&
+	command -v fdisk >/dev/null 2>&1
+then
+	if ! fdisk -l "$mkiso_output" 2>/dev/null |
+		grep -qE '(^|[[:space:]])(ef|EFI)'
+	then
+		sps_die "$SPS_EX_BUILD" \
+			"generated ISO has no USB-visible EFI partition"
+	fi
+fi
+
 printf '%s\n' "$mkiso_output"
 ls -lh "$mkiso_output" >&2
 exit 0
diff --git a/tests/test_mkiso.sh b/tests/test_mkiso.sh
index 2c97960..56a47dc 100755
--- a/tests/test_mkiso.sh
+++ b/tests/test_mkiso.sh
@@ -87,6 +87,17 @@ grep -qx 'HOME_URL="https://splux.robertflexx.dev"' "$layout/etc/os-release" ||
 	fail 'os-release HOME_URL is not the Splux site'
 grep -q mkiso_stamp_distro_branding "$mkiso" ||
 	fail 'mkiso must overlay Distro PNG branding from extra'
+grep -q -- '-append_partition 2 0xef' "$mkiso" ||
+	fail 'mkiso must append the EFI image as partition 2 type 0xef'
+grep -q -- '--interval:appended_partition_2:all::' "$mkiso" ||
+	fail 'mkiso must boot EFI from the appended partition'
+grep -q -- '--mbr-force-bootable' "$mkiso" ||
+	fail 'mkiso must mark the hybrid MBR bootable'
+if grep -q -- '-isohybrid-gpt-basdat' "$mkiso"; then
+	fail 'mkiso must not combine GRUB2 MBR with ISOLINUX hybrid GPT machinery'
+fi
+grep -q 'generated ISO has no USB-visible EFI partition' "$mkiso" ||
+	fail 'mkiso must reject an EFI ISO without a visible EFI partition'
 
 # Host /bin/sh is bash. Getty runs /bin/sh. A bash symlink without libtinfo
 # is the Plasma ISO boot loop.
@@ -138,6 +149,10 @@ then
 fi
 grep -q FONTCONFIG_PATH "$layout/etc/sps/live-plasma" ||
 	fail 'live-plasma must set FONTCONFIG_PATH'
+grep -q '/usr/share/fonts/X11/dejavu/DejaVu' "$mkiso" ||
+	fail 'plasma ISO must support X11-style DejaVu font installation paths'
+grep -q '/usr/share/fonts/X11/liberation-fonts/Liberation' "$mkiso" ||
+	fail 'plasma ISO must support X11-style Liberation font installation paths'
 grep -q virtio_gpu "$layout/etc/sps/live-rc" ||
 	fail 'live-rc must load virtio_gpu for QEMU/virt-manager'
 grep -q cirrus_qemu "$layout/etc/sps/live-rc" ||
@@ -196,6 +211,12 @@ grep -q plasma_waitforname "$project_dir/lib/mkiso/plasma-bins" ||
 grep -q -- '-comp zstd' "$mkiso" || fail 'mkiso must write a zstd squashfs'
 grep -q -- '-Xcompression-level 3' "$mkiso" ||
 	fail 'mkiso squashfs compression should stay fast to build'
+grep -q 'xz squashfs failed, trying gzip' "$mkiso" ||
+	fail 'mkiso must support gzip-only mksquashfs builds'
+grep -q '\-d "$mkiso_pc" -O i386-pc' "$mkiso" ||
+	fail 'mkiso must point grub-mkimage at the selected BIOS modules'
+grep -q '\-d "$mkiso_efi" -O x86_64-efi' "$mkiso" ||
+	fail 'mkiso must point grub-mkimage at the selected EFI modules'
 grep -q 'Qt/KF shared libraries' "$mkiso" ||
 	fail 'plasma ISO must copy Qt/KF libraries without per-file ldd'
 grep -q 'found live image' "$project_dir/lib/mkiso/initrd-init" ||