Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ AM_DISTCHECK_CONFIGURE_FLAGS = \
dist_systemdunit_DATA = \
eos-config-journal.service \
eos-enable-zram.service \
eos-ensure-sd-boot.service \
eos-firewall-localonly.service \
eos-firstboot.service \
eos-image-boot-dm-setup.service \
Expand Down Expand Up @@ -87,6 +88,7 @@ dist_polkitrules_DATA = \
dist_sbin_SCRIPTS = \
eos-config-journal \
eos-enable-zram \
eos-ensure-sd-boot \
eos-firewall-localonly \
eos-firstboot \
eos-image-boot-dm-setup \
Expand Down
70 changes: 70 additions & 0 deletions eos-ensure-sd-boot
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/bin/bash

# eos-ensure-sd-boot: Ensure systemd-boot is installed
#
# Copyright © 2023 Endless OS Foundation LLC
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

# Ensure systemd-boot is considered installed by bootctl (when
# appropriate) so that bootctl update works.

set -e
set -o pipefail

LOADER_INFO_VAR=LoaderInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
LOADER_INFO_PATH="/sys/firmware/efi/efivars/$LOADER_INFO_VAR"

# Read the LoaderInfo EFI variable.
get_loader_info() {
[ -f "$LOADER_INFO_PATH" ] || return 0

# The LoaderInfo variable is a NUL terminated UTF-16 string. The
# first 4 bytes of any EFI variable are attributes.
dd if="$LOADER_INFO_PATH" ibs=1 skip=4 status=none \
| iconv -f UTF16LE | tr -d '\0'
}

# We only use systemd-boot on x86_64. If we add any other architectures
# later, they'll install it correctly out of the box.
arch=$(uname -m)
if [ "$arch" != x86_64 ]; then
exit 0
fi

# If it's already considered installed, there's nothing to do.
if bootctl --quiet is-installed; then
exit 0
fi

# Only make changes when the boot loader is systemd-boot.
echo "Reading $LOADER_INFO_VAR EFI variable"
loader_info=$(get_loader_info)
if ! [[ $loader_info =~ ^systemd-boot ]]; then
echo "Boot loader is not systemd-boot"
exit 0
fi

# Install systemd-boot but don't touch the EFI Boot* variables since we
# assume those are already working.
echo "Installing systemd-boot"
bootctl --no-variables install

# Validate that systemd-boot is now considered installed.
if ! bootctl --quiet is-installed; then
echo "bootctl does not consider systemd-boot installed" >&2
exit 1
fi
24 changes: 24 additions & 0 deletions eos-ensure-sd-boot.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[Unit]
Description=Ensure systemd-boot is installed
DefaultDependencies=no
Conflicts=shutdown.target
Wants=local-fs.target
After=local-fs.target
Before=sysinit.target

# Run before systemd-boot-update so that it doesn't run concurrently.
Before=systemd-boot-update.service

# Only run on x86_64 UEFI as that's the only platform where systemd-boot
# is used. Any other platforms added later will install systemd-boot
# correctly out of the box.
ConditionArchitecture=x86-64
ConditionFirmware=uefi

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/eos-ensure-sd-boot

[Install]
WantedBy=sysinit.target