Skip to content

Instantly share code, notes, and snippets.

@mugdha-adhav
Forked from mbtamuli/EFISTUB.md
Created August 18, 2020 13:53
Show Gist options
  • Save mugdha-adhav/380441ba7e289d7319796c45e850e144 to your computer and use it in GitHub Desktop.
Save mugdha-adhav/380441ba7e289d7319796c45e850e144 to your computer and use it in GitHub Desktop.

Why

We don't want extra stuff

What

We want to boot Linux without installing a boot loader

How

  1. We need to create an entry in the UEFI NVRAM entries list.
  2. We can use the bcfg tool for that. But we need a unified kernel image(something with .efi).
  3. We use the objcopy utility to do generate the unified kernel image.
  4. Finally, we need to setup Pacman hooks to have the unified kernel image every time we upgrade linux.

Steps

  1. Install binutils package, as we need the objcopy utility

    pacman -S binutils
    
  2. Get PARTUUID using lsblk command

    lsblk --output=PATH,PARTUUID
    
  3. Create a file with your kernel command line parameters

    cat <<EOF > kernel-command-line.txt
    root=PARTUUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx rw
    EOF
    
  4. Create and place linux.efi at /boot/EFI/Linux/linux.efi

    objcopy \
        --add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=0x20000 \
        --add-section .cmdline="kernel-command-line.txt" --change-section-vma .cmdline=0x30000 \
        --add-section .splash="/usr/share/systemd/bootctl/splash-arch.bmp" --change-section-vma .splash=0x40000 \
        --add-section .linux="/boot/vmlinuz-linux" --change-section-vma .linux=0x2000000 \
        --add-section .initrd="/boot/initramfs-linux.img" --change-section-vma .initrd=0x3000000 \
        "/usr/lib/systemd/boot/efi/linuxx64.efi.stub" "linux.efi"
    mkdir -p /boot/EFI/Linux/
    cp linux.efi /boot/EFI/Linux/
    
  5. Use the bcfg command in UEFI Shell v2 (i.e., from the Arch Linux live iso).

    bcfg boot add 0 fs2:\EFI\Linux\linux.efi "Arch Linux"
    
  6. Create the hook file /etc/pacman.d/hooks/90-update-efistub.hook with content

    [Trigger]
    Operation = Install
    Operation = Upgrade
    Type = Path
    Target = usr/src/*/dkms.conf
    Target = usr/lib/modules/*/build/include/
    Target = usr/lib/modules/*/modules.alias
    
    [Action]
    Description = Updating linux efistub...
    When = PostTransaction
    Depends = linux
    Depends = binutils
    Depends = util-linux
    Exec = /etc/pacman.d/scripts/efistub-update
    NeedsTargets
    
  7. Also create the corresponding script /etc/pacman.d/scripts/efistub-update with content

    #!/bin/bash -e
    
    SCRIPT_TMPDIR=$(mktemp -d)
    ROOT_PARTITION=$(findmnt -n -o SOURCE --target /)
    ROOT_PARTUUID=$(lsblk --output=PARTUUID $ROOT_PARTITION --noheadings)
    
    trap "{ rm -rf $SCRIPT_TMPDIR; }" EXIT HUP INT QUIT TERM STOP PWR
    
    pushd "$SCRIPT_TMPDIR" > /dev/null
    
    cat <<EOF > kernel-command-line.txt
    root=PARTUUID=$ROOT_PARTUUID rw
    EOF
    
    objcopy \
        --add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=0x20000 \
        --add-section .cmdline="kernel-command-line.txt" --change-section-vma .cmdline=0x30000 \
        --add-section .splash="/usr/share/systemd/bootctl/splash-arch.bmp" --change-section-vma .splash=0x40000 \
        --add-section .linux="/boot/vmlinuz-linux" --change-section-vma .linux=0x2000000 \
        --add-section .initrd="/boot/initramfs-linux.img" --change-section-vma .initrd=0x3000000 \
        "/usr/lib/systemd/boot/efi/linuxx64.efi.stub" "linux.efi"
    rm /boot/EFI/Linux/linux.efi
    cp linux.efi /boot/EFI/Linux/
    
    popd > /dev/null
    
  8. Make the script executable

    chmod +x /etc/pacman.d/scripts/efistub-update
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment