diff --git a/doc/usage/os/ubuntu-live.rst b/doc/usage/os/ubuntu-live.rst
index bd4e85e4c8a..fad476b4832 100644
--- a/doc/usage/os/ubuntu-live.rst
+++ b/doc/usage/os/ubuntu-live.rst
@@ -3,17 +3,16 @@
 Booting Ubuntu live ISOs via U-Boot
 ===================================
 
-U-Boot can replace GRUB as the bootloader on an Ubuntu live ISO. The
-stock ISO has an appended EFI system partition (ESP) containing shim,
-GRUB and their configuration. ``scripts/ubuntu-iso-to-uboot.py`` rewrites
-that ESP with a U-Boot EFI application, a :doc:`Boot Loader Specification
-Type #1 </usage/bls>` entry and the casper kernel and initrd, leaving the
-rest of the ISO untouched so casper still finds its squashfs by disc
-label at runtime.
-
-The flow only touches the appended partition. BIOS El Torito, the
-grub2 MBR, the GPT layout and the ISO 9660 tree are preserved verbatim
-by xorriso's ``-boot_image any replay``
+U-Boot can replace GRUB as the bootloader on an Ubuntu live ISO.
+``scripts/ubuntu-iso-to-uboot.py`` rewrites the ISO so the appended EFI
+system partition holds a U-Boot EFI application and the ISO 9660 tree
+carries a :doc:`Boot Loader Specification Type #1 </usage/bls>` entry
+pointing at the casper kernel and initrd that Ubuntu already places on
+the disc.
+
+All other boot records (BIOS El Torito, grub2 MBR, GPT layout) are
+preserved verbatim by xorriso's ``-boot_image any replay``, and casper
+still finds its squashfs by disc label at runtime.
 
 Host prerequisites
 ------------------
@@ -26,17 +25,17 @@ Building the U-Boot EFI application
 -----------------------------------
 
 The ``efi-x86_app64`` target enables ``CONFIG_BOOTMETH_BLS=y``,
-``CONFIG_FS_ISOFS=y`` and ``CONFIG_JOLIET=y`` by default, so no
-Kconfig tweaks are required. Build with::
+``CONFIG_FS_ISOFS=y`` and ``CONFIG_JOLIET=y`` by default, so no Kconfig
+tweaks are required. Build with::
 
     make O=/tmp/b/efi-x86_app64 efi-x86_app64_defconfig
     make O=/tmp/b/efi-x86_app64 -j$(nproc)
 
-The output is ``/tmp/b/efi-x86_app64/u-boot-app.efi``, a PE32+ x86_64 EFI
-application.
+The output is ``/tmp/b/efi-x86_app64/u-boot-app.efi``, a PE32+ x86_64
+EFI application.
 
 If ``rustc`` is not installed, also disable the rust example build
-before ``make``::
+before the main ``make``::
 
     scripts/config --file /tmp/b/efi-x86_app64/.config \\
         -d RUST_EXAMPLES -d EXAMPLES
@@ -58,13 +57,14 @@ The script:
 
 1. Reads the input ISO's boot record with ``xorriso -report_el_torito``
    to pick up the volume label and the EFI system partition GUID.
-2. Extracts ``/casper/vmlinuz`` and ``/casper/initrd`` via ``xorriso -osirrox``
-3. Builds a fresh FAT32 ESP (auto-sized to fit) containing
-   ``/EFI/BOOT/BOOTX64.EFI`` (the U-Boot app), ``/casper/vmlinuz``,
-   ``/casper/initrd`` and ``/loader/entry.conf``
-4. Writes a new ISO with ``xorriso -indev ... -outdev ... -boot_image
-   any replay -append_partition 2 ...``, replacing the original ESP
-   while preserving all other boot metadata.
+2. Builds a small FAT ESP (4 MiB by default) containing just
+   ``/EFI/BOOT/BOOTX64.EFI`` -- the U-Boot EFI application.
+3. Writes a new ISO with
+   ``xorriso -indev ... -outdev ... -boot_image any replay
+   -append_partition 2 ... -map entry.conf /loader/entry.conf``,
+   which replaces the original ESP and adds ``/loader/entry.conf`` to
+   the ISO 9660 tree. The kernel and initrd stay in ``/casper/`` on the
+   ISO 9660 tree; U-Boot reads them directly via its isofs driver.
 
 Relevant options:
 
@@ -72,14 +72,15 @@ Relevant options:
 * ``-o PATH`` -- the output ISO (required).
 * ``-a ARGS`` -- override the kernel command line written to
   ``loader/entry.conf``. The default is
-  ``console=ttyS0,115200 console=tty0 --- quiet``, which logs the kernel output
-  serial and video. Duplicate the ``console=`` arguments after ``---`` as well
-  if you want casper and the running system logged to serial too.
+  ``console=ttyS0,115200 console=tty0 --- quiet``, which logs the
+  kernel to serial and video. Duplicate the ``console=`` arguments
+  after ``---`` as well if you want casper and the running system
+  logged to serial too.
 * ``-k PATH`` / ``-i PATH`` -- override the kernel and initrd paths
   inside the ISO if a distribution uses something other than
   ``casper/vmlinuz`` and ``casper/initrd``.
-* ``-s MiB`` -- force an ESP size; the default auto-sizes to fit the
-  kernel, initrd and U-Boot app with 16 MiB of headroom.
+* ``-s MiB`` -- force an ESP size; the default is 4 MiB, enough for the
+  U-Boot binary.
 * ``-t TITLE`` -- override the BLS entry title.
 
 Testing under QEMU + OVMF
@@ -95,60 +96,23 @@ Testing under QEMU + OVMF
 
 The expected boot trace on the serial console is roughly::
 
-    BdsDxe: loading Boot0001 "UEFI Misc Device" from PciRoot(0x0)/Pci(0x3,0x0)
-    BdsDxe: starting Boot0001 "UEFI Misc Device" from PciRoot(0x0)/Pci(0x3,0x0)
-    Laceboot EFI App (using allocated RAM address 6beef000) starting
-
-
     U-Boot Concept 2026.02
-
-    CPU: x86_64, vendor <invalid cpu vendor>, device 0h
-    Model: EFI x86 Application
-    DRAM:  256 MiB
-    Core:  22 devices, 13 uclasses, devicetree: separate
-    EFI:   disks 2, partitions 3
-    Loading Environment from FAT... Unable to use efi 0:0...
-    Video: 1280x800x32 @ 0
-    Hit any key to stop autoboot:  2
-    Hit any key to stop autoboot: 1
-    Hit any key to stop autoboot: 0
-    Scanning for bootflows in all bootdevs
-    Seq  Method       State   Uclass    Part  Ent  E  Name                      Filename
-    ---  -----------  ------  --------  ----  ---  -  ------------------------  ----------------
-    Hunting with: fs
+    ...
     Scanning bootdev 'efi_media_0.bootdev':
-      0  bls          ready   pci          2    0     efi_media_0.bootdev.part_ /loader/entry.conf
-    ** Booting bootflow 'efi_media_0.bootdev.part_2' with bls
+      0  bls    ready   pci  1  0  efi_media_0.bootdev.part_ /loader/entry.conf
+    ** Booting bootflow 'efi_media_0.bootdev.part_1' with bls
     Retrieving file: /casper/vmlinuz
     Retrieving file: /casper/initrd
-    Valid Boot Flag
-    Magic signature found
-    Linux kernel version 6.8.0-41-generic (buildd@lcy02-amd64-100) #41-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug  2 20:41:06 UTC 2024
-    Building boot_params at 90000
-    Loading bzImage at address 100000 (14926336 bytes)
-    Initial RAM disk at linear address 8000000, size 47a003e (75104318 bytes)
-    Kernel command line: "console=ttyS0,115200 console=tty0 --- console=ttyS0,115200 quiet"
-
+    Linux kernel version 6.8.0-41-generic ... Ubuntu
     Starting kernel ...
 
-    ...
-
-
-Why the kernel and initrd live on the ESP
------------------------------------------
-
-BLS paths are resolved against the partition holding ``loader/entry.conf``
-
-OVMF only exposes the EFI system partition as an ``EFI_BLOCK_IO`` protocol
-handle on CD media, so U-Boot's ``efi_media`` bootdev cannot see the ISO 9660
-partition directly and would fail to resolve ``/casper/vmlinuz`` if the entry
-were placed there. Copying the kernel and initrd onto the ESP sidesteps this;
-the ISO 9660 side remains bootable in its own right, and casper finds its
-squashfs on the original media at runtime.
+The bootflow appears on ``part_1`` -- the ISO 9660 partition -- because
+``entry.conf`` lives in the ISO 9660 tree and U-Boot reads kernel and
+initrd from the same partition via isofs.
 
 See also
 --------
 
-* :doc:`/usage/bls` — the U-Boot Boot Loader Specification bootmeth.
+* :doc:`/usage/bls` -- the U-Boot Boot Loader Specification bootmeth.
 * `Boot Loader Specification
   <https://uapi-group.org/specifications/specs/boot_loader_specification/>`_.
diff --git a/scripts/ubuntu-iso-to-uboot.py b/scripts/ubuntu-iso-to-uboot.py
index ec32ac7b0dd..ec2e3cdd2c3 100755
--- a/scripts/ubuntu-iso-to-uboot.py
+++ b/scripts/ubuntu-iso-to-uboot.py
@@ -8,17 +8,18 @@ the EFI system partition. Each entry names a kernel, initrd and command
 line; U-Boot's BOOTMETH_BLS scans the ESP and presents them in its boot
 menu, replacing the shim/grub chain that Ubuntu ships by default.
 
-The ISO's appended EFI System Partition is replaced with a fresh ESP
-containing:
+Two things change in the rewritten ISO:
 
-    /EFI/BOOT/BOOTX64.EFI   U-Boot EFI app (built with CONFIG_BOOTMETH_BLS=y)
-    /casper/vmlinuz         copied from the input ISO
-    /casper/initrd          copied from the input ISO
-    /loader/entry.conf      BLS Type #1 entry pointing at the above
+    EFI system partition  /EFI/BOOT/BOOTX64.EFI  replaced with the U-Boot
+                                                 EFI app
+    ISO 9660 tree         /loader/entry.conf     added, pointing at the
+                                                 existing /casper/vmlinuz
+                                                 and /casper/initrd
 
-The ISO9660 tree is preserved unchanged, so casper still finds its squashfs
-by disc label at runtime. All other boot records (BIOS El Torito, grub2 MBR,
-GPT layout) are preserved by xorriso's -boot_image any replay.
+The kernel and initrd stay where Ubuntu put them. U-Boot reads them off
+the ISO 9660 partition directly via its isofs driver. All other boot
+records (BIOS El Torito, grub2 MBR, GPT layout) are preserved by
+xorriso's -boot_image any replay.
 
 Quick start (run from the root of the U-Boot tree)::
 
@@ -114,65 +115,32 @@ def parse_boot_report(iso: Path) -> tuple[str, str]:
     return m_vol.group(1), m_esp.group(1)
 
 
-def extract_from_iso(iso: Path, src: str, dst: Path) -> None:
-    """Pull a single file out of the ISO9660 tree via xorriso -osirrox"""
-    dst.parent.mkdir(parents=True, exist_ok=True)
-    command.run(
-        'xorriso', '-osirrox', 'on', '-indev', str(iso),
-        '-extract', f'/{src.lstrip("/")}', str(dst),
-    )
-
-
-def build_esp(
-    esp_path: Path,
-    size_mib: int,
-    uboot_efi: Path,
-    vmlinuz: Path,
-    initrd: Path,
-    entry_conf: str,
-) -> None:
-    """Create a fresh FAT32 ESP at esp_path populated with BLS + kernel.
+def build_esp(esp_path: Path, size_mib: int, uboot_efi: Path) -> None:
+    """Create a fresh FAT ESP containing only the U-Boot EFI application.
 
     Args:
         esp_path (Path): Output file to hold the new ESP image
         size_mib (int): Size of the ESP in mebibytes
         uboot_efi (Path): U-Boot EFI app to install as /EFI/BOOT/BOOTX64.EFI
-        vmlinuz (Path): Kernel image to install under /casper/vmlinuz
-        initrd (Path): Initrd image to install under /casper/initrd
-        entry_conf (str): Contents for /loader/entry.conf (BLS Type #1)
     """
     with esp_path.open('wb') as f:
         f.truncate(size_mib * MIB)
-    command.output('mkfs.vfat', '-F32', '-n', 'ESP', str(esp_path))
-    command.run('mmd', '-i', str(esp_path),
-                '::EFI', '::EFI/BOOT', '::loader', '::casper')
-
-    def put(src: Path, dst: str) -> None:
-        command.run('mcopy', '-i', str(esp_path), str(src), f'::{dst}')
-
-    put(uboot_efi, 'EFI/BOOT/BOOTX64.EFI')
-    put(vmlinuz, 'casper/vmlinuz')
-    put(initrd, 'casper/initrd')
-
-    entry = Path(esp_path.parent) / 'entry.conf'
-    entry.write_text(entry_conf)
-    put(entry, 'loader/entry.conf')
-
-
-def auto_esp_size(files: list[Path], headroom_mib: int = 16) -> int:
-    """Sum file sizes + headroom, round up to MiB, floor at 64 MiB (FAT32)"""
-    total = sum(f.stat().st_size for f in files) + headroom_mib * MIB
-    mib = (total + MIB - 1) // MIB
-    return max(mib, 64)
+    # FAT12 is enough for the small ESP we emit (just a U-Boot binary).
+    command.output('mkfs.vfat', '-F12', '-n', 'ESP', str(esp_path))
+    command.run('mmd', '-i', str(esp_path), '::EFI', '::EFI/BOOT')
+    command.run('mcopy', '-i', str(esp_path), str(uboot_efi),
+                '::EFI/BOOT/BOOTX64.EFI')
 
 
 def repack_iso(
     in_iso: Path, out_iso: Path, esp_img: Path, esp_guid: str,
+    entry_conf: Path,
 ) -> None:
-    """Stream the input ISO to a new ISO, replacing partition 2's data.
+    """Stream the input ISO to a new ISO with the ESP and BLS entry replaced.
 
     -boot_image any replay preserves every other boot record (BIOS El Torito,
-    grub2 MBR, GPT layout); only the bytes behind partition 2 are rewritten
+    grub2 MBR, GPT layout); only the bytes behind partition 2 are rewritten,
+    plus /loader/entry.conf is added to the ISO 9660 tree.
     """
     command.run(
         'xorriso',
@@ -180,6 +148,7 @@ def repack_iso(
         '-outdev', str(out_iso),
         '-boot_image', 'any', 'replay',
         '-append_partition', '2', esp_guid, str(esp_img),
+        '-map', str(entry_conf), '/loader/entry.conf',
         '-commit',
     )
 
@@ -202,7 +171,7 @@ def main() -> None:
     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,
-                   help='ESP size in MiB (default: auto-size to fit)')
+                   help='ESP size in MiB (default: 4 MiB)')
     args = p.parse_args()
 
     if not args.iso.is_file():
@@ -220,27 +189,22 @@ def main() -> None:
 
     with tempfile.TemporaryDirectory(prefix='iso2uboot.') as td:
         work = Path(td)
-        vmlinuz = work / 'vmlinuz'
-        initrd = work / 'initrd'
 
-        print(f'=> Extracting /{args.kernel} and /{args.initrd}')
-        extract_from_iso(args.iso, args.kernel, vmlinuz)
-        extract_from_iso(args.iso, args.initrd, initrd)
-
-        esp_mib = args.esp_size or auto_esp_size([vmlinuz, initrd, args.uboot])
+        esp_mib = args.esp_size or 4
         print(f'=> Building {esp_mib} MiB ESP')
-
-        entry_conf = f'''\
-title {title}
-linux /casper/vmlinuz
-initrd /casper/initrd
-options {args.cmdline}
-'''
         esp = work / 'esp.img'
-        build_esp(esp, esp_mib, args.uboot, vmlinuz, initrd, entry_conf)
+        build_esp(esp, esp_mib, args.uboot)
+
+        entry = work / 'entry.conf'
+        entry.write_text(
+            f'title {title}\n'
+            f'linux /{args.kernel}\n'
+            f'initrd /{args.initrd}\n'
+            f'options {args.cmdline}\n'
+        )
 
         print(f'=> Repacking to {args.out}')
-        repack_iso(args.iso, args.out, esp, esp_guid)
+        repack_iso(args.iso, args.out, esp, esp_guid, entry)
 
     size_mib = args.out.stat().st_size / MIB
     print(f'=> Done: {args.out} ({size_mib:.1f} MiB)')
