Boot fixes: drop the stock BLS entry, define load_video, set kernel cmdline
All checks were successful
build image / build (push) Successful in 23m57s

First boot on the hardware failed, returning to the GRUB menu with:

    can't find command 'load_video'
    file '/boot/vmlinuz-7.1.5-200.fc44.aarch64' not found
    you need to load the kernel first

The title in that message was the tell: "Fedora Linux (7.1.5-...) 44 (Forty
Four)" is Fedora's stock format, not ours. GRUB was booting an entry we did not
write. Confirmed by unpacking the published image and reading the boot
filesystem — /loader/entries held two files, and the one named after the
machine-id sorts before c630-*, so it won.

kernel-install wrote it during the dnf transaction, from inside the install
root where /boot is an ordinary directory rather than a partition. It was wrong
three ways: paths of /boot/vmlinuz-… that resolve nowhere once /boot is its own
filesystem; an empty options line, so no root= and no command line at all; and
no devicetree, so even had it loaded, the kernel would not have known what
machine it was on. Ours, sitting right beside it, was correct throughout.

So: delete any entry we did not write, and define load_video in grub.cfg —
blscfg emits menuentries that call it, and Fedora's generated config defines it
where a hand-written one must too.

Also write /etc/kernel/cmdline. That empty options line was not a build-time
quirk; it is what kernel-install produces when nothing tells it the command
line. The same gap would have bitten on the device at the first
`dnf update kernel`, writing an entry with no root= and no C630 quirks, and the
laptop would not have come back.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
This commit is contained in:
2026-07-27 17:01:48 +03:00
parent a5f492d115
commit 2243166642

View File

@@ -245,6 +245,15 @@ UUID=${BOOT_UUID} /boot ext4 defaults 1 2
UUID=${ESP_UUID} /boot/efi vfat umask=0077,shortname=winnt 0 2 UUID=${ESP_UUID} /boot/efi vfat umask=0077,shortname=winnt 0 2
EOF EOF
# The entry kernel-install wrote during the transaction had an empty options
# line, because nothing told it what the command line should be. That same gap
# would bite on the device: the first `dnf update kernel` would write an entry
# with no root= and no C630 quirks, and the machine would not come back. This is
# where kernel-install looks.
mkdir -p "$ROOTFS/etc/kernel"
printf 'root=UUID=%s ro %s\n' "$ROOT_UUID" "$DEVICE_CMDLINE" \
> "$ROOTFS/etc/kernel/cmdline"
# Empty (not missing) machine-id marks this as a first boot for systemd, which # Empty (not missing) machine-id marks this as a first boot for systemd, which
# then generates a unique one per device rather than cloning the builder's. # then generates a unique one per device rather than cloning the builder's.
: > "$ROOTFS/etc/machine-id" : > "$ROOTFS/etc/machine-id"
@@ -290,9 +299,19 @@ chroot "$ROOTFS" dracut --force --no-hostonly --no-hostonly-cmdline \
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
log "Writing bootloader configuration" log "Writing bootloader configuration"
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
mkdir -p "$ROOTFS/boot/loader/entries"
# kernel-install already wrote an entry during the dnf transaction, from inside
# the install root — where /boot is an ordinary directory, not a partition. It
# is wrong in three ways: its paths are /boot/vmlinuz-… which resolve nowhere
# once /boot is a filesystem in its own right; its options line is empty, so no
# root= and no command line; and it has no devicetree, so even if it loaded, the
# kernel would not know what machine it was on. Being named after the machine-id
# it also sorts before ours, so GRUB picks it. Delete anything we did not write.
rm -f "$ROOTFS/boot/loader/entries/"*.conf
# The bootstrap BLS entry. Subsequent kernels get theirs from kernel-install, # The bootstrap BLS entry. Subsequent kernels get theirs from kernel-install,
# with the devicetree line supplied by 95-c630-devicetree.install. # with the devicetree line supplied by 95-c630-devicetree.install.
mkdir -p "$ROOTFS/boot/loader/entries"
cat > "$ROOTFS/boot/loader/entries/c630-${KVER}.conf" <<EOF cat > "$ROOTFS/boot/loader/entries/c630-${KVER}.conf" <<EOF
title Fedora Linux ${FEDORA_RELEASE} (${KVER}) — ${DEVICE_DESC} title Fedora Linux ${FEDORA_RELEASE} (${KVER}) — ${DEVICE_DESC}
version ${KVER} version ${KVER}
@@ -320,6 +339,19 @@ insmod all_video
insmod gzio insmod gzio
insmod blscfg insmod blscfg
# blscfg turns each BLS entry into a menuentry that calls load_video before
# loading the kernel. Fedora's generated grub.cfg defines it; a hand-written one
# has to as well, or every entry fails with "can't find command 'load_video'".
function load_video {
if [ x\$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod video_bochs
insmod video_cirrus
fi
}
search --no-floppy --fs-uuid --set=root ${BOOT_UUID} search --no-floppy --fs-uuid --set=root ${BOOT_UUID}
if [ -s \$prefix/grubenv ]; then if [ -s \$prefix/grubenv ]; then