Page MenuHomeFreeBSD

D19588.id55089.diff
No OneTemporary

D19588.id55089.diff

Index: usr.sbin/efi-update-loader/efi-update-loader.8
===================================================================
--- /dev/null
+++ usr.sbin/efi-update-loader/efi-update-loader.8
@@ -0,0 +1,68 @@
+\"
+.\" Copyright (c) 2019 Rebecca Cran <bcran@freebsd.org>.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 12, 2019
+.Dt EFI-UPDATE-LOADER 8
+.Os
+.Sh NAME
+.Nm efi-update-loader
+.Nd Update an EFI System Partition with a FreeBSD loader
+.Sh SYNOPSIS
+.Nm
+.Op Fl d Ar device
+.Op Fl l Ar loader
+.Sh DESCRIPTION
+This program updates the
+.Dq Unified Extensible Firmware Interface
+.Pq UEFI
+.Dq EFI System Partition
+.Pq ESP
+with a new FreeBSD loader.efi file.
+
+The ESP is a FAT12, FAT16 or FAT32 filesystem that is used by the UEFI system
+firmware to load and run OS boot loaders that are compiled as
+.Dq Portable Executable
+.Pq PE
+binaries. The UEFI Boot Manager, which can be configured with the
+.Xr efibootmgr 8
+utility, contains entries which point to the location of the boot loader
+within the ESP.
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl d Ar device
+Specify the device to use as the ESP.
+.It Fl l Ar loader
+Specify the file to install as the FreeBSD boot loader. This should normally
+be /boot/loader.efi, but could also for example be /boot/loader_4th.efi etc.
+.Sh SEE ALSO
+.Xr efibootmgr 8 ,
+.Xr efivar 8
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 13.0
Index: usr.sbin/efi-update-loader/efi-update-loader.sh
===================================================================
--- /dev/null
+++ usr.sbin/efi-update-loader/efi-update-loader.sh
@@ -0,0 +1,212 @@
+#!/bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright (c) 2019 Rebecca Cran <bcran@FreeBSD.org>.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+set -e
+
+get_uefi_bootname() {
+
+ case ${TARGET:-$(uname -m)} in
+ amd64) echo bootx64 ;;
+ arm64) echo bootaa64 ;;
+ i386) echo bootia32 ;;
+ arm) echo bootarm ;;
+ *)
+ echo "machine type $(uname -m) doesn't support UEFI"
+ exit 1
+ ;;
+ esac
+}
+
+
+clean_up() {
+ if [ -z "${mntpt}" ]; then
+ exit 1
+ fi
+
+ if mount | grep -q "${mntpt}" ; then
+ umount "${mntpt}"
+ fi
+
+ if [ -d "${mntpt}" ]; then
+ rmdir "${mntpt}"
+ fi
+}
+
+
+bootefi_is_freebsd() {
+ efibootname=$(get_uefi_bootname)
+
+ if [ -f "${mntpt}/efi/boot/${efibootname}.efi" ]; then
+ boot1asbootefi=$(grep "FreeBSD EFI boot block" "${mntpt}/efi/boot/${efibootname}.efi") || true
+ if [ -n "${boot1asbootefi}" ]; then
+ echo "true"
+ fi
+ fi
+}
+
+
+get_freespace_on_esp() {
+ df -k "${mntpt}" | tail -1 | awk '{print $4}'
+}
+
+
+copyloader() {
+ mntpt=$(mktemp -d /tmp/esp.XXXXXX)
+
+ mount -t msdosfs "$espdev" "${mntpt}"
+
+ ldrsize=$(stat -f %z "${loader}")
+ # Convert to KB
+ ldrsize=$((ldrsize / 1024))
+
+ efibootname=$(get_uefi_bootname)
+
+ if [ ! -d "${mntpt}/EFI" ]; then
+ mkdir "${mntpt}/EFI"
+ fi
+
+ if [ ! -d "${mntpt}/EFI/FreeBSD" ]; then
+ mkdir "${mntpt}/EFI/FreeBSD"
+ fi
+
+ if [ -n "$(bootefi_is_freebsd)" ]; then
+
+ echo "Moving FreeBSD bootx64.efi to /EFI/FreeBSD/${efibootname}-old.efi"
+ mv "${mntpt}/EFI/BOOT/${efibootname}.efi" "${mntpt}/EFI/FreeBSD/${efibootname}-old.efi"
+ fi
+
+ if [ -f "${mntpt}/EFI/FreeBSD/loader.efi" ]; then
+ existing_ldr_size=$(stat -f %z "${mntpt}/EFI/FreeBSD/loader.efi")
+ existing_ldr_size=$((existing_ldr_size / 1024))
+ fi
+
+ if [ -f "${mntpt}/efi/freebsd/loader.efi" ] && ! cmp -sz "${loader}" "${mntpt}/efi/freebsd/loader.efi"; then
+ # Check we have enough free space
+ if [ ! -e "${mntpt}/EFI/FreeBSD/loader-old.efi" ] && [ $(($(get_freespace_on_esp))) -lt ${existing_ldr_size} ] ; then
+ echo "Insufficient space on ESP to back up loader.efi; skipping backup"
+ else
+ echo "Backing up /EFI/FreeBSD/loader.efi to /EFI/FreeBSD/loader-old.efi"
+ cp "${mntpt}/EFI/FreeBSD/loader.efi" "${mntpt}/EFI/FreeBSD/loader-old.efi"
+ fi
+ fi
+
+ if [ -e "${mntpt}/EFI/FreeBSD/loader.efi" ]; then
+ spaceneeded=$((existing_ldr_size - ldrsize))
+ else
+ spaceneeded=${ldrsize}
+ fi
+
+ if [ $(($(get_freespace_on_esp))) -lt ${spaceneeded} ]; then
+ echo "Error: Insufficient space on ESP ${espdev} to install ${loader}."
+ eval clean_up
+ exit 1
+ fi
+
+ echo "Copying ${loader} to /EFI/FreeBSD/loader.efi"
+ cp "${loader}" "${mntpt}/EFI/FreeBSD/loader.efi"
+
+ if ! efibootmgr -v | grep -qi "EFI/FreeBSD/loader.efi" ; then
+ echo "Boot Option for FreeBSD doesn't exist: it's recommended to run efibootmgr. e.g.:"
+ echo " efibootmgr -c -a -L FreeBSD -l /mnt/EFI/FreeBSD/loader.efi"
+ fi
+
+ umount "${mntpt}"
+ rmdir "${mntpt}"
+}
+
+
+usage() {
+ printf 'usage: %s -d [espdev] -l [loader]\n' "${progname}"
+ printf '\t-d ESP device\n'
+ printf '\t-l FreeBSD EFI loader\n'
+ exit 0
+}
+
+
+progname=$0
+loader=/boot/loader.efi
+espdev=
+
+while getopts "d:l:h" opt; do
+ case "$opt" in
+ d)
+ espdev=${OPTARG}
+ ;;
+ l)
+ loader=${OPTARG}
+ ;;
+ ?)
+ usage
+ ;;
+ esac
+done
+
+trap clean_up 1 2 15 EXIT
+
+if [ -z "${espdev}" ]; then
+
+ mntpt=$(mktemp -d /tmp/esp.XXXXXX)
+
+ for disk in $(sysctl -n kern.disks); do
+ espindexes=$(gpart show "${disk}" 2> /dev/null | grep efi | awk '{print $3}')
+ for idx in ${espindexes}; do
+ if [ -e "/dev/${disk}p${idx}" ]; then
+ dev=/dev/${disk}p${idx}
+ elif [ -e "/dev/${disk}s${idx}" ]; then
+ dev=/dev/${disk}s${idx}
+ fi
+
+ if mount -t msdosfs "${dev}" "${mntpt}" 2> /dev/null ; then
+
+ if [ -n "$(bootefi_is_freebsd)" ] || [ -e "${mntpt}/efi/freebsd/loader.efi" ]; then
+ espdev=${dev}
+ echo "Found FreeBSD ESP device ${espdev}"
+ fi
+
+ umount "${mntpt}"
+ fi
+ done
+ done
+
+ rmdir "${mntpt}"
+
+ if [ -z "${espdev}" ]; then
+ echo "Error: could not detect ESP containing FreeBSD loader to update"
+ exit 1
+ fi
+fi
+
+if [ -z "${espdev}" ]; then
+ eval usage
+ exit 1
+fi
+
+eval copyloader "${espdev}" "${loader}"
+
+trap 1 2 15 EXIT

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 19, 10:46 AM (15 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25621501
Default Alt Text
D19588.id55089.diff (8 KB)

Event Timeline