From 078c5f4f9443d69b0b91666aa97059db223c9dc0 Mon Sep 17 00:00:00 2001 From: Breadway Date: Sun, 14 Jun 2026 17:57:50 +0800 Subject: [PATCH] Fix unbootable installs: lay the kernel into the target and own GRUB archiso keeps vmlinuz/initramfs in the ISO boot dir, not the squashfs, so unpackfs lays down an empty /boot. The chroot's mkinitcpio/grub-mkconfig had nothing to work with and the ESP ended up empty (firmware found no bootloader). - shellprocess@kernel (dontChroot) copies the live kernel into the target /boot before the bootloader step - post-install.sh now runs grub-install itself, including a --removable pass so firmware with no NVRAM entry still boots via EFI/BOOT/BOOTX64.EFI --- .../modules/shellprocess-kernel.conf | 8 +++++++ iso/airootfs/etc/calamares/post-install.sh | 21 +++++++++++++++- iso/airootfs/etc/calamares/settings.conf | 8 +++++++ iso/airootfs/usr/local/bin/bos-copy-kernel | 24 +++++++++++++++++++ iso/profiledef.sh | 1 + 5 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 iso/airootfs/etc/calamares/modules/shellprocess-kernel.conf create mode 100755 iso/airootfs/usr/local/bin/bos-copy-kernel diff --git a/iso/airootfs/etc/calamares/modules/shellprocess-kernel.conf b/iso/airootfs/etc/calamares/modules/shellprocess-kernel.conf new file mode 100644 index 0000000..4e5ab5c --- /dev/null +++ b/iso/airootfs/etc/calamares/modules/shellprocess-kernel.conf @@ -0,0 +1,8 @@ +--- +# Lay the kernel into the target /boot before the bootloader/initramfs steps. +# Runs in the live environment (not the chroot) so it can read the ISO boot dir. +dontChroot: true +timeout: 60 + +script: + - "/usr/bin/bash /usr/local/bin/bos-copy-kernel ${ROOT}" diff --git a/iso/airootfs/etc/calamares/post-install.sh b/iso/airootfs/etc/calamares/post-install.sh index 1a81b5a..e126a22 100644 --- a/iso/airootfs/etc/calamares/post-install.sh +++ b/iso/airootfs/etc/calamares/post-install.sh @@ -35,7 +35,26 @@ fallback_options="-S autodetect" PRESET mkinitcpio -P || echo "WARN: mkinitcpio regeneration failed" -# Refresh GRUB so it references the rebuilt initramfs (and the new fallback). +# --------------------------------------------------------------------------- +# Install GRUB ourselves. Calamares' bootloader module runs before the kernel +# and initramfs exist (archiso keeps them out of the squashfs; shellprocess +# @kernel only lays vmlinuz down just beforehand), so its grub-install/config +# leaves the ESP empty. Redo it here, now that /boot is fully populated. +# +# Two passes: the standard NVRAM entry, plus a --removable copy to +# EFI/BOOT/BOOTX64.EFI so firmware that lost/never wrote an NVRAM entry (the +# "no boot device / screen just refreshes" failure) still finds a bootloader. +# --------------------------------------------------------------------------- +if command -v grub-install &>/dev/null; then + grub-install --target=x86_64-efi --efi-directory=/boot/efi \ + --bootloader-id=BOS --recheck \ + || echo "WARN: grub-install (nvram) failed" + grub-install --target=x86_64-efi --efi-directory=/boot/efi \ + --removable --recheck \ + || echo "WARN: grub-install (removable) failed" +fi + +# Refresh GRUB so it references the kernel + rebuilt initramfs. if command -v grub-mkconfig &>/dev/null; then grub-mkconfig -o /boot/grub/grub.cfg || echo "WARN: grub-mkconfig failed" fi diff --git a/iso/airootfs/etc/calamares/settings.conf b/iso/airootfs/etc/calamares/settings.conf index ea17565..bb6f01c 100644 --- a/iso/airootfs/etc/calamares/settings.conf +++ b/iso/airootfs/etc/calamares/settings.conf @@ -1,6 +1,13 @@ --- modules-search: [/etc/calamares/modules, /usr/lib/calamares/modules] +# Second shellprocess instance: copies the live kernel into the target /boot +# (archiso keeps it out of the squashfs) before the bootloader step runs. +instances: +- id: kernel + module: shellprocess + config: shellprocess-kernel.conf + sequence: - show: - welcome @@ -22,6 +29,7 @@ sequence: - networkcfg - hwclock - packages + - shellprocess@kernel - bootloader - shellprocess - umount diff --git a/iso/airootfs/usr/local/bin/bos-copy-kernel b/iso/airootfs/usr/local/bin/bos-copy-kernel new file mode 100755 index 0000000..1d75e46 --- /dev/null +++ b/iso/airootfs/usr/local/bin/bos-copy-kernel @@ -0,0 +1,24 @@ +#!/bin/bash +# Copy the live kernel into the freshly-unpacked target /boot. +# +# archiso keeps vmlinuz/initramfs in the ISO boot dir (arch/boot/x86_64/), NOT +# in the squashfs, so the rootfs that unpackfs lays down has an empty /boot. +# Without a kernel, the chroot's `mkinitcpio -P` and `grub-mkconfig` produce +# nothing and the installed system is unbootable. +# +# Runs in the LIVE environment (Calamares shellprocess, dontChroot) so it can +# read /run/archiso/bootmnt; the target root mount point is passed as $1. +set -uo pipefail + +ROOT="${1:?target root required}" +SRC="/run/archiso/bootmnt/arch/boot/x86_64" + +install -d -m 0755 "$ROOT/boot" +cp -f "$SRC/vmlinuz-linux" "$ROOT/boot/vmlinuz-linux" + +# Microcode, if the live medium carries it (grub-mkconfig picks it up). +for u in amd-ucode.img intel-ucode.img; do + [ -f "$SRC/$u" ] && cp -f "$SRC/$u" "$ROOT/boot/$u" +done + +echo "Copied live kernel into $ROOT/boot" diff --git a/iso/profiledef.sh b/iso/profiledef.sh index 1d1e595..6c496b2 100644 --- a/iso/profiledef.sh +++ b/iso/profiledef.sh @@ -19,4 +19,5 @@ file_permissions=( ["/etc/calamares/post-install.sh"]="0:0:755" ["/usr/local/bin/bos-live-setup"]="0:0:755" ["/usr/local/bin/bos-launch-calamares"]="0:0:755" + ["/usr/local/bin/bos-copy-kernel"]="0:0:755" )