Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136578340
D19588.id55089.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D19588.id55089.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D19588: Add a new efi-update-loader script and associated man page
Attached
Detach File
Event Timeline
Log In to Comment