Instantly share code, notes, and snippets.

Embed
What would you like to do?
Ubuntu 16.04 using systemd-boot instead of grubby

You do not need a separate /boot partition unless you have an LVM setup (used in dm-crypt setups).

Run ubiquity -b to open the installer with the option of skipping grub installation (since we're using systemd-boot).

When you get to the screen "Ubuntu has finished installation" choose Continue testing.

Open a Terminal.

Chroot into the new system.

mount /dev/sda5 /mnt # replace /dev/sda5 with wherever it is you installed Ubuntu
mount /dev/sda1 /mnt/boot/efi # this is where Ubuntu mounts the ESP
for i in /dev /dev/pts /proc /sys /run; do sudo mount -B $i /mnt$i; done
chroot /mnt

This will set systemd-boot to be our default:

aj@aj-MacbookPro $ sudo -i
root@aj-MacBookPro:~# history
    1  cd boot
    2  ls
    3  cd efi
    4  ls
    5  cat /etc/fstab # check entries
    6  ls
    7  cd ..
    8  ls
    9  cp abi-4.4.0-22-generic efi
   10  cp config-4.4.0-22-generic efi
   11  cp initrd.img-4.4.0-22-generic efi
   12  cp System.map-4.4.0-22-generic efi
   13  cp vmlinuz-4.4.0-22-generic efi
   14  ls efi
   15  cd efi
   16  ls
   17  bootctl --help
   18  cd
   19  cd /boot/efi
   20  ls
   21  mkdir -p loader/entries
   22  ls
   23  vi loader/loader.conf
   24  vi loader/entries/ubuntu.conf
   25  tree
   26  apt install tree
   27  tree
   28  bootctl install --path=/boot/efi
   29  efibootmgr
   30  ls
   31  cd /
   32  ls
   33  cd boo
   34  cd boot
   35  ls
   36  ls -l
   37  cp initrd.img-4.4.0-22-generic efi
   38  tree efi
   39  bootctl install --path=/boot/efi
   40  cd efi
   41  ls
   42  ls EFI
   43  ls EFI/systemd/
   51  efibootmgr -c -d /dev/sda1 -p 1 -l EFI/systemd/systemd-bootx64.efi -L "Linux Boot Manager"
   52  efibootmgr -o 0000
   53  ls
   54  history
root@aj-MacBookPro:~# 
@hashhar

This comment has been minimized.

Copy link

hashhar commented Mar 5, 2017

Works great. I have written a kernel postinstall hook to automate the copying of kernels into ESP. I'll share it here once I get back to my system.

#!/bin/bash

vmlinuz=$(find /boot -maxdepth 1 -name "vmlinuz-*-generic")
version=$(echo $vmlinuz | grep -o -P "\d\.\d\.\d-\d{2}" | sort -V | head -n -1)
latest=$(echo $vmlinuz | grep -o -P "\d\.\d\.\d-\d{2}" | sort -V | tail -n 1)

echo "COPYING ${latest}-generic. LATEST VERSION."
for file in abi config initrd.img System.map vmlinuz; do
    cp "/boot/${file}-${latest}-generic" "/boot/efi/ubuntu/${file}-generic"
    cat << 'EOF' > /boot/efi/loader/entries/ubuntu.conf
title   Ubuntu GNOME
linux   /ubuntu/vmlinuz-generic
initrd  /ubuntu/initrd.img-generic
options root=PARTUUID=74984ba1-8d9a-410e-87d9-5bf2cee46462 rw
EOF
done

for ver in $version; do
    echo "COPYING ${ver}-generic."
    for file in abi config initrd.img System.map vmlinuz; do
        cp "/boot/${file}-${ver}-generic" "/boot/efi/ubuntu/${file}-${ver}-generic"
        cat << EOF > /boot/efi/loader/entries/ubuntu-${ver}.conf
title   Ubuntu GNOME ${ver}
linux   /ubuntu/vmlinuz-${ver}-generic
initrd  /ubuntu/initrd.img-${ver}-generic
options root=PARTUUID=74984ba1-8d9a-410e-87d9-5bf2cee46462 rw
EOF
    done
done

exit 0
@petar-andrejic

This comment has been minimized.

Copy link

petar-andrejic commented Mar 16, 2017

https://wiki.archlinux.org/index.php/systemd-boot
Surely this would work as well, and would be a lot simpler?

@hashhar

This comment has been minimized.

Copy link

hashhar commented Mar 31, 2017

@petar-andrejic Debian based systems refuse to install kernels (or any package for that matter) on FAT based filesystems. You do have to setup some way of copying the kernel images over to the ESP for systemd-boot to work. Personally rEFInd is the most flexible and powerful bootloader I've used but since I don't use Ubuntu these days I simply load the kernel image as an EFI binary (EFISTUB as mentioned on ArchWiki).

@Brainiarc7

This comment has been minimized.

Copy link

Brainiarc7 commented May 15, 2018

And for setting custom kernel options with systemd-boot, you can use kernelstub.

Example:

sudo kernelstub -a "options here"

For example, to add nvidia modeset, you would use:

sudo kernelstub -a "nvidia-drm.modeset=1"

This has the advantage of keeping everything up to date automatically when your system gets a new kernel.

@0x715C

This comment has been minimized.

Copy link

0x715C commented May 26, 2018

@hashhar

I use d+, otherwise the grep match fails when kernels >= 4.10.x-y

#!/bin/bash

vmlinuz=$(find /boot -maxdepth 1 -name "vmlinuz-*-generic")
version=$(echo $vmlinuz | grep -o -P "\d+\.\d+\.\d+\-\d+" | sort -V | head -n -1)
latest=$(echo $vmlinuz | grep -o -P "\d+\.\d+\.\d+\-\d+" | sort -V | tail -n 1)

echo "COPYING ${latest}-generic. LATEST VERSION."
for file in abi config initrd.img System.map vmlinuz; do
    cp "/boot/${file}-${latest}-generic" "/boot/efi/ubuntu/${file}-generic"
    cat << 'EOF' > /boot/efi/loader/entries/ubuntu.conf
title   Ubuntu GNOME
linux   /ubuntu/vmlinuz-generic
initrd  /ubuntu/initrd.img-generic
options root=UUID=INSERTYOURROOTUUIDHERE rw rootflags=subvol=INSERTYOURSUBVOLHERE intel_iommu=on
EOF
done

for ver in $version; do
    echo "COPYING ${ver}-generic."
    for file in abi config initrd.img System.map vmlinuz; do
        cp "/boot/${file}-${ver}-generic" "/boot/efi/ubuntu/${file}-${ver}-generic"
        cat << EOF > /boot/efi/loader/entries/ubuntu-${ver}.conf
title   Ubuntu GNOME ${ver}
linux   /ubuntu/vmlinuz-${ver}-generic
initrd  /ubuntu/initrd.img-${ver}-generic
options root=UUID=INSERTYOURROOTUUIDHERE rw rootflags=subvol=INSERTYOURSUBVOLHERE intel_iommu=on
EOF
    done
done

exit 0
@pepa65

This comment has been minimized.

Copy link

pepa65 commented May 29, 2018

Are the abi-* config-* and System.map-* needed? Or even used??

@pepa65

This comment has been minimized.

Copy link

pepa65 commented Jun 3, 2018

  • You don't need a separate /boot partitition, even if you're using LUKS/LVM
  • You only need vmlinuz and initrd.img, they can be put anywhere on /boot/efi, but are supposed to reside somewhere in /boot/efi/EFI/*/
  • bootctl --path /boot/efi install installs /boot/efi/EFI/systemd/systemd-bootx64.efi which populates a UEFI bootmenu from /boot/efi/loader/*.conf files, and defaults for the loader can be set in /boot/efi/loader/loader.conf
  • For Ubuntu, this can be used to set things up: https://github.com/pepa65/misc/blob/master/bootctlu
@anxanywhere

This comment has been minimized.

Copy link

anxanywhere commented Aug 28, 2018

Hi @0x715C and @hashhar,

Thank you for shared code.

Question about shared code:

Why repeating the line that writes latest kernel entry to /boot/efi/loader/entries/ubuntu.conf? The latest kernel entry is expected to be written only once, so that part of code could be moved out of first FOR block.

Regards,
ANx

Suggesting the code below:

#!/bin/bash

vmlinuz=$(find /boot -maxdepth 1 -name "vmlinuz-*-generic")
version=$(echo $vmlinuz | grep -o -P "\d+\.\d+\.\d+\-\d+" | sort -V | head -n -1)
latest=$(echo $vmlinuz | grep -o -P "\d+\.\d+\.\d+\-\d+" | sort -V | tail -n 1)

echo ">> COPYING ${latest}-generic. LATEST VERSION."

cat << EOF > /boot/efi/loader/entries/ubuntu.conf
title   Ubuntu
linux   /ubuntu/vmlinuz-generic
initrd  /ubuntu/initrd.img-generic
options root=/dev/VG0/lvROOT rw
EOF

for file in initrd.img vmlinuz; do
    cp "/boot/${file}-${latest}-generic" "/boot/efi/ubuntu/${file}-generic"
done

for ver in $version; do

    echo ">> COPYING ${ver}-generic."

cat << EOF > /boot/efi/loader/entries/ubuntu-${ver}.conf
title   Ubuntu ${ver}
linux   /ubuntu/vmlinuz-${ver}-generic
initrd  /ubuntu/initrd.img-${ver}-generic
options root=/dev/VG0/lvROOT rw
EOF

    for file in initrd.img vmlinuz; do
        cp "/boot/${file}-${ver}-generic" "/boot/efi/ubuntu/${file}-${ver}-generic"
    done
done

exit 0
@jeremyb31

This comment has been minimized.

Copy link

jeremyb31 commented Dec 25, 2018

pepa65 the abi files are not needed and are not included with Ubuntu kernel 4.15.0-43

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