-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add service to ensure systemd-boot installed
On systemd-boot systems, the bootloader is updated with `bootctl update` on every boot. Unfortunately, it doesn't currently work because `bootctl` considers systemd-boot to be installed if `/EFI/systemd` is non-empty in the ESP. The image builder only populates `/EFI/BOOT`, so systemd-boot is not considered installed. If `bootctl` does not consider systemd-boot to be installed, `eos-ensure-sd-boot` will check the `LoaderInfo` EFI variable to see if the current bootloader is systemd-boot. If so, it populates `/EFI/systemd` so that the next time `bootctl update` runs, it will update the bootloader. https://phabricator.endlessm.com/T34703
- Loading branch information
1 parent
b27e2f3
commit 3469c96
Showing
3 changed files
with
101 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#!/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 is-installed --quiet; 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 | ||
|
||
# Copy the default boot loader to the systemd-boot path. bootctl | ||
# considers systemd-boot installed if EFI/systemd is non-empty. | ||
esp_path=$(bootctl --print-esp-path) | ||
default_efi="$esp_path/EFI/BOOT/BOOTX64.EFI" | ||
systemd_efi_dir="$esp_path/EFI/systemd" | ||
systemd_efi="$systemd_efi_dir/systemd-bootx64.efi" | ||
echo "Copying $default_efi to $systemd_efi" | ||
mkdir -p "$systemd_efi_dir" | ||
cp -a "$default_efi" "$systemd_efi" | ||
|
||
# Validate that systemd-boot is now considered installed. | ||
if ! bootctl is-installed --quiet; then | ||
echo "bootctl does not consider systemd-boot installed" >&2 | ||
exit 1 | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
||
# Run before systemd-boot-update so that it will apply updates if the | ||
# installation is fixed. | ||
Before=sysinit.target 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 |