Skip to content

initrd: boot dd-written hybrid ISOs in mount-usb and usb-autoboot - #2186

Merged
tlaurion merged 19 commits into
linuxboot:masterfrom
tlaurion:fix-2008-dd-hybrid-iso-boot
Aug 19, 2026
Merged

initrd: boot dd-written hybrid ISOs in mount-usb and usb-autoboot#2186
tlaurion merged 19 commits into
linuxboot:masterfrom
tlaurion:fix-2008-dd-hybrid-iso-boot

Conversation

@tlaurion

@tlaurion tlaurion commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #2008: a Kicksecure hybrid ISO dd'd to a USB drive
now boots in both the manual USB boot menu and Basic-mode auto-boot.

The problem

A dd-written Kicksecure ISO is a GPT hybrid whose bootable iso9660
filesystem lives on the whole raw device, not on a partition. The boot
path relied on blkid TYPE="iso9660" to detect such drives, which does
not reliably report the type on these oversized/GPT-hybrid sticks, so no
bootable filesystem was found and boot failed.

The fix

  • initrd/etc/functions.sh: add first_mountable_usb_disk() (a
    non-destructive read-only mount probe that finds a bootable filesystem
    on a whole device) and is_whole_disk(); host _get_blkid_fstype()
    (moved from kexec-iso-init.sh).
  • initrd/bin/mount-usb.sh: add a --whole-disk flag that probes whole USB
    disks with an actual read-only mount instead of blkid; the default
    remains partitions-only.
  • initrd/bin/media-scan.sh: the USB boot path opts in via
    mount_usb --whole-disk, and retries once with the default
    partitions-only mount when a whole disk mounts but yields no boot
    entries.
  • initrd/etc/gui_functions.sh: mount_usb() forwards its arguments to
    mount-usb.sh and maps exit 5 (picker abort) to exit 1.
  • initrd/bin/usb-autoboot.sh: enumerate whole disks before partitions so
    a dd-written hybrid ISO auto-boots in Basic mode.
  • config/busybox.config: enable CONFIG_FEATURE_BLKID_TYPE=y so blkid
    reports the filesystem TYPE used by kexec-iso-init.sh.
  • boards/qemu-coreboot-fbwhiptail-tpm2-basic-usb-autoboot: new QEMU test
    board (Basic mode + USB autoboot) for this path.
  • tests/iso-test/: move the iso-boot test suite out of initrd/ so it no
    longer ships in the initrd image.
  • Docs (boot-process.md, busybox_perks.md, iso_boot.md, logging.md).

Testing

  • ISO boot test suite: 26 passed / 0 failed / 0 skipped.
  • QEMU: a dd'd Kicksecure ISO mounts the whole device and reaches the
    boot menu in manual mode, and auto-boots in Basic mode; Tails, Debian
    live, and partitioned images (NixOS) still boot through the existing
    paths.

Boot confirmation and one-time runtime edit

  • The dd'ed-USB boot path now reuses the ISO boot confirmation codepath: the full kexec command line is displayed and confirmed before boot (skip_confirm removed from the bootable-USB path in media-scan.sh).
  • Added an Edit [e] option to that confirmation: edit the boot entry in vi as a one-time runtime change (nothing persisted to /boot or config.user), then re-show the final kexec command line for reconfirmation.
  • make default (d) is suppressed after an edit, since a persisted edited entry would diverge from the on-media boot config and the signed /boot state.
  • Added unit tests for edited-entry parse, validation, and the edited-append round-trip.

Copilot AI lite review requested due to automatic review settings August 15, 2026 14:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@tlaurion
tlaurion marked this pull request as draft August 15, 2026 14:11
@tlaurion tlaurion changed the title initrd/mount-usb: detect dd-written hybrid ISO and boot whole disk initrd/mount-usb: mount whole device when it is an iso9660 hybrid ISO Aug 15, 2026
@tlaurion
tlaurion force-pushed the fix-2008-dd-hybrid-iso-boot branch 3 times, most recently from 58a3ab5 to 92d099d Compare August 15, 2026 20:33
@tlaurion tlaurion changed the title initrd/mount-usb: mount whole device when it is an iso9660 hybrid ISO initrd: detect dd-written hybrid ISO on whole device Aug 15, 2026
@tlaurion

Copy link
Copy Markdown
Collaborator Author

Verified working without regression under qemu on thumb drives with multiple isos dropped on it and directly booting on iso from qemu: both work.

@tlaurion
tlaurion marked this pull request as ready for review August 15, 2026 20:37
@tlaurion

Copy link
Copy Markdown
Collaborator Author

verified dd'ed and iso boot on debian-13 xfce too.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 7 changed files in this pull request and generated no new comments.

@tlaurion tlaurion changed the title initrd: detect dd-written hybrid ISO on whole device initrd: boot dd-written hybrid ISOs in mount-usb and usb-autoboot Aug 16, 2026
@tlaurion

Copy link
Copy Markdown
Collaborator Author

Was testing Kicksecure-LXQt-18.1.4.2.Intel_AMD64.iso, will test Kicksecure-LXQt-18.2.1.9.Intel_AMD64.iso

- mount-usb.sh: probe whole USB disks with a read-only mount
  (first_mountable_usb_disk) instead of blkid TYPE=iso9660; --whole-disk
  opts in, the default remains partitions-only
- media-scan.sh: retry once with the partitions-only mount when a whole
  disk mounts but yields no boot entries
- gui_functions.sh: mount_usb() forwards its arguments to mount-usb.sh
  and maps exit 5 (picker abort) to exit 1
- functions.sh: add first_mountable_usb_disk and is_whole_disk; host
  _get_blkid_fstype for kexec-iso-init.sh

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Enable CONFIG_FEATURE_BLKID_TYPE so BusyBox blkid reports the filesystem
TYPE, which kexec-iso-init.sh's _get_blkid_fstype (shared from
initrd/etc/functions.sh) relies on.

Part of the issue linuxboot#2008 hybrid ISO boot fix.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Move initrd/tests/iso-test/ to tests/iso-test/ so the test script no longer ships inside the initrd image.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Update boot-process, busybox_perks, iso_boot and logging docs for the kernel mount-test mechanism and the mount-usb.sh exit 5 contract.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…B autoboot test board

- Add qemu-coreboot-fbwhiptail-tpm2-basic-usb-autoboot board with
  CONFIG_BASIC_USB_AUTOBOOT=y to test automatic boot of bootable USB
  media (dd-written hybrid ISO) under QEMU
- Enable CONFIG_DEBUG_OUTPUT and TPM2 pcap capture for test diagnostics

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- Print the source git commit (GIT_HASH and HEADS_GIT_VERSION) in the
  build start banner so non-reproducible builds are attributable to the
  commit that produced them
- Part of issue linuxboot#2008 follow-up

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Document that the last console= parameter becomes the primary console
for /dev/console, and how that routes STATUS/NOTE (primary only),
DEBUG/WARN/DIE (kmsg broadcast to all consoles), kernel printk (all
consoles), and whiptail dialogs (framebuffer only).

Part of issue linuxboot#2008 follow-up.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
@tlaurion
tlaurion force-pushed the fix-2008-dd-hybrid-iso-boot branch from db00961 to aacb22a Compare August 18, 2026 14:56
@tlaurion

tlaurion commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator Author

Tested with oversized raw image vs iso size (thumb drives should always be bigger then iso...) and now works as expected.

…time edit

- media-scan.sh: drop skip_confirm (-s) from bootable-USB kexec-select-boot invocations so the dd'ed path shows the full kexec command line confirmation, as the ISO path already does

- kexec-select-boot.sh: add Edit [e] to the boot confirmation; edit the boot entry in vi (one-time runtime change, nothing persisted), re-parse and validate the entry, then re-show the final kexec command line for reconfirmation

- kexec-select-boot.sh: suppress make default (d) after an edit since the entry no longer matches the on-media boot configuration

- tests/iso-test/iso-boot-test.sh: add unit tests for edited entry parse, validation, and cmdline round-trip

Signed-off-by: Thierry Laurion <insurgo@riseup.net>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 16 changed files in this pull request and generated no new comments.

Suppressed comments (2)

tests/iso-test/README.md:34

  • This entry lists a Debian 13 DVD date of 2026-12-15, which is in the future relative to the current date. If this is meant to be the download/build date used for testing, it should reflect an actual past date (or be marked as TBD/unknown).
    initrd/etc/gui_functions.sh:31
  • The abort/return handling here is broken because the failure branch runs in a subshell (...): USB_FAILED=1 won’t persist to the parent shell, and exit 1 exits only the subshell. This can leave USB_FAILED unset and make [ $USB_FAILED -ne 0 ] error, and it won’t reliably abort on picker exit code 5 as intended.

Capture the exit status in the parent shell and set USB_FAILED deterministically (and exit 1 from the parent) instead of using a subshell.

	# Forward "$@" (e.g. --whole-disk) to mount-usb.sh. It exits 5 when
	# the user aborts the USB disk picker; map that to exit 1 (abort).
	mount-usb.sh "$@" && USB_FAILED=0 || ([ $? -eq 5 ] && exit 1 || USB_FAILED=1)
	if [ $USB_FAILED -ne 0 ]; then
		whiptail_error --title 'USB Drive Missing' \
			--msgbox "Insert your USB drive and press Enter to continue." 0 80
		# mount-usb.sh exits 5 when the user aborts the USB disk picker; map that to exit 1 (abort).
		mount-usb.sh "$@" && USB_FAILED=0 || ([ $? -eq 5 ] && exit 1 || USB_FAILED=1)
		if [ $USB_FAILED -ne 0 ]; then

- explain at each bootable-USB kexec-select-boot call site that -s (skip_confirm) is intentionally omitted so the dd'ed path shows the same boot confirmation as the ISO path

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
…cknowledge vi guidance

- restore the confirmation-dialog comment: full kernel/initrd/params display, Cancel/Esc returns to the menu, cmdline combines parsed params and global ADD

- replace the vi NOTE (3s auto-sleep) with an INPUT acknowledgment so the user reads the beginner vi instructions and presses Enter before the editor opens

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- The mount-usb.sh failure branch ran in a subshell "(...)", so "USB_FAILED=1" never persisted to the parent shell and "exit 1" exited only the subshell.
- "[ $USB_FAILED -ne 0 ]" then expanded to "[ -ne 0 ]" (test error), making the USB mount retry dialog and the exit-5 picker abort dead code.
- Replace the subshell with an if/else that captures mount-usb.sh's exit status in the current shell, maps exit 5 to "return 1" (abort), and sets USB_FAILED=1 otherwise.
- Use "return 1" instead of "exit 1" so media-scan.sh's "mount_usb --whole-disk || DIE" guard still runs.
- Regression introduced in f02ab49 (PR linuxboot#1908), later touched by d904dc5 (PR linuxboot#2186).

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- The "Debian 13 DVD" row in the "ISOs that require raw-device (dd) boot" table carried "2026-12-15", which is in the future relative to the current date (2026-08-19).
- The date column records the ISO snapshot/build date; openSUSE Tumbleweed DVD lists "2026-06-05" (a real past date), so a future date is not yet known.
- Mark the entry "(date TBD)" instead of leaving a not-yet-known date.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- mount_usb() now returns 1 when the user aborts the USB disk picker
  (mount-usb.sh exit 5).  Under set -e -o pipefail, unguarded callers in
  flash-gui.sh and the GPG flows would terminate silently on abort.
- flash-gui.sh: guard with 'mount_usb || true'; the following
  'grep -q /media /proc/mounts' already handles the no-media case.
- gpg_functions.sh gpg_post_gen_mgmt: guard with 'mount_usb || return 1'
  to abort the copy-to-USB flow (no following /media guard).
- gpg_functions.sh gpg_add_key_reflash and gpg_add_key_to_standalone_rom:
  guard with 'mount_usb || true'; both are followed by a /media mount check.
- Declare rc as local in both mount_usb() if/else blocks.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- mount-usb.sh:196 comment and doc/logging.md Exit codes section said
  mount_usb() maps the picker abort 'to exit 1', but the function does
  'return 1' (a function return, not a process exit).  Align both with
  'return 1'.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- The 'Boot entry modified at runtime' message reports a successful,
  desired outcome (the user edited the entry), not a likely/actionable
  problem, so WARN is the wrong level per doc/logging.md.
- Use NOTE: user guidance about a consequence (the change is not saved)
  that needs attention, and avoid the 1s WARN sleep on a normal path.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- Restructure the dd-required ISO table from 2 columns (ISO, Reason) to
  3 columns (ISO, Date, Reason), one row per ISO with no continuation rows.
- Unify the dates: openSUSE Tumbleweed DVD keeps 2026-06-05, Debian 13 DVD
  changes from '(date TBD)' to 2026-06-05, and NixOS gains 2026-06-05.
- Reflow each Reason into a single cell, preserving the wording.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Signed-off-by: Thierry Laurion <insurgo@riseup.net>
- @makkiato83 offered to be a physical x230 tester.

- Ref: linuxboot#2008 (comment)

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kicksecure ISO live amnesic (USER Session) boot fails on novacustom-v540tu; works on x230 and nv4x_adl "kicksecure iso doesn't boot under Heads

2 participants