Skip to content

Instantly share code, notes, and snippets.

@gdamjan
Last active May 23, 2025 18:30
Show Gist options
  • Save gdamjan/ccdcda2c91119406a0f8d22f8b8f2c4a to your computer and use it in GitHub Desktop.
Save gdamjan/ccdcda2c91119406a0f8d22f8b8f2c4a to your computer and use it in GitHub Desktop.
Replace grub2 with systemd-boot on Ubuntu 22.04
  1. remove grub
apt purge --allow-remove-essential grub2-common grub-pc-bin grub-pc grub-gfxpayload-lists grub-efi-amd64-bin grub-efi-amd64-signed grub-common os-prober shim-signed libfreetype6 
apt-get autoremove --purge
rm -rf /boot/grub/
rm -rf /boot/efi/EFI/ubuntu
  1. make sure it's not installed back
    • apt-mark hold "grub*"
  2. install systemd-boot
apt install systemd-boot systemd-ukify
  1. create /etc/kernel/cmdline with the wanted kernel command line (check /proc/cmdline for inspiration)
  2. create /etc/kernel/postinst.d/zz-update-systemd-boot (see below, and make sure it's 0755 mode) and run it
  3. reinstall the kernel package so it triggers kernel-install & friends
  4. reboot
#!/bin/bash
#
# This is a simple kernel hook to populate the systemd-boot entries
# whenever kernels are added or removed.
#
# Our kernels.
KERNELS=()
FIND="find /boot -maxdepth 1 -name 'vmlinuz-*' -type f -print0 | sort -rz"
while IFS= read -r -u3 -d $'\0' LINE; do
KERNEL=$(basename "${LINE}")
KERNELS+=("${KERNEL:8}")
done 3< <(eval "${FIND}")
# There has to be at least one kernel.
if [ ${#KERNELS[@]} -lt 1 ]; then
echo -e "\e[2msystemd-boot\e[0m \e[1;31mNo kernels found.\e[0m"
exit 1
fi
LATEST="${KERNELS[@]:0:1}"
echo -e "\e[2msystemd-boot\e[0m \e[1;32m${LATEST}\e[0m"
objcopy \
--add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
--add-section .cmdline=/etc/kernel/cmdline --change-section-vma .cmdline=0x30000 \
--add-section .linux=/boot/vmlinuz-${LATEST} --change-section-vma .linux=0x2000000 \
--add-section .initrd=/boot/initrd.img-${LATEST} --change-section-vma .initrd=0x3000000 \
/usr/lib/systemd/boot/efi/linuxx64.efi.stub \
/boot/efi/EFI/Linux/ubuntu.efi
# Success!
exit 0
@mangkoran
Copy link

mangkoran commented Nov 15, 2024

Currently I am looking for a way to switch from grub2 to systemd-boot in Ubuntu 24.04 and found your gist. When I tried to remove grub packages, I get the following prompt which asked to remove a lot of Ubuntu-shipped packages that I actually want to keep.

❯ sudo apt purge --allow-remove-essential grub2-common grub-pc-bin grub-pc grub-gfxpayload-lists grub-efi-amd64-bin grub-efi-amd64-signed grub-common os-prober shim-signed libfreetype6
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Package 'grub-gfxpayload-lists' is not installed, so not removed
The following packages were automatically installed and are no longer required:
  acl adwaita-icon-theme apg apport apport-core-dump-handler apport-symptoms aptdaemon aptdaemon-data avahi-utils ca-certificates-java cheese-common colord-data cups-daemon cups-ipp-utils cups-pk-helper cups-server-common dconf-cli
  docbook-xml duplicity enchant-2 evolution-data-server-common fontconfig-config fonts-dejavu-extra fonts-droid-fallback fonts-noto-mono gedit-common geoclue-2.0 geocode-glib-common gir1.2-atk-1.0 gir1.2-dbusmenu-glib-0.4
  gir1.2-dee-1.0 gir1.2-gck-2 gir1.2-gcr-4 gir1.2-gdesktopenums-3.0 gir1.2-gdm-1.0 gir1.2-geoclue-2.0 gir1.2-gnomebluetooth-3.0 gir1.2-gnomedesktop-4.0 gir1.2-graphene-1.0 gir1.2-gst-plugins-base-1.0 gir1.2-gstreamer-1.0
  gir1.2-gudev-1.0 gir1.2-gweather-4.0 gir1.2-ibus-1.0 gir1.2-javascriptcoregtk-4.1 gir1.2-javascriptcoregtk-6.0 gir1.2-nm-1.0 gir1.2-notify-0.7 gir1.2-polkit-1.0 gir1.2-secret-1 gir1.2-snapd-2 gir1.2-soup-2.4 gir1.2-soup-3.0
  gir1.2-totemplparser-1.0 gir1.2-udisks-2.0 gir1.2-unity-7.0 gir1.2-upowerglib-1.0 gnome-bluetooth-3-common gnome-control-center-faces gnome-desktop3-data gnome-keyring-pkcs11 gnome-session-common gnome-settings-daemon-common
  gnome-shell-common gnome-terminal-data gnome-themes-extra-data grilo-plugins-0.3-base grim gstreamer1.0-pipewire gtk-update-icon-cache guile-3.0-libs heif-gdk-pixbuf heif-thumbnailer hicolor-icon-theme hplip-data humanity-icon-theme
  hunspell-en-us iio-sensor-proxy imagemagick-6-common ipp-usb java-common libaa1 libaacs0 libabw-0.1-1 libaom3 libatkmm-1.6-1v5 libavahi-glib1 libavc1394-0 libavif16 libavutil58 libbdplus0 libblas3 libboost-locale1.83.0
  libboost-thread1.83.0 libbrotli-dev libbs2b0 libburn4t64 libcaca0 libcamel-1.2-64t64 libcanberra-pulse libcanberra0t64 libcdio-cdda2t64 libcdio-paranoia2t64 libcdparanoia0 libcdr-0.1-1 libchafa0t64 libchromaprint1 libcjson1
  libclucene-contribs1t64 libclucene-core1t64 libclutter-1.0-common libcodec2-1.2 libcogl-common libcolamd3 libcolord2 libcolorhug2 libcue2 libcupsfilters2-common libcupsimage2t64 libdate-tz3 libdatrie-dev libdatrie1 libdav1d7
  libdbusmenu-glib4 libde265-0 libdecor-0-0 libdee-1.0-4 libdisplay-info1 libdjvulibre-text libdjvulibre21 libdmapsharing-4.0-3t64 libdouble-conversion3 libdv4t64 libe-book-0.1-1 libebackend-1.2-11t64 libebook-1.2-21t64
  libebook-contacts-1.2-4t64 libecal-2.0-3 libedata-book-1.2-27t64 libedata-cal-2.0-2t64 libedataserver-1.2-27t64 libei1 libeis1 libenchant-2-2 libeot0 libepoxy0 libepubgen-0.1-1 libetonyek-0.1-1 libevent-2.1-7t64 libexempi8 libexif12
  libexiv2-27 libexttextcat-2.0-0 libextutils-depends-perl libfftw3-double3 libflite1 libfmt9 libfontenc1 libfreehand-0.1-1 libfribidi-dev libgav1-1 libgck-1-0 libgcr-base-3-1 libgdata-common libgdata22 libgdm1 libgedit-amtk-5-common
  libgedit-gtksourceview-300-common libgee-0.8-2 libgeoclue-2-0 libgeocode-glib-2-0 libgexiv2-2 libgfortran5 libgif7 libglib-object-introspection-perl libglib-perl libglibmm-2.4-1t64 libglibmm-2.68-1t64 libglu1-mesa libgme0
  libgnome-autoar-0-0 libgnome-bluetooth-3.0-13 libgnome-desktop-4-2t64 libgnome-games-support-common libgnomekbd-common libgoa-1.0-0b libgoa-1.0-common libgom-1.0-0t64 libgphoto2-l10n libgphoto2-port12t64 libgpod-common libgpod4t64
  libgraphite2-3 libgraphite2-dev libgrilo-0.3-0 libgs-common libgsf-1-114 libgsf-1-common libgsm1 libgsound0t64 libgspell-1-common libgstreamer-plugins-good1.0-0 libgtk-3-common libgtk-4-common libgtk2.0-common
  libgtksourceview-5-common libgtop-2.0-11 libgtop2-common libgupnp-av-1.0-3 libgupnp-dlna-2.0-4 libgweather-4-0t64 libgweather-4-common libheif-plugin-aomdec libheif-plugin-aomenc libheif-plugin-libde265 libheif1 libhpmud0
  libhunspell-1.7-0 libhwy1t64 libhyphen0 libibus-1.0-5 libice-dev libicu-dev libid3tag0 libiec61883-0 libieee1284-3t64 libimagequant0 libimath-3-1-29t64 libinput-bin libinput10 libisoburn1t64 libisofs6t64 libjack-jackd2-0
  libjavascriptcoregtk-4.1-0 libjavascriptcoregtk-6.0-1 libjbig2dec0 libjxl0.7 libjxr-tools libjxr0t64 liblapack3 libliftoff0 liblilv-0-0 liblirc-client0t64 liblouisutdml-bin liblouisutdml-data liblouisutdml9t64 liblqr-1-0
  libmalcontent-0-0 libmanette-0.2-0 libmbedcrypto7t64 libmd4c0 libmediaart-2.0-0 libmhash2 libminiupnpc17 libmozjs-115-0t64 libmpdclient2t64 libmsgraph-0-1 libmspub-0.1-1 libmtdev1t64 libmtp-common libmtp-runtime libmtp9t64
  libmwaw-0.3-3 libmysofa1 libmythes-1.2-0 libnatpmp1t64 libnautilus-extension4 libnetpbm11t64 libnfs14 libnma-common libnorm1t64 libodfgen-0.1-1 libopenexr-3-1-30 libopengl0 libopenjp2-7 libopenmpt0t64 liborcus-0.18-0
  liborcus-parser-0.18-0 libpagemaker-0.0-0 libpaper-utils libpaper1 libpeas-common libpgm-5.3-0t64 libphonenumber8 libpixman-1-dev libplacebo338 libplayerctl2 libpocketsphinx3 libportal1 libpostproc57 libppd2-common libprotobuf32t64
  libpthread-stubs0-dev libpulse-mainloop-glib0 libqpdf29t64 libqqwing2v5 libqt5core5t64 libqt5dbus5t64 libqt5network5t64 libqt5positioning5 libqt5qml5 libqt5qmlmodels5 libqt5sensors5 libqt5webchannel5 librabbitmq4 libraptor2-0
  librasqal3t64 librav1e0 libraw1394-11 libraw23t64 librdf0t64 libreoffice-uiconfig-calc libreoffice-uiconfig-draw libreoffice-uiconfig-impress libreoffice-uiconfig-math libreoffice-uiconfig-writer librest-1.0-0 librevenge-0.0-0
  librist4 librsync2t64 librubberband2 librygel-core-2.8-0 librygel-db-2.8-0 librygel-renderer-2.8-0 librygel-server-2.8-0 libsane-common libsane-hpaio libseat1 libserd-0-0 libsgutils2-1.46-2 libshine3 libsigc++-3.0-0 libsm-dev
  libsnappy1v5 libsndio7.0 libsnmp-base libsnmp40t64 libsord-0-0 libsoup-2.4-1 libsoup-gnome-2.4-1 libsoup2.4-common libsoxr0 libspdlog1.12 libspeex1 libsphinxbase3t64 libsratom-0-0 libsrt1.5-gnutls libstartup-notification0
  libsuitesparseconfig7 libsvtav1enc1d1 libswresample4 libswscale7 libtag1v5 libtag1v5-vanilla libtepl-common libthai-data libthai-dev libthai0 libtiff5 libtotem-plparser-common libtotem-plparser18 libtracker-sparql-3.0-0
  libtss2-tcti-libtpms0t64 libtss2-tcti-spi-helper0t64 libtss2-tctildr0t64 libtwolame0 libudfread0 libunibreak5 libunity-protocol-private0 libunity-scopes-json-def-desktop libunity9 libv4l-0t64 libv4lconvert0t64 libvidstab1.1
  libvisio-0.1-1 libvisual-0.4-0 libvncclient1 libvorbisfile3 libvpl2 libvpx9 libvte-2.91-common libwacom-common libwacom9 libwavpack1 libwhoopsie-preferences0 libwinpr3-3 libwlroots12t64 libwmflite-0.2-7 libwnck-3-common libwoff1
  libwpd-0.10-10 libwpg-0.3-3 libwps-0.4-4 libx11-dev libx265-199 libxau-dev libxcb-composite0 libxcb-damage0 libxcb-ewmh2 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-render0 libxcb-render0-dev libxcb-res0
  libxcb-shape0 libxcb-shm0-dev libxcb-util1 libxcb-xinerama0 libxcb-xinput0 libxcb-xv0 libxcb1-dev libxcomposite1 libxcvt0 libxdamage1 libxdmcp-dev libxext-dev libxinerama1 libxkbregistry0 libxklavier16 libxmlsec1t64 libxmlsec1t64-nss
  libxrender-dev libxres1 libxslt1.1 libxss-dev libxss1 libxt-dev libxv1 libxvidcore4 libxvmc1 libxxf86dga1 libyuv0 libzimg2 libzix-0-0 libzmq5 libzvbi-common libzvbi0t64 lp-solve media-player-info mobile-broadband-provider-info netpbm
  network-manager-openvpn ocl-icd-libopencl1 p11-kit p11-kit-modules pipewire-alsa pipewire-audio pocketsphinx-en-us power-profiles-daemon printer-driver-postscript-hp python3-apport python3-aptdaemon python3-brlapi python3-cups
  python3-cupshelpers python3-dateutil python3-debconf python3-defer python3-fasteners python3-ibus-1.0 python3-louis python3-mako python3-markupsafe python3-monotonic python3-olefile python3-problem-report python3-requests
  python3-speechd python3-xdg qttranslations5-l10n remmina-common rhythmbox-data rygel sane-airscan sgml-data sound-theme-freedesktop sway-backgrounds switcheroo-control system-config-printer-udev tcl-dev tcl8.6-dev toilet toilet-fonts
  totem-common tracker transmission-common ubuntu-advantage-desktop-daemon ubuntu-mono update-notifier-common usb-creator-common webp-pixbuf-loader whoopsie-preferences x11-session-utils x11proto-dev xbitmaps xbrlapi xcvt
  xdg-dbus-proxy xfonts-encodings xinit xinput xorg-sgml-doctools xorriso xtrans-dev yelp-xsl zenity-common
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
  foomatic-filters
Recommended packages:
  ghostscript paps | cups | enscript | a2ps poppler-utils colord
The following packages will be REMOVED:
  aisleriot* apport-gtk* baobab* bluez-cups* caca-utils* chafa* cheese* colord* cups* cups-browsed* cups-core-drivers* cups-filters* cups-filters-core-drivers* deja-dup* eog* evince* evolution-data-server* file-roller* fontconfig*
  fonts-urw-base35* foot* gcr* gcr4* gdm3* gedit* ghostscript* gir1.2-adw-1* gir1.2-amtk-5* gir1.2-atspi-2.0* gir1.2-freedesktop* gir1.2-freedesktop-dev* gir1.2-gnomebg-4.0* gir1.2-gtk-3.0* gir1.2-gtk-4.0* gir1.2-gtksource-300*
  gir1.2-handy-1* gir1.2-harfbuzz-0.0* gir1.2-mutter-14* gir1.2-nma4-1.0* gir1.2-pango-1.0* gir1.2-peas-1.0* gir1.2-rb-3.0* gir1.2-rsvg-2.0* gir1.2-tepl-6* gir1.2-totem-1.0* gir1.2-vte-2.91* gir1.2-webkit-6.0* gir1.2-webkit2-4.0*
  gir1.2-webkit2-4.1* gir1.2-wnck-3.0* git-all* git-gui* gitk* gjs* gkbd-capplet* globalprotect* gnome-bluetooth* gnome-bluetooth-sendto* gnome-calculator* gnome-calendar* gnome-characters* gnome-control-center* gnome-disk-utility*
  gnome-font-viewer* gnome-keyring* gnome-logs* gnome-mahjongg* gnome-mines* gnome-online-accounts* gnome-power-manager* gnome-remote-desktop* gnome-session-bin* gnome-session-canberra* gnome-settings-daemon* gnome-shell*
  gnome-startup-applications* gnome-sudoku* gnome-system-monitor* gnome-terminal* gnome-themes-extra* gnome-user-docs* gnome-video-effects* google-chrome-stable* grimshot* grub-common* grub-efi-amd64* grub-efi-amd64-bin*
  grub-efi-amd64-signed* grub-pc* grub-pc-bin* grub2-common* gstreamer1.0-clutter-3.0* gstreamer1.0-gtk3* gstreamer1.0-libav* gstreamer1.0-plugins-base* gstreamer1.0-plugins-good* gstreamer1.0-pulseaudio* gstreamer1.0-x*
  gtk2-engines-murrine* gtk2-engines-pixbuf* gvfs-backends* hplip* ibus* ibus-data* ibus-gtk* ibus-gtk3* ibus-gtk4* ibus-table* imagemagick* imagemagick-6.q16* language-selector-gnome* libadwaita-1-0* libasound2-plugins* libass9*
  libatk-wrapper-java* libatk-wrapper-java-jni* libavahi-ui-gtk3-0* libavcodec60* libavfilter9* libavformat60* libayatana-appindicator3-1* libayatana-ido3-0.4-0* libayatana-indicator3-7* libbluray2* libc-devtools*
  libcairo-gobject-perl* libcairo-gobject2* libcairo-perl* libcairo-script-interpreter2* libcairo2* libcairo2-dev* libcairomm-1.0-1v5* libcairomm-1.16-1* libcanberra-gtk3-0t64* libcanberra-gtk3-module* libcheese-gtk25* libcheese8*
  libclutter-1.0-0* libclutter-gst-3.0-0* libclutter-gtk-1.0-0* libcogl-pango20* libcogl-path20* libcogl20* libcolord-gtk4-1t64* libcupsfilters2t64* libdbusmenu-gtk3-4* libdecor-0-plugin-1-gtk* libedataserverui-1.2-4t64*
  libedataserverui4-1.0-0t64* libevdocument3-4t64* libevview3-3t64* libfcft4t64* libfontconfig-dev* libfontconfig1* libfontconfig1-dev* libfreerdp-client3-3* libfreerdp-server3-3* libfreerdp3-3* libfreetype-dev* libfreetype6*
  libgail-common* libgail18t64* libgcr-ui-3-1* libgd3* libgedit-amtk-5-0* libgedit-gtksourceview-300-0* libgjs0g* libgnome-bg-4-2t64* libgnome-bluetooth-ui-3.0-13* libgnome-desktop-3-20t64* libgnome-games-support-1-3*
  libgnome-rr-4-2t64* libgnomekbd8* libgoa-backend-1.0-2* libgphoto2-6t64* libgs10* libgs10-common* libgspell-1-2* libgtk-3-0t64* libgtk-3-bin* libgtk-4-1* libgtk-4-bin* libgtk-4-media-gstreamer* libgtk-layer-shell0* libgtk2.0-0t64*
  libgtk2.0-bin* libgtk3-perl* libgtkmm-3.0-1t64* libgtkmm-4.0-0* libgtksourceview-5-0* libgxps2t64* libhandy-1-0* libharfbuzz-cairo0* libharfbuzz-dev* libharfbuzz-gobject0* libharfbuzz-icu0* libharfbuzz-subset0* libharfbuzz0b*
  libimlib2t64* libmagickcore-6.q16-7-extra* libmagickcore-6.q16-7t64* libmagickwand-6.q16-7t64* libmutter-14-0* libnma-gtk4-0* libnma0* libpango-1.0-0* libpango1.0-0* libpango1.0-dev* libpangocairo-1.0-0* libpangoft2-1.0-0*
  libpangomm-1.4-1v5* libpangomm-2.48-1t64* libpangoxft-1.0-0* libpeas-1.0-0* libpoppler-cpp0t64* libpoppler-glib8t64* libpoppler118* libpoppler134* libportal-gtk3-1* libppd2* libqt5gui5t64* libqt5printsupport5t64* libqt5quick5*
  libqt5svg5* libqt5webkit5* libqt5widgets5t64* libraqm0* libreoffice-base-core* libreoffice-calc* libreoffice-core* libreoffice-draw* libreoffice-gnome* libreoffice-gtk3* libreoffice-impress* libreoffice-math* libreoffice-pdfimport*
  libreoffice-writer* librhythmbox-core10* librsvg2-2* librsvg2-common* libsane1* libshout3* libspectre1* libtepl-6-4* libtheora0* libtk8.6* libtotem0* libvte-2.91-0* libwebkit2gtk-4.0-37* libwebkit2gtk-4.1-0* libwebkitgtk-6.0-4*
  libwmf-0.2-7* libwmf-0.2-7-gtk* libwmf0.2-7-gtk* libwnck-3-0* libxfont2* libxft-dev* libxft2* libyelp0* memtest86+* mousetweaks* mutter-common-bin* nautilus-extension-gnome-terminal* network-manager-gnome*
  network-manager-openvpn-gnome* network-manager-pptp-gnome* notification-daemon* openjdk-8-jdk* openjdk-8-jdk-headless* openjdk-8-jre* openjdk-8-jre-headless* orca* os-prober* pango1.0-tools* pavucontrol* pinentry-gnome3*
  plymouth-label* plymouth-theme-spinner* policykit-1-gnome* poppler-utils* printer-driver-c2esp* printer-driver-hpcups* printer-driver-pnm2ppa* printer-driver-ptouch* printer-driver-sag-gdi* printer-driver-splix*
  python3-aptdaemon.gtk3widgets* python3-cairo* python3-gi-cairo* python3-pil* python3-uno* qt5-gtk-platformtheme* remmina* remmina-plugin-rdp* remmina-plugin-secret* remmina-plugin-vnc* rhythmbox* rhythmbox-plugin-alternative-toolbar*
  rhythmbox-plugins* sane-utils* seahorse* shim-signed* simple-scan* slurp* software-properties-gtk* spice-vdagent* sway* swaybg* swaylock* system-config-printer* system-config-printer-common* tecla* tk* tk-dev* tk8.6* tk8.6-dev*
  totem* totem-plugins* tracker-extract* tracker-miner-fs* transmission-gtk* ubuntu-docs* ubuntu-release-upgrader-gtk* ubuntu-session* update-manager* update-notifier* usb-creator-gtk* w3m-img* waybar* wmenu* wofi* x11-apps* x11-utils*
  xdg-desktop-portal-gtk* xdg-user-dirs-gtk* xfonts-base* xfonts-scalable* xfonts-utils* xorg* xserver-xephyr* xserver-xorg* xserver-xorg-core* xserver-xorg-input-all* xserver-xorg-input-libinput* xserver-xorg-input-wacom*
  xserver-xorg-video-all* xserver-xorg-video-amdgpu* xserver-xorg-video-ati* xserver-xorg-video-fbdev* xserver-xorg-video-intel* xserver-xorg-video-nouveau* xserver-xorg-video-qxl* xserver-xorg-video-radeon* xserver-xorg-video-vesa*
  xserver-xorg-video-vmware* xvfb* xwayland* yaru-theme-gtk* yelp* zenity*
The following NEW packages will be installed:
  foomatic-filters
WARNING: The following essential packages will be removed.
This should NOT be done unless you know exactly what you are doing!
  shim-signed grub-efi-amd64-signed (due to shim-signed) grub2-common (due to shim-signed)
0 upgraded, 1 newly installed, 360 to remove and 0 not upgraded.
Need to get 92,2 kB of archives.
After this operation, 1.709 MB disk space will be freed.
Do you want to continue? [Y/n] n
Abort.

Is there any way to remove grub without removing other packages too?

@gdamjan
Copy link
Author

gdamjan commented Nov 15, 2024

omit libfreetype6 from the list of packages to remove

ps.
this gist was for a headless server

@mangkoran
Copy link

@gdamjan Thank you that fixed it. Is libfreetype6 intended to be removed (based on your gist)?

@Novantric
Copy link

Novantric commented May 22, 2025

Thanks! Just installing the packages worked flawlessly on 25.04, and after that I was able to purge and hold grub2 without issue (aside from libfreetype6 as mentioned above).
Any way to get secure boot working?

@txhammer68
Copy link

txhammer68 commented May 23, 2025 via email

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