Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

install: write kernel-direct (kernel as BOOTX64.EFI), not splash chain

Symptom: install completed, UEFI boot entry registered, firmware loaded
"AC Native OS" entry → "Chinese characters scrolling, cuts to black,
falls to boot selector." Classic "EFI binary loaded but doesn't actually
boot" garbage display.

Cause: the install copied splash.efi as /EFI/BOOT/BOOTX64.EFI on the
destination disk (because source USB used systemd-boot universal layout
where splash chains to LOADER.EFI = systemd-boot, which then loads
KERNEL.EFI). On the source USB this works because all the chain
targets are present and firmware-discoverable on the same FAT. On the
freshly installed internal disk the SAME splash.efi fails — likely
because splash assumes a hardcoded partition GUID for LOADER.EFI that
doesn't match the new disk, or because the chain semantics don't
translate cleanly when boot is via NVRAM entry rather than firmware
fallback path.

Fix: install ALWAYS uses kernel-direct boot. The kernel itself is
copied as /EFI/BOOT/BOOTX64.EFI and runs as an EFI stub — its
CONFIG_CMDLINE has `initrd=\initramfs.cpio.gz` baked in so it finds
initramfs at the ESP root automatically. No splash, no systemd-boot,
no loader/entries, no chain.

This is exactly what the USB ACBOOT partition does and it boots
cleanly on the same hardware. We were just gratuitously using the
more complex systemd-boot layout for installs.

Also lifted the `&& systemd_boot_layout` gate on initramfs_src
discovery so the kernel-direct path can find /initramfs.cpio.gz on the
source USB regardless of whether the source had a systemd-boot layout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+39 -32
+39 -32
fedac/native/src/ac-native.c
··· 1098 1098 snprintf(config_src, sizeof(config_src), "%s/config.json", source_mount); 1099 1099 snprintf(loader_conf_src, sizeof(loader_conf_src), "%s/loader/loader.conf", source_mount); 1100 1100 snprintf(loader_entry_src, sizeof(loader_entry_src), "%s/loader/entries/ac-native.conf", source_mount); 1101 - if (access(source_dev, F_OK) == 0 && systemd_boot_layout) { 1101 + // Initramfs is at the ESP root in EVERY layout the oven produces (Phase 2 1102 + // de-embed), not just systemd-boot. Drop the `&& systemd_boot_layout` 1103 + // gate — the kernel-direct install path needs initramfs from the source 1104 + // ACBOOT/ACEFI mount even when source_score detected chainloader-only. 1105 + if (access(source_dev, F_OK) == 0) { 1102 1106 char initramfs_gz[96]; 1103 1107 char initramfs_lz4[96]; 1104 1108 snprintf(initramfs_gz, sizeof(initramfs_gz), "%s/initramfs.cpio.gz", source_mount); ··· 1749 1753 ac_log("[install] repartitioned OK, retrying copy\n"); 1750 1754 } 1751 1755 } 1752 - // Copy kernel (and initramfs/loader for systemd-boot layout) 1756 + // Copy kernel + initramfs onto the destination ESP. ALWAYS use 1757 + // the kernel-direct layout, regardless of what the source USB 1758 + // looks like: 1759 + // 1760 + // /EFI/BOOT/BOOTX64.EFI = the actual kernel (EFI stub) 1761 + // /initramfs.cpio.gz = initramfs at ESP root 1762 + // 1763 + // Why not systemd-boot for installs? splash.efi as BOOTX64.EFI 1764 + // worked on the source USB (because firmware found splash, ran 1765 + // it, splash chained to LOADER.EFI = systemd-boot, sd-boot 1766 + // loaded kernel + initramfs from the same FAT). But on the 1767 + // installed disk the SAME splash.efi → "Chinese characters 1768 + // scrolling, cuts to black, falls to boot selector" — symptom 1769 + // of the firmware loading the EFI binary and getting confused 1770 + // by partial output / failed chain. The kernel-direct boot 1771 + // (kernel as BOOTX64.EFI) IS what the USB ACBOOT partition uses 1772 + // and it boots cleanly on the same hardware. Just use that. 1773 + // 1774 + // The kernel's CONFIG_CMDLINE has `initrd=\initramfs.cpio.gz` 1775 + // baked in, so the EFI stub finds initramfs at the ESP root 1776 + // automatically — no loader config needed. 1753 1777 long sz = 0; 1754 - if (systemd_boot_layout) { 1755 - // Universal layout: splash BOOTX64.EFI + LOADER.EFI + 1756 - // KERNEL.EFI + initramfs + loader config. 1757 - long bsz = copy_file(bootloader_src, "/tmp/hd/EFI/BOOT/BOOTX64.EFI"); 1758 - long lsz = copy_file(loader_src, "/tmp/hd/EFI/BOOT/LOADER.EFI"); 1759 - long ksz = copy_file(chain_kernel_src, "/tmp/hd/EFI/BOOT/KERNEL.EFI"); 1778 + const char *kernel_to_install = (systemd_boot_layout || chainloader_layout) 1779 + ? chain_kernel_src // KERNEL.EFI on source 1780 + : kernel_src; // monolithic BOOTX64.EFI is the kernel 1781 + long ksz = copy_file(kernel_to_install, "/tmp/hd/EFI/BOOT/BOOTX64.EFI"); 1782 + ac_log("[install] kernel-direct: BOOTX64.EFI = %ld bytes (from %s)\n", 1783 + ksz, kernel_to_install); 1784 + long isz = 0; 1785 + if (initramfs_src[0]) { 1786 + const char *initramfs_name = strstr(initramfs_src, ".lz4") ? "initramfs.cpio.lz4" : "initramfs.cpio.gz"; 1760 1787 char initramfs_dst[128]; 1761 - const char *initramfs_name = strstr(initramfs_src, ".lz4") ? "initramfs.cpio.lz4" : "initramfs.cpio.gz"; 1762 1788 snprintf(initramfs_dst, sizeof(initramfs_dst), "/tmp/hd/%s", initramfs_name); 1763 - long isz = copy_file(initramfs_src, initramfs_dst); 1764 - mkdir("/tmp/hd/loader", 0755); 1765 - mkdir("/tmp/hd/loader/entries", 0755); 1766 - long csz = copy_file(loader_conf_src, "/tmp/hd/loader/loader.conf"); 1767 - long esz = copy_file(loader_entry_src, "/tmp/hd/loader/entries/ac-native.conf"); 1768 - ac_log("[install] bootloader: %ld bytes\n", bsz); 1769 - ac_log("[install] loader: %ld bytes\n", lsz); 1770 - ac_log("[install] kernel: %ld bytes\n", ksz); 1771 - ac_log("[install] initramfs: %ld bytes\n", isz); 1772 - ac_log("[install] loader.conf: %ld bytes\n", csz); 1773 - ac_log("[install] loader entry: %ld bytes\n", esz); 1774 - sz = (bsz > 0 && lsz > 0 && ksz > 0 && isz > 0 && csz > 0 && esz > 0) 1775 - ? (bsz + lsz + ksz + isz + csz + esz) 1776 - : -1; 1777 - } else if (chainloader_layout) { 1778 - long bsz = copy_file(bootloader_src, "/tmp/hd/EFI/BOOT/BOOTX64.EFI"); 1779 - long ksz = copy_file(chain_kernel_src, "/tmp/hd/EFI/BOOT/KERNEL.EFI"); 1780 - ac_log("[install] chainloader: %ld bytes\n", bsz); 1781 - ac_log("[install] kernel: %ld bytes\n", ksz); 1782 - sz = (bsz > 0 && ksz > 0) ? (bsz + ksz) : -1; 1789 + isz = copy_file(initramfs_src, initramfs_dst); 1790 + ac_log("[install] initramfs: %ld bytes (from %s)\n", isz, initramfs_src); 1783 1791 } else { 1784 - // Monolithic: single BOOTX64.EFI is the kernel 1785 - sz = copy_file(kernel_src, "/tmp/hd/EFI/BOOT/BOOTX64.EFI"); 1786 - ac_log("[install] copy result: %ld bytes\n", sz); 1792 + ac_log("[install] no initramfs source — kernel must have it embedded\n"); 1787 1793 } 1794 + sz = (ksz > 0 && (isz > 0 || initramfs_src[0] == '\0')) ? (ksz + isz) : -1; 1788 1795 1789 1796 if (sz <= 0) { 1790 1797 ac_log("[install] copy failed on %s (sz=%ld)\n", devpath, sz);