Getting rid of Grub

This is similar to a “normal” Fedora installation and pretty straight forward.

Before you try this make sure you have a backup of any data before you
start. Playing with the boot loader can bring you very easily in the situation
that your PC refuses to start. Of course you also should have a rescue USB
stick ready so you can do fixes when it really comes to this.

I just want to keep a note here in case anyone comes up with the same
question: how can I get rid of grub?

To be one the safe side first thing I did was to replace all symbolic
links in /boot with copy of the corresponding files.

Then make a tarball of the content of /boot and safe this somewhere
(e.g. in /root).

Next step is to format the partitions which where /boot and /boot/efi
with vfat (mkfs.vfat). The original efi partition which has been /boot/efi
will no longer be used.

You should not forget to check in /dev/disk/by-uuid for your new uuid
of /boot. You can copy your /boot/efi entry in /etc/fstab and change
/boot/efi to /boot and put your new UUID for /boot there. Comment out
your original /boot/efi entry and also you original /boot entry.

So you will have a new boot entry with vfat and the new UUID and no
/boot/efi entry any longer.

Now you should use parted or fdisk to unset the boot flag on the original
efi partiion and set in on the boot partition. You can also change the names
if you like. As already said the original efi partition will no longer be used.

Back in you /boot partition untar your saved boot tar file so you have
all your files back in /boot.

It is very important that you now move your efi directory. In the original
layout in was placed in /boot/efi/EFI because /boot/efi was a mount point.

cd /boot
mv efi efi.x
mv efi.x/EFI .
rm -rf efi.x

All EFI stuff is now in /boot/EFI.

Now we have a vfat formatted boot partition without any extra efi partition.
This also means that the kernel and the initial ramdisk are on a vfat
partition which is readable by your UEFI.

For a test you can boot your PC now and grub will come up. After the
described steps I got an error message and the hint I should press a key.
Press any key and the installation will start up will continue.

Next step is to install systemd-boot. This is done simply by

bootctl install

All relevant EFI stuff is now in /boot/EFI/systemd.

If you boot your PC at this point you will have to disable Secure boot
because systemd-boot cannot handle signed binaries as it is able with grub.
This is due to the fact that the kernel is started by the UEFI directly.

In order to fix that we need to apply the secure boot system of the
Linux Foundation which was presented in Februrary 2013 by James Bottomley.

https://blog.hansenpartnership.com/linux-foundation-secure-boot-system-released/

Download PreLoader.efi and HashTool.efi and put them into
/boot/EFI/systemd.

cd /boot/EFI/systemd
mv systemd-bootx64.efi loader.efi
cp PreLoader.efi systemd-bootx64.efi

As you can see from this PreLoader.efi will act as systemd-bootx64.efi.
Then loader.efi (the original systemd-bootx64.efi) is loaded.

PreLoader.efi is signed by Microsoft and will start with Secure Boot.

Now you can start your PC. You will see a “blue screen” telling you
that you need to do hash enrollment. First you have to sign loader.efi.
After this you have to sign your kernel (/boot/ostree/fedora-…/vmlinuz-…).

For each new kernel you will get you have to repeat this and do the
enrollment with HashTool.

BTW: if you for some reason want to remove your MokList you can enter
and EFI shell and do

dmpstore -d MokList

This solution still does not deal with signed binaries like grub but
since you manually have to add a hash into the MokList with the HashTool
you prevent your systems to startup binaries you have not agreed to.
Nobody who has not physical access to your system can use your HashTool.

Of course it is a matter of taste but I prefer to see the boot menu
and also have a timeout so you can activate the correspondent lines
in /boot/loader/loader.conf.

Booting now will even work with activated Secure Boot.

This seems to me much simpler than all these complicated grub configurations
with several stages.

1 Like

Well as awesome as this is, IIRC OSTree doesn’t support placing kernels on a fat partition, so you’ll now be unable to run an upgrade…

It refuses to update because of the file system? What concept is that?

It’s not quite that simple, basically OSTree will try to do stuff like set the permissions on the kernel for security reasons, but chmod isn’t supported on fat32, therefore your next kernel update will likely fail.

I kind of want to make a PR to fix it since it’s not super tricky and I don’t like GRUB, but I haven’t found the time yet.

3 Likes

I have reconfigured my system back to grub. I don’t understand why it is used instead of systemd-boot but perhaps it is because of secure boot.

rpm-ostree is not working anymore.

[root@bat ~]# rpm-ostree status
error: Timeout was reached

Could you try journalctl -u rpm-ostreed -b -e?

I think ostree came out before gummiboot became systemd-boot, so it could partly just be that at the time it made more sense.

I have already done another reinstallation.

My last command was “ostree admin cleanup” before I rebooted my PC and it refused to start because ostree did not start.

This ostree stuff is completely new to me and I have no idea how to debug or fix it.

The whole thing was about getting rid of grub and obviously this did not work.

I have now some kind of parallel installation of grub and systemd-boot but the latter is not really usable because I don’t see a good way to maintain it.

I created some loader file like this:

title Fedora 30 (5.0.17)
machine-id 0c7ef96f9e934c259738840ef39fdbef
linux /0c7ef96f9e934c259738840ef39fdbef/vmlinuz-5.0.17-300.fc30.x86_64
initrd /0c7ef96f9e934c259738840ef39fdbef/initramfs-5.0.17-300.fc30.x86_64.img
options resume=/dev/mapper/fedora-swap rd.lvm.lv=fedora/root rd.lvm.lv=fedora/swap rd.luks.uuid=luks-6cf16b77-a720-48ef-b734-47f4ffe4c288 root=/dev/mapper/fedora-root ostree=/ostree/boot.0/fedora/8150f1d4dfd6f83fbb5b9ea391455543c40c72242cecd4d7774ef96a04a81fd2/0

As you can see this contains this long ostree number. I put kernel and initrd on this small efi partition (which is ok for just one pair of them) but I consider it only as some test that this would work.

From my point of view it looks like that systemd-boot is not really supported by Fedora (maybe because secure boot does not work with signed binaries).

This means I have to correct myself: we can not get rid of the volume and directory layout given by Fedora.

We have to work with /boot/efi/EFI/systemd. The /boot partition has to be xfs (or ext4 if you prefer this) and /boot/efi is vfat.

For maintenance something like this should do for the beginning.

Configure your own LUKS_UUID or adapt the script to your scenario. In my case I use LVM on LUKS.

#!/bin/bash
# write-ostree-boot-config.sh

# --- configure this -------------------------------------------------------
MAX_DEPLOY=1 # works only with 1 at the moment
LUKS_UUID='6cf16b77-a720-48ef-b734-47f4ffe4c288'
# -------------------------------------------------------------------------

ARCH=$(uname -m)
ID=$(cat /etc/machine-id)

if [[ ! ${ID:0:1} =~ [0-9,a-z] ]]
then
  echo 'machine-id not correct'
  exit 1
fi

if [[ ! -d /boot/efi/${ID} ]]
then
  mkdir /boot/efi/${ID}
fi

# find current boot number
BOOT=$(find /ostree/ -maxdepth 1 -type l | grep boot)
BOOT_NUM_ORG=${BOOT##*.}

# find latest deployment and corresponding ostree boot
# currently we take only the latest deployment
DEPLOY_LIST=''
DEPLOY_BASE_DIR='/ostree/deploy/fedora/deploy'
DEPLOY_LIST_FILES=$(ls -t ${DEPLOY_BASE_DIR}/*.origin)

for d_elt_tmp in ${DEPLOY_LIST_FILES}
do
  d_elt_tmp2=${d_elt_tmp%.origin}
  d_elt=${d_elt_tmp2##*/}
  DEPLOY_LIST="${DEPLOY_LIST} $d_elt"
done

deploy_counter=0;

for dp in ${DEPLOY_LIST}
do
  deploy_counter=$((deploy_counter+1))
  if [[ $deploy_counter -gt ${MAX_DEPLOY} ]]
  then
    break
  fi

  KERNEL_DP=$(ls ${DEPLOY_BASE_DIR}/${dp}/usr/lib/ostree-boot/vmlinuz*)
  INITRD_DP=$(ls ${DEPLOY_BASE_DIR}/${dp}/usr/lib/ostree-boot/initramfs*)
done

KERNEL_DP_BASE=$(basename ${KERNEL_DP})
OSTREE_CURRENT=${KERNEL_DP_BASE##*-}
FEDORA_KERNEL_DIR=/boot/ostree/fedora-${OSTREE_CURRENT}
k_tmp=${KERNEL_DP_BASE##*vmlinuz-}
VER_LIST=${k_tmp%-${OSTREE_CURRENT}}
VER=${VER_LIST}

# swap boot number after new deployment
if [[ -d $FEDORA_KERNEL_DIR ]]
then
  BOOT_NUM=${BOOT_NUM_ORG}
else
  if [[ ${BOOT_NUM_ORG} -eq 0 ]]
  then
    BOOT_NUM=1
  elif [[ ${BOOT_NUM_ORG} -eq 1 ]]
  then
    BOOT_NUM=0
  else
    BOOT_NUM=${BOOT_NUM_ORG}
    echo "WARNING: ${BOOT_NUM} is neither 0 or 1. \
This is unexpected and will probably go wrong."
  fi
fi

OSTREE_BOOT_DIR=/ostree/boot.${BOOT_NUM}/fedora/${OSTREE_CURRENT}/0

cd /boot/efi/${ID}

if [[ $? -ne 0 ]]
then
   echo "cannot enter /boot/efi/${ID}";
   exit 1
fi

# check which version we have in the EFI partition
# remove those we don't have in /boot/ostree
EXISTING_VERSIONS=$(ls)

for EXISTING_VERSION in ${EXISTING_VERSIONS}
do
  version_found=0
  for VER in ${VER_LIST}
  do
    if [[ "${EXISTING_VERSION}" == "${VER}" ]]
    then
      version_found=1
    fi
   done

  if [[ $version_found == 0 ]]
  then
    echo "removing ${EXISTING_VERSION}"
    rm -rf ${EXISTING_VERSION}
  fi
done

KERNEL_DIRS=fedora-${OSTREE_CURRENT}

for KERNEL_DIR in ${KERNEL_DIRS}
do
   OPTIONS="resume=/dev/mapper/fedora-swap \
rd.lvm.lv=fedora/root \
rd.lvm.lv=fedora/swap \
rd.luks.uuid=luks-${LUKS_UUID} \
root=/dev/mapper/fedora-root \
ostree=${OSTREE_BOOT_DIR} \
rhgb quiet"

  cd /boot/efi

  if [[ $? -ne 0 ]]
  then
    echo "cannot enter /boot/efi"
    exit 1
  fi

  rm -f loader/entries/${ID}-[1-9]*.conf

  ENTRY=loader/entries/${ID}-${VER}.conf

  mkdir -p ${ID}/${VER}

  KERNEL_TARGET=${ID}/${VER}/linux
  INITRD_TARGET=${ID}/${VER}/initrd

  if [[ -f ${KERNEL_TARGET} ]]
  then
    echo "${KERNEL_TARGET} already exists"
  else
    cp ${KERNEL_DP} ${KERNEL_TARGET}
  fi

  if [[ -f ${INITRD_TARGET} ]]
  then
    echo "${INITRD_TARGET} already exists"
  else
    cp ${INITRD_DP} ${INITRD_TARGET}
  fi

  cat <<EOF > ${ENTRY}
title      ${VER}
version    ${VER}
machine-id ${ID}
options    ${OPTIONS}
linux      /${KERNEL_TARGET}
initrd     /${INITRD_TARGET}
EOF
done

Any progress since then? Wanted to remove Grub too in favor of systemd-boot.
I don’t need secure boot so it should be simpler.
But I still wanted to keep kernel upgrades…

Please help. Let’s at least file issue on this or something…

1 Like

@fansari Thanks for the instruction!
But I don’t see you actually removing grub, can we do it also?

Also, can I just use EFI ESP for your setup?

This script was an attempt from me to use systemd-boot on Fedora Silverblue. I am using it since months now but it has its drawbacks.

It never failed so far on a single “rpm-ostree upgrade” command and afterwards running this script.

But when you install/uninstall rpm packages sometimes there is this change from /ostree/boot.0 to /ostree/boot.1 or vice versa and I have no idea how to predict what it will use after reboot. I put some swap logic into this script but this does not cover all cases.

I raised the question here:

Somebody should explain to me how I can know before reboot whether this number will be 0 and 1. Then I can update my script.

So far I often end up with a black screen and have to go into the BIOS and use grub again and fix this number. Once booted by grub you don’t even have to fix the loader entry manually: you can just run this script and the number will be correct. Once this is done I can use efibootmgr to go back to systemd-boot.

And you are right: this is not a removal of grub. I use both in parallel - grub only as fallback for the situation described above.

Also I have learned that it is not possible to remove the partition layout to a /boot with vfat and no extra efi partion (just normal directory). Fedora Silverblue becomes unusable with this.

As a workaround I make /boot/efi large enough for kernel and initrd (1GB , same as /boot).

So for now the script needed even for non-encrypted setup?
Will it be the case when OSTree gets systemd-boot support?

What exactly happened?
I’m going to try make /boot as BTRFS subvolume at least. Will it work?

The only task of this script is to provide you with some useful .conf file in /boot/efi/loader/entries. If you don’t use LVM on LUKS but LUKS on LVM or no encryption alt all you might adapt the script to your needs.

What will happen if you change to layout is that you will not be able to make updates anymore. As refi64 wrote it does not work. I can confirm this. I had to reinstall my system after trying this. You have to stick to fhe layout scheme given by Fedora Silverblue. You might of course use a greater size of /boot/efi than suggested.

Can I reproduce it somehow? I’m on VM so can freely try.
Maybe OSTree just doesn’t work with VFAT but if POSIX fs is provided it doesn’t really matters?

Well, I tried it with BTRFS, seems no problems so far.

Next step is to try it with BTRFS subvolume :wink:

UPDATE: no problems also. Need to check the updates…

Tried to replace Grub with systemd-boot and SB 33.
I’ve been trying this extensively but systemd-boot can never find (bootctl command finds it)
the kernel. When you select in systemd-boot the entry it shows error loading \path\kernel no such file or directory…

Damian,

I don’t currently have the know-how or the time to test this - will try soon - but something I’ve been interested in for a while is using /efi as it’s own partition.

Arch has a guide that recommends this; I’m curious if it will solve the woes of systemd-boot with Silverblue. Below is the bootctl line and the link, check it out:

bootctl --esp-path=/efi --boot-path=/boot install

https://wiki.archlinux.org/index.php/Systemd-boot