[Concept,13/16] scripts: ubuntu-iso-to-uboot: Inherit cmdline from the ISO

Message ID 20260421183511.2044469-14-sjg@u-boot.org
State New
Headers
Series efi-x86: Boot Ubuntu live ISOs via U-Boot + BLS, end to end |

Commit Message

Simon Glass April 21, 2026, 6:34 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

The rewritten ISO should behave the same as the original Ubuntu live
image under any boot loader, so the kernel command line it advertises
via /loader/entry.conf should match what the source ISO's own grub entry
would pass to /casper/vmlinuz. Hard-coding a fresh cmdline changes the
user-visible behaviour (e.g. casper flags, plymouth splash) and risks
drifting from the upstream ISO as Ubuntu revises it between releases.

Parse /boot/grub/grub.cfg out of the input ISO and pick up the arguments
after the first 'linux /casper/vmlinuz' line, falling through to that
value when the caller does not override with -a. Log the resulting
cmdline so the user can see what the rewritten ISO will boot with.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 scripts/ubuntu-iso-to-uboot.py | 39 ++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)
  

Patch

diff --git a/scripts/ubuntu-iso-to-uboot.py b/scripts/ubuntu-iso-to-uboot.py
index 7fc20327f02..d9430cfd006 100755
--- a/scripts/ubuntu-iso-to-uboot.py
+++ b/scripts/ubuntu-iso-to-uboot.py
@@ -76,7 +76,6 @@  sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'tools'))
 from u_boot_pylib import command
 from u_boot_pylib import tout
 
-DEFAULT_CMDLINE = 'console=ttyS0,115200 console=tty0 --- quiet'
 REQUIRED_TOOLS = ('xorriso', 'mcopy', 'mmd', 'mkfs.vfat')
 MIB = 1024 * 1024
 
@@ -90,6 +89,33 @@  def check_tools() -> None:
         )
 
 
+def parse_grub_cmdline(iso: Path) -> str:
+    """Return the kernel cmdline from the ISO's default grub entry.
+
+    Parses the first `linux /casper/vmlinuz ...` line in /boot/grub/grub.cfg
+    and strips the kernel path, so the caller can pass the remaining tokens
+    to the kernel (e.g. '--- quiet splash' on Ubuntu 24.04.1).
+    """
+    with tempfile.TemporaryDirectory(prefix='iso2uboot.grub.') as td:
+        dst = Path(td) / 'grub.cfg'
+        command.run(
+            'xorriso', '-osirrox', 'on', '-indev', str(iso),
+            '-extract', '/boot/grub/grub.cfg', str(dst),
+        )
+        cfg = dst.read_text(errors='replace')
+
+    m = re.search(
+        r'^\s*linux\s+\S*casper/vmlinuz\S*\s*(.*)$',
+        cfg, re.MULTILINE,
+    )
+    if not m:
+        tout.fatal(
+            'could not find a casper linux entry in /boot/grub/grub.cfg'
+        )
+    # Collapse any run of whitespace to a single space
+    return ' '.join(m.group(1).split())
+
+
 def parse_boot_report(iso: Path) -> tuple[str, str]:
     """Return (volume_label, esp_partition_guid) from xorriso's mkisofs report.
 
@@ -181,8 +207,9 @@  def main() -> None:
                    help='kernel path inside the input ISO')
     p.add_argument('-i', '--initrd', default='casper/initrd',
                    help='initrd path inside the input ISO')
-    p.add_argument('-a', '--cmdline', default=DEFAULT_CMDLINE,
-                   help='kernel command line written into loader/entry.conf')
+    p.add_argument('-a', '--cmdline', default=None,
+                   help='kernel command line written into loader/entry.conf '
+                        '(default: inherit from the ISO\'s grub.cfg)')
     p.add_argument('-t', '--title', default=None,
                    help='BLS entry title (default: derived from volume label)')
     p.add_argument('-s', '--esp-size', type=int, default=None,
@@ -199,8 +226,12 @@  def main() -> None:
     # Extract the volume label and ESP partition GUID from xorriso's report
     vol_id, esp_guid = parse_boot_report(args.iso)
     title = args.title or f'U-Boot BLS boot ({vol_id})'
+    cmdline = args.cmdline
+    if cmdline is None:
+        cmdline = parse_grub_cmdline(args.iso)
     print(f'   Volume label: {vol_id}')
     print(f'   ESP GUID:     {esp_guid}')
+    print(f'   Cmdline:      {cmdline}')
 
     with tempfile.TemporaryDirectory(prefix='iso2uboot.') as td:
         work = Path(td)
@@ -215,7 +246,7 @@  def main() -> None:
             f'title {title}\n'
             f'linux /{args.kernel}\n'
             f'initrd /{args.initrd}\n'
-            f'options {args.cmdline}\n'
+            f'options {cmdline}\n'
         )
 
         print(f'=> Repacking to {args.out}')