Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradfa/b99e24f1dd9fc9e5e8c0cbc1bc6bf6a7 to your computer and use it in GitHub Desktop.
Save bradfa/b99e24f1dd9fc9e5e8c0cbc1bc6bf6a7 to your computer and use it in GitHub Desktop.
Initramfs hook script to copy kernel and initrd.img to EFI System Partition

If the Linux kernel is compiled with the EFI stub loader (grep CONFIG_EFI_STUB /boot/config-*), then an EFI BIOS can boot the kernel directly, without the need for a bootloader like GRUB. This only requires that the kernel and the initrd exist on the EFI partition. The EFI boot menu and boot order can be managed with the command-line utility efibootmgr.

Copying the kernel image and initrd onto the EFI partition the first time is simple; the problem is keeping them up-to-date as the system is updated. In particular, lots of software packages can trigger the initrd to be rebuilt. The most recent kernel image and initrd need to be copied to the EFI partition every time they are updated.

The Debian Linux Kernel Handbook documents initramfs hooks, stating that "Packages for boot loaders that need to be updated whenever the files they load are modified must also install hook scripts in /etc/initramfs/post-update.d".

Additionally, Debian automatically invokes initramfs-tools after a kernel is installed via a script in /etc/kernel/postinst.d/initramfs-tools.

Debian also maintains /vmlinuz and /initrd.img symbolic links to the current configured kernel and initrd.

Therefore, whenever a new kernel is installed, or some other software is updated that triggers the initrd to be rebuilt, both the kernel image and the initrd.img can be re-copied to the EFI System Partition automatically by putting a script in /etc/initramfs/post-update.d. This will also re-copy the unchanged kernel whenever the initrd is regenerated by some other software update, but doing so is harmless.

E.g.,

#!/usr/bin/env bash

EFI_DEST_PATH="/boot/efi/EFI/linux/"

echo "Copying kernel and initrd to EFI System Partition"

cp -fv /{vmlinuz,initrd.img} "$EFI_DEST_PATH"

Then, the next time the system boots, it will have the latest kernel image and initrd on the EFI system partition.

@bradfa
Copy link
Author

bradfa commented Dec 22, 2021

To extend this to work with systemd-boot on Debian bullseye (and maybe other untested releases) so every time you update your initramfs it will update the copy used by systemd-boot on your ESP, you can craft a /etc/initramfs/post-update.d/zz-update-systemd-boot file like:

#!/bin/sh
set -e

KERNEL="/boot/vmlinuz-$1"
/usr/bin/kernel-install --verbose add "$1" "$KERNEL" "$2"

exit 0

This is very similar to the kernel postinst and postrm scripting found here: https://p5r.uk/blog/2020/using-systemd-boot-on-debian-bullseye.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment