fix: ensure the ISO is actually UEFI-bootable
BOOT=efi only changed the GRUB inside the rootfs squashfs — grub-mkrescue
builds the ISO bootloader from the build host's GRUB, so an ISO assembled
on a host without the x86_64-efi modules + mtools shipped with NO UEFI
boot entry. Booting that ISO on a UEFI machine showed:
"make sure there is a bootable uefi x64 image"
- check-host-deps.sh now verifies the GRUB module dirs it needs for a
hybrid ISO (/usr/lib/grub/x86_64-efi from grub-efi-amd64-bin,
/usr/lib/grub/i386-pc from grub-pc-bin) and mtools, not just
grub-mkrescue.
- build-iso.sh verifies the finished ISO has both EFI and BIOS boot
entries (xorriso El Torito report) and prints the result; BOOT=efi
builds FAIL if the EFI entry is missing.
- GitLab CI build image gains grub-pc-bin, grub-efi-amd64-bin, mtools.
- docs/building.md: hybrid-ISO burning instructions (dd) and the
"bootable uefi x64 image" troubleshooting path.
This commit is contained in:
@@ -31,7 +31,7 @@ validate:
|
|||||||
image: debian:trixie
|
image: debian:trixie
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update -qq
|
- apt-get update -qq
|
||||||
- apt-get install -y -qq debootstrap squashfs-tools grub2-common xorriso cpio curl git make bash gdisk parted rsync dosfstools qemu-utils unzip dpkg openssl sbsigntool
|
- apt-get install -y -qq debootstrap squashfs-tools grub2-common grub-pc-bin grub-efi-amd64-bin mtools xorriso cpio curl git make bash gdisk parted rsync dosfstools qemu-utils unzip dpkg openssl sbsigntool
|
||||||
script:
|
script:
|
||||||
- make ${TARGET:-iso}-${EDITION}
|
- make ${TARGET:-iso}-${EDITION}
|
||||||
artifacts:
|
artifacts:
|
||||||
|
|||||||
@@ -120,3 +120,33 @@ The ISO boots a **live** system (via `live-boot`): the rootfs is compressed to
|
|||||||
a squashfs and mounted on boot, so you can try an edition before installing it
|
a squashfs and mounted on boot, so you can try an edition before installing it
|
||||||
to disk. The same rootfs can be installed with the btrfs layout via
|
to disk. The same rootfs can be installed with the btrfs layout via
|
||||||
`btrfs/init.sh` (the installer is follow-up work — see `docs/architecture.md`).
|
`btrfs/init.sh` (the installer is follow-up work — see `docs/architecture.md`).
|
||||||
|
|
||||||
|
### Burning the ISO
|
||||||
|
|
||||||
|
The ISO is **hybrid** (BIOS + UEFI). Write it to a USB stick with `dd` (or
|
||||||
|
Ventoy), not as a file copy:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dd if=build/artifacts/arcline-server-0.1.0-amd64.iso of=/dev/sdX bs=4M status=progress
|
||||||
|
```
|
||||||
|
|
||||||
|
The build verifies the finished ISO actually contains **both** boot entries and
|
||||||
|
prints `✓ EFI boot entry present` / `✓ BIOS boot entry present`; `BOOT=efi`
|
||||||
|
builds **fail** if the EFI entry is missing.
|
||||||
|
|
||||||
|
### UEFI says "make sure there is a bootable uefi x64 image"
|
||||||
|
|
||||||
|
That firmware error means the ISO had no UEFI boot entry. `grub-mkrescue`
|
||||||
|
builds the ISO bootloader from the **build host's** GRUB, so the host needs the
|
||||||
|
UEFI modules even though the image is `BOOT=efi`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get install -y grub-efi-amd64-bin grub-pc-bin mtools
|
||||||
|
scripts/check-host-deps.sh # should now pass; rebuild the ISO
|
||||||
|
```
|
||||||
|
|
||||||
|
If the entry was present but it still won't boot, enable/disable Secure Boot
|
||||||
|
(our `BOOT=bios` ISOs are unsigned and will be refused by Secure Boot — use
|
||||||
|
`BOOT=efi make iso-server` plus the MOK flow in `docs/secureboot.md` for
|
||||||
|
signed, Secure-Boot-friendly media).
|
||||||
|
|
||||||
|
|||||||
@@ -87,5 +87,32 @@ grub-mkrescue -o "$ARTIFACT" "$ISOFILES" -- \
|
|||||||
-volume-label "ARCLINE_${EDITION^^}" 2>/dev/null || \
|
-volume-label "ARCLINE_${EDITION^^}" 2>/dev/null || \
|
||||||
grub-mkrescue -o "$ARTIFACT" "$ISOFILES"
|
grub-mkrescue -o "$ARTIFACT" "$ISOFILES"
|
||||||
|
|
||||||
|
# ── 5. verify hybrid boot entries ───────────────────────────────────────────
|
||||||
|
# grub-mkrescue builds the ISO bootloader from the HOST's GRUB modules. If the
|
||||||
|
# host lacks the x86_64-efi modules or mtools, the ISO has no UEFI boot entry
|
||||||
|
# and UEFI firmware shows "make sure there is a bootable uefi x64 image".
|
||||||
|
# Check the finished ISO instead of trusting the host.
|
||||||
|
if command -v xorriso >/dev/null 2>&1; then
|
||||||
|
log "verifying ISO boot entries"
|
||||||
|
ET="$(xorriso -indev "$ARTIFACT" -report_el_torito cmd 2>/dev/null || true)"
|
||||||
|
|
||||||
|
HAS_EFI=0
|
||||||
|
echo "$ET" | grep -qiE 'boot_image efi|efi\.img|BOOTX64\.EFI' && HAS_EFI=1
|
||||||
|
if [[ $HAS_EFI -eq 0 ]]; then
|
||||||
|
# fallback: some xorriso versions name it differently — look in the fs
|
||||||
|
xorriso -indev "$ARTIFACT" -find / -name 'efi.img' 2>/dev/null | grep -qi 'efi\.img' && HAS_EFI=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
HAS_BIOS=0
|
||||||
|
echo "$ET" | grep -qiE 'boot_image isolinux|boot_image grub' && HAS_BIOS=1
|
||||||
|
|
||||||
|
[[ $HAS_EFI -eq 1 ]] && log " ✓ EFI boot entry present" || warn " ISO has NO EFI boot entry (UEFI will refuse it)"
|
||||||
|
[[ $HAS_BIOS -eq 1 ]] && log " ✓ BIOS boot entry present" || warn " ISO has NO BIOS boot entry (legacy BIOS will refuse it)"
|
||||||
|
|
||||||
|
if [[ "$BOOT" == "efi" && $HAS_EFI -eq 0 ]]; then
|
||||||
|
die "BOOT=efi but the ISO has no EFI boot entry — install grub-efi-amd64-bin + mtools on the build host (scripts/check-host-deps.sh --install), then rebuild"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
log "ISO artifact: $ARTIFACT"
|
log "ISO artifact: $ARTIFACT"
|
||||||
sha256sum "$ARTIFACT" | tee "$ARTIFACT.sha256"
|
sha256sum "$ARTIFACT" | tee "$ARTIFACT.sha256"
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ NEEDED=(
|
|||||||
"openssl|openssl"
|
"openssl|openssl"
|
||||||
"sbsign|sbsigntool"
|
"sbsign|sbsigntool"
|
||||||
"sbverify|sbsigntool"
|
"sbverify|sbsigntool"
|
||||||
|
# hybrid ISO: mtools builds the embedded EFI image that grub-mkrescue uses
|
||||||
|
"mformat|mtools"
|
||||||
)
|
)
|
||||||
|
|
||||||
MISSING=()
|
MISSING=()
|
||||||
@@ -49,6 +51,19 @@ for entry in "${NEEDED[@]}"; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# grub-mkrescue assembles the ISO bootloader from the HOST's GRUB modules.
|
||||||
|
# A missing x86_64-efi module set produces an ISO with no UEFI boot entry —
|
||||||
|
# the exact cause of "make sure there is a bootable uefi x64 image" on UEFI
|
||||||
|
# machines. Verify the module dirs directly (they are not binaries).
|
||||||
|
for spec in "/usr/lib/grub/x86_64-efi:grub-efi-amd64-bin:UEFI" \
|
||||||
|
"/usr/lib/grub/i386-pc:grub-pc-bin:BIOS"; do
|
||||||
|
dir="${spec%%:*}"; rest="${spec#*:}"; pkg="${rest%%:*}"; what="${rest##*:}"
|
||||||
|
if [[ ! -d "$dir" ]]; then
|
||||||
|
warn "missing: GRUB $what modules in $dir (package: $pkg) — ISO will not boot via $what"
|
||||||
|
MISSING+=("$pkg")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
if [[ ${#MISSING[@]} -eq 0 ]]; then
|
if [[ ${#MISSING[@]} -eq 0 ]]; then
|
||||||
log "all host build dependencies present ✓"
|
log "all host build dependencies present ✓"
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
Reference in New Issue
Block a user