Skip to content

Instantly share code, notes, and snippets.

@mbtamuli
Last active September 4, 2020 17:35
Show Gist options
  • Save mbtamuli/119256296920c3e004e78430498cc41e to your computer and use it in GitHub Desktop.
Save mbtamuli/119256296920c3e004e78430498cc41e 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.

Partition scheme

Depending on your partition scheme, you might need to change the paths in the steps.

lsblk

NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
nvme0n1     259:0    0 476.9G  0 disk 
├─nvme0n1p1 259:1    0   529M  0 part 
├─nvme0n1p2 259:2    0   100M  0 part /boot
├─nvme0n1p3 259:3    0    16M  0 part 
├─nvme0n1p4 259:4    0 298.8G  0 part 
├─nvme0n1p5 259:5    0   581M  0 part 
└─nvme0n1p6 259:6    0 176.9G  0 part /

/etc/fstab

UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx	/         	ext4      	rw,relatime	0 1
UUID=xxxx-xxxx      	/boot     	vfat      	rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro	0 2

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
    note: You might need to change the path according to your setup /boot/EFI/Linux/linux.efi

    #!/bin/bash -e
    
    SCRIPT_TMPDIR=$(mktemp -d)
    ROOT_PARTUUID="$(findmnt --noheadings --output PARTUUID --target /)"
    
    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 --force /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
    
@mbtamuli
Copy link
Author

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