[packages/efi-boot-update] new package
jajcus
jajcus at pld-linux.org
Tue Oct 30 16:20:07 CET 2012
commit 7a63766af4cd8aed055e5f4881d9dd7f8485308f
Author: Jacek Konieczny <j.konieczny at eggsoft.pl>
Date: Tue Oct 30 16:19:14 2012 +0100
new package
I hope this is not useless.
README | 26 +++++
TODO | 5 +
efi-boot-update | 273 +++++++++++++++++++++++++++++++++++++++++++++++++++
efi-boot-update.spec | 67 +++++++++++++
grub.conf | 54 ++++++++++
shellx32.conf | 13 +++
shellx64.conf | 11 +++
update.conf | 3 +
xen.conf | 17 ++++
9 files changed, 469 insertions(+)
---
diff --git a/efi-boot-update.spec b/efi-boot-update.spec
new file mode 100644
index 0000000..9b3fff1
--- /dev/null
+++ b/efi-boot-update.spec
@@ -0,0 +1,67 @@
+# $Revision: 1.81 $, $Date: 2012/04/20 10:52:52 $
+#
+Summary: EFI bootloader updater
+Name: efi-boot-update
+Version: 0.1
+Release: 0.1
+License: GPL v2
+Group: Applications
+Source0: %{name}
+Source1: update.conf
+Source2: shellx64.conf
+Source3: shellx32.conf
+Source4: grub.conf
+Source10: README
+Source11: TODO
+URL: http://www.pld-linux.org/
+BuildRequires: help2man
+Suggests: efibootmgr
+BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
+
+%define _sbindir /sbin
+
+%description
+Script to update EFI bootloaders.
+
+%prep
+%setup -qcT
+cp %{SOURCE0} .
+cp %{SOURCE10} %{SOURCE11} .
+
+%build
+chmod a+x %{name}
+help2man --no-info ./%{name} > %{name}.8
+
+%install
+rm -rf $RPM_BUILD_ROOT
+install -d $RPM_BUILD_ROOT/etc/efi-boot/update.d
+install -d $RPM_BUILD_ROOT{%{_prefix}/lib{,64}/efi,%{_sbindir},%{_mandir}/man8}
+
+install %{name} $RPM_BUILD_ROOT%{_sbindir}/%{name}
+install %{name}.8 $RPM_BUILD_ROOT%{_mandir}/man8/%{name}.8
+install %{SOURCE1} $RPM_BUILD_ROOT/etc/efi-boot
+install %{SOURCE2} %{SOURCE3} %{SOURCE4} $RPM_BUILD_ROOT/etc/efi-boot/update.d
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+# Most efi-boot-update-managed loaders will use kernel files
+# even if the kernel itself is not build as EFI
+%triggerin -- kernel
+/sbin/efi-boot-update
+%triggerin -- kernel-longterm
+/sbin/efi-boot-update
+
+%files
+%defattr(644,root,root,755)
+%doc README TODO
+%attr(755,root,root) %{_sbindir}/%{name}
+%dir /etc/efi-boot
+%config(noreplace) %verify(not md5 mtime size) /etc/efi-boot/update.conf
+%config(noreplace) %verify(not md5 mtime size) /etc/efi-boot/update.d/*.conf
+%dir /etc/efi-boot/update.d
+%dir %{_libdir}/efi
+%if "%{_libdir}" != "%{_prefix}/lib"
+%dir %{_prefix}/lib/efi
+%endif
+%{_mandir}/man8/%{name}.8*
diff --git a/README b/README
new file mode 100644
index 0000000..f873e79
--- /dev/null
+++ b/README
@@ -0,0 +1,26 @@
+(U)EFI bootloaders updater
+==========================
+
+What is this for?
+-----------------
+
+(U)EFI systems boot using bootloaders on a special EFI System Partition.
+Many different bootloaders may be present at a time. These are not only
+traditional bootloaders like GRUB, but arbitrary 'EFI applications'.
+
+Xen or Linux kernel can be built as an EFI application too and booted directly
+from the EFI firmware. The problem is the kernels and data or config files
+needed for boot must be stored on the EFI System Partition, but that is not
+the place where they are installed on package upgrade. And it is hard to
+install files from RPM packages there directly.
+
+efi-boot-update script makes it easy to manage the files on the EFI system
+partition. Those files are to be installed in the regular Linux system and
+will be copied to the EFI system partition using rules defined in
+/etc/efi-boot/update.d/*.conf files.
+
+efi-boot-update will also manage EFI boot manager configuration, adding
+the configured bootloaders to the platform boot menu, provided the 'efibootmgr'
+package is installed and functional.
+
+
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..cb07a7e
--- /dev/null
+++ b/TODO
@@ -0,0 +1,5 @@
+
+TODO:
+ - complete the documentation
+ - support for boot entries for anything else that files in /boot/efi
+ - handle /dev/something0p1 partition devices
diff --git a/efi-boot-update b/efi-boot-update
new file mode 100755
index 0000000..f2095ec
--- /dev/null
+++ b/efi-boot-update
@@ -0,0 +1,273 @@
+#!/bin/sh
+
+_SCRIPT_NAME=efi-boot-update
+_SCRIPT_VERSION=0.0
+
+. /etc/rc.d/init.d/functions
+
+usage () {
+
+ echo "Usage: $0 OPTIONS"
+ echo "Update EFI boot loaders"
+ echo
+ echo " --version Show version number"
+ echo " --help, -h This help message"
+ echo " --mount, -m Try to mount /boot/efi first"
+ echo " --verbose, -v Verbose output"
+ echo " --force Force file updates"
+}
+
+msg () {
+ echo "efi-boot-update: $*" >&2
+}
+
+verbose () {
+ if is_yes "$VERBOSE" ; then
+ echo "efi-boot-update: $*" >&2
+ fi
+}
+
+verbose_cmd () {
+ if is_yes "$VERBOSE" ; then
+ echo "+$*" >&2
+ fi
+ "$@"
+}
+
+
+list_remove () {
+
+ for item in $1 ; do
+ if [ "$item" = "$2" ] ; then
+ continue
+ fi
+ echo -n "$item "
+ done
+}
+
+update_file () {
+ local cmd
+ local src
+ local dest
+ while [ -n "$1" ] ; do
+ case $1 in
+ --missingok)
+ shift
+ [ -e "$1" ] || return 0
+ ;;
+ --*)
+ msg "update_file: ignoring unknown option: $1"
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+ done
+ src="$1"; shift
+ dst="$2"; shift
+ if [ -n "$*" ] ; then
+ msg "update_file: unexpected arguments: $*"
+ return 1
+ fi
+ if [ "${dst#/}" = "${dst}" ] ; then
+ # relative path
+ dst="$DESTDIR/$dst"
+ fi
+ if is_yes "$FORCE_UPDATES" ; then
+ is_yes "$VERBOSE" && echo +cp --force --preserve=timestamps "$src" "$dst"
+ cp --force --preserve=timestamps "$src" "$dst"
+ else
+ is_yes "$VERBOSE" && echo +cp --update --preserve=timestamps "$src" "$dst"
+ cp --update --preserve=timestamps "$src" "$dst"
+ fi
+}
+
+get_efibootmgr_opts() {
+ local efi_disk
+ local efi_partnum
+ efi_disk=$(mount | awk '$3=="/boot/efi" {print $1}' 2>/dev/null)
+ EFIBOOTMGR_OPTS="--gpt"
+ if [ -n "$efi_disk" ] ; then
+ efi_partnum="$(echo $efi_disk|sed -e's;^.*[^0-9]\([0-9]\+\)$;\1;')"
+ efi_disk="$(echo $efi_disk|sed -e's;^\(.*\)[0-9]\+$;\1;')"
+ if [ -b "$efi_disk" -a -n "$efi_partnum" ] ; then
+ EFIBOOTMGR_OPTS="$EFIBOOTMGR_OPTS --disk $efi_disk"
+ EFIBOOTMGR_OPTS="$EFIBOOTMGR_OPTS --part $efi_partnum"
+ fi
+ fi
+ echo -n $EFIBOOTMGR_OPTS
+}
+
+find_bootmgr_entry () {
+
+ $EFIBOOTMGR | awk -v find="$1" '
+/^Boot[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\*?/ {
+ sub(/^Boot/,"");
+ sub(/\*/,"");
+ num=$1;
+ $1="";
+ gsub(/^[ \t]+|[ \t]+$/,"");
+ if ($0 == find) print num
+ }'
+}
+
+remove_bootmgr_entry () {
+ local bootnum
+ bootnum=$(find_bootmgr_entry "$1")
+ [ -n "$bootnum" ] || return 0
+ verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --delete-bootnum -b --quiet "$bootnum"
+ echo -n "$bootnum"
+}
+
+add_bootmgr_entry () {
+ local label=$1
+ local binary=$2
+ local args=$3
+ local bootnum
+ bootnum=$(find_bootmgr_entry "$label")
+
+ if [ "${binary#/}" = "${binary}" ] ; then
+ # relative path
+ binary="$DESTDIR/$binary"
+ fi
+ binary="${binary#/boot/efi}"
+ binary="$(echo -n "$binary"|sed -e's;/;\\;g')"
+
+ if [ -n "$bootnum" ] ; then
+ echo -n "$args" | verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet \
+ --bootnum "$bootnum" --loader "$binary" -@ -
+ else
+ echo -n "$args" | verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --create \
+ --quiet --label "$label" --loader "$binary" -@ -
+ bootnum="$(find_bootmgr_entry "$label")"
+ fi
+ echo -n "$bootnum"
+}
+
+FORCE_UPDATES="no"
+MOUNT_EFI_PARTITION="no"
+LABEL_PREFIX=""
+DEFAULT=""
+VERBOSE="no"
+
+[ -e /etc/efi-boot/update.conf ] && . /etc/efi-boot/update.conf
+
+while [ -n "$*" ] ; do
+ local arg
+ arg="$1"
+ shift
+ case $arg in
+ --help|-h)
+ usage
+ exit 0
+ ;;
+ --version)
+ echo "$_SCRIPT_NAME $_SCRIPT_VERSION"
+ exit 0
+ ;;
+ --mount|-m)
+ MOUNT_EFI_PARTITION=yes
+ ;;
+ --verbose|-v)
+ VERBOSE=yes
+ ;;
+ --force)
+ FORCE_UPDATES="yes"
+ ;;
+ *)
+ usage >&2
+ exit 2
+ ;;
+ esac
+done
+
+if ! mountpoint -q /boot/efi ; then
+ mkdir -p /boot/efi
+ if is_yes "$MOUNT_EFI_PARTITION" ; then
+ # first try via fstab
+ if ! mount /boot/efi 2>/dev/null ; then
+ local efi_device
+ efi_device="$(/sbin/blkid -o device -l -t PARTUUID="54f69bcc-954d-4f97-8fef-80b359f9e4aa")"
+ if [ -z "$efi_device" ] ; then
+ msg "EFI system partition not found."
+ exit 1
+ fi
+ mount -t vfat "$efi_device" /boot/efi
+ fi
+ fi
+ if ! mountpoint -q /boot/efi ; then
+ msg "EFI system partition not mounted."
+ exit 1
+ fi
+fi
+
+if [ -x /usr/sbin/efibootmgr ] ; then
+ modprobe -q efivars
+ EFIBOOTMGR=/usr/sbin/efibootmgr
+ if ! $EFIBOOTMGR >/dev/null 2>&1 ; then
+ msg "efibootmgr does not work (efivars interface not available?)"
+ msg "won't update boot manager configuration"
+ EFIBOOTMGR=/bin/true
+ else
+ EFIBOOTMGR_OPTS="$(get_efibootmgr_opts)"
+ fi
+else
+ msg "efibootmgr missing, won't update the boot manager configuration"
+ EFIBOOTMGR=/bin/true
+fi
+
+
+for bootloader_conf in /etc/efi-boot/update.d/*.conf ; do
+ if [ ! -e "$bootloader_conf" ] ; then
+ continue
+ fi
+ ENABLED=yes
+ CONFIG_NAME="$(basename "$bootloader_conf" .conf)"
+ LABEL="$CONFIG_NAME"
+ ARCH="$(uname -m)"
+ BINARY=""
+ ARGS=""
+ install_files() {}
+
+ . "$bootloader_conf" || continue
+
+ LABEL="$LABEL_PREFIX$LABEL"
+
+ if ! is_yes "$ENABLED" ; then
+ remove_bootmgr_entry "$LABEL"
+ continue
+ fi
+
+ DESTDIR="/boot/efi/EFI/$(echo -n "$PLATFORM_DIR"|sed -e's/@ARCH@/'"$ARCH"'/')"
+ mkdir -p "$DESTDIR"
+
+ verbose "Updating $LABEL..."
+ install_files
+ if [ -n "$BINARY" ] ; then
+ bootnum="$(add_bootmgr_entry "$LABEL" "$BINARY" "$ARGS")"
+ eval "_${CONFIG_NAME}_bootnum=\"$bootnum\""
+ fi
+done
+
+if [ -n "$ORDER" ] ; then
+ set -x
+ # set up the configured boot order, not removing any existing entries
+ tail="$(efibootmgr | awk '/^BootOrder:/ {gsub(/,/," ",$2); print $2}')"
+ head=""
+ for config_name in $ORDER ; do
+ eval "bootnum=\$_${config_name}_bootnum"
+ if [ -z "$bootnum" ] ; then
+ msg "Cannot find '$config_name' config - won't add to boot order."
+ continue
+ fi
+ tail="$(list_remove "$tail" "$bootnum")"
+ head="$head $bootnum"
+ done
+ bootorder="$(echo -n $head $tail | sed -e's/ /,/g')"
+ if [ -n "$bootorder" ] ; then
+ verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet --bootorder "$bootorder"
+ fi
+fi
+
+# vi: ft=sh sw=4 sts=4 et
diff --git a/grub.conf b/grub.conf
new file mode 100644
index 0000000..1be3694
--- /dev/null
+++ b/grub.conf
@@ -0,0 +1,54 @@
+#
+# This is disabled by default, as GRUB does good job by itself
+#
+# This is rather a proof-of-concept example how such things can be implemented
+# here.
+#
+
+ENABLED=no
+LABEL=GRUB
+ARCH=x86_64
+BINARY=grub.efi
+
+GRUB_EXTRA_MODULES=""
+
+install_files() {
+ local target
+ local module
+ local modules
+ local final_modules
+ local drive
+ local prefix
+
+ modules=""
+ modules="$modules $(/sbin/grub-probe --target=fs /boot)"
+ modules="$modules $(/sbin/grub-probe --target=abstraction /boot)"
+ modules="$modules part_$(/sbin/grub-probe --target=partmap /boot)"
+ modules="$modules search_fs_file search_fs_uuid"
+ modules="$modules $GRUB_EXTRA_MODULES"
+ drive="$(/sbin/grub-probe --target=drive /boot)"
+
+ if [ "$ARCH" = "x86_64" ] ; then
+ target="x86_64-efi"
+ else
+ target="i386-efi"
+ fi
+
+ if /bin/mountpoint -q /boot ; then
+ prefix="$drive/grub"
+ else
+ prefix="$drive/boot/grub"
+ fi
+
+ final_modules=""
+ for module in $modules ; do
+ [ -e "/lib/grub/$target/$module.mod" ] && final_modules="$final_modules $module"
+ done
+
+ is_yes $VERBOSE && set -x
+ /sbin/grub-mkimage -O "$target" -d /lib/grub/$target \
+ --output=$DESTDIR/grub.efi \
+ --prefix="$prefix" $final_modules
+}
+
+# vi: ft=sh
diff --git a/shellx32.conf b/shellx32.conf
new file mode 100644
index 0000000..49f4c9c
--- /dev/null
+++ b/shellx32.conf
@@ -0,0 +1,13 @@
+#
+# Configure a 32-bit EFI Shell as a boot option
+#
+# Note: most UEFI systems are 64-bit, so shellx64 is the right choice
+#
+# The shell can be obtained from:
+# https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/ShellBinPkg/UefiShell/Ia32/Shell.efi
+#
+# And should be manually placed at /boot/efi/EFI/SHELLX32.EFI
+#
+ENABLED=no
+LABEL="EFI Shell"
+BINARY=/EFI/SHELLX32.EFI
diff --git a/shellx64.conf b/shellx64.conf
new file mode 100644
index 0000000..00b7bfb
--- /dev/null
+++ b/shellx64.conf
@@ -0,0 +1,11 @@
+#
+# Configure an EFI Shell as a boot option
+#
+# The shell can be obtained from:
+# https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/ShellBinPkg/UefiShell/X64/Shell.efi
+#
+# And should be manually placed at /boot/efi/EFI/SHELLX64.EFI
+#
+ENABLED=yes
+LABEL="EFI Shell"
+BINARY=/EFI/SHELLX64.EFI
diff --git a/update.conf b/update.conf
new file mode 100644
index 0000000..4289c6b
--- /dev/null
+++ b/update.conf
@@ -0,0 +1,3 @@
+LABEL_PREFIX="PLD "
+ORDER="grub shellx64"
+PLATFORM_DIR="pld-linux/@ARCH@"
diff --git a/xen.conf b/xen.conf
new file mode 100644
index 0000000..5a4876d
--- /dev/null
+++ b/xen.conf
@@ -0,0 +1,17 @@
+ENABLED=yes
+LABEL="Xen native EFI"
+ARCH=x86_64
+BINARY=xen.efi
+ARGS=""
+
+install_files() {
+
+ update_file /usr/lib64/efi/xen.efi xen.efi
+ update_file /etc/efi-boot/xen.cfg xen.cfg
+
+ update_file /boot/kernel-axeos-initrd kernel-axeos-initrd
+ update_file /boot/kernel-axeos-vmlinuz kernel-axeos-vmlinuz
+
+ update_file --missingok /boot/kernel-axeos-initrd.old kernel-axeos-initrd.old
+ update_file --missingok /boot/kernel-axeos-vmlinuz.old kernel-axeos-vmlinuz.old
+}
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/efi-boot-update.git/commitdiff/7a63766af4cd8aed055e5f4881d9dd7f8485308f
More information about the pld-cvs-commit
mailing list