3 _SCRIPT_NAME=efi-boot-update
6 . /etc/rc.d/init.d/functions
10 echo "Usage: $0 OPTIONS"
11 echo "Update EFI boot loaders"
13 echo " --version Show version number"
14 echo " --help, -h This help message"
15 echo " --mount, -m Try to mount /boot/efi first"
16 echo " --verbose, -v Verbose output"
17 echo " --force Force file updates"
18 echo " --auto Automatic run from packages %post"
22 echo -E "efi-boot-update: $*" >&2
26 if is_yes "$VERBOSE" ; then
27 echo -E "efi-boot-update: $*" >&2
32 if is_yes "$VERBOSE" ; then
42 if [ "$item" = "$2" ] ; then
53 while [ -n "$1" ] ; do
57 [ -e "$1" ] || return 0
60 msg "update_file: ignoring unknown option: $1"
71 msg "update_file: unexpected arguments: $*"
74 if [ -z "$src" ] ; then
75 msg "update_file: no source file"
78 if [ -z "$dst" ] ; then
81 if [ "${dst#/}" = "${dst}" ] ; then
85 if is_yes "$FORCE_UPDATES" ; then
86 is_yes "$VERBOSE" && echo +cp --force --preserve=timestamps "$src" "$dst"
87 cp --force --preserve=timestamps "$src" "$dst"
89 is_yes "$VERBOSE" && echo +cp --update --preserve=timestamps "$src" "$dst"
90 cp --update --preserve=timestamps "$src" "$dst"
94 get_efibootmgr_opts() {
97 efi_disk=$(mount | awk '$3=="/boot/efi" {print $1}' 2>/dev/null)
98 EFIBOOTMGR_OPTS="--gpt"
99 if [ -n "$efi_disk" ] ; then
100 efi_partnum="$(echo $efi_disk|sed -e's;^.*[^0-9]\([0-9]\+\)$;\1;')"
101 efi_disk="$(echo $efi_disk|sed -e's;^\(.*\)[0-9]\+$;\1;')"
102 if [ -b "$efi_disk" -a -n "$efi_partnum" ] ; then
103 EFIBOOTMGR_OPTS="$EFIBOOTMGR_OPTS --disk $efi_disk"
104 EFIBOOTMGR_OPTS="$EFIBOOTMGR_OPTS --part $efi_partnum"
107 echo -n $EFIBOOTMGR_OPTS
110 find_bootmgr_entry () {
112 $EFIBOOTMGR | awk -v find="$1" '
113 /^Boot[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\*?/ {
118 gsub(/^[ \t]+|[ \t]+$/,"");
119 if ($0 == find) print num
123 remove_bootmgr_entry () {
125 bootnum=$(find_bootmgr_entry "$1")
126 [ -n "$bootnum" ] || return 0
127 verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet --delete-bootnum -b "$bootnum"
131 add_bootmgr_entry () {
136 bootnum=$(find_bootmgr_entry "$label")
138 if [ "${binary#/}" = "${binary}" ] ; then
140 binary="$DESTDIR/$binary"
142 binary="${binary#/boot/efi}"
143 binary="$(echo -nE "$binary"|sed -e's;/;\\;g')"
145 if [ -n "$bootnum" ] ; then
146 # efibootmgr doesn't seem to update the arguments
147 # we need to remove old entry and create a new one
148 verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet --delete-bootnum -b "$bootnum"
150 verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --create \
151 --quiet --label "$label" --loader "$binary" -u "$args"
152 bootnum="$(find_bootmgr_entry "$label")"
157 echo -n "$*" | tr -c '[a-zA-Z0-9_]' '_'
162 MOUNT_EFI_PARTITION="no"
166 [ -e /etc/efi-boot/update.conf ] && . /etc/efi-boot/update.conf
170 while [ -n "$*" ] ; do
180 echo "$_SCRIPT_NAME $_SCRIPT_VERSION"
184 MOUNT_EFI_PARTITION=yes
193 is_yes "$ALLOW_AUTO" || exit 0
203 if ! mountpoint -q /boot/efi ; then
205 if is_yes "$MOUNT_EFI_PARTITION" ; then
206 # first try via fstab
207 if ! mount /boot/efi 2>/dev/null ; then
209 efi_device="$(/sbin/blkid -o device -l -t PARTUUID="54f69bcc-954d-4f97-8fef-80b359f9e4aa")"
210 if [ -z "$efi_device" ] ; then
211 msg "EFI system partition not found."
214 mount -t vfat "$efi_device" /boot/efi
217 if ! mountpoint -q /boot/efi ; then
218 msg "EFI system partition not mounted."
223 if [ -x /usr/sbin/efibootmgr ] ; then
225 EFIBOOTMGR=/usr/sbin/efibootmgr
226 if ! $EFIBOOTMGR >/dev/null 2>&1 ; then
227 msg "efibootmgr does not work (efivars interface not available?)"
228 msg "won't update boot manager configuration"
231 EFIBOOTMGR_OPTS="$(get_efibootmgr_opts)"
234 msg "efibootmgr missing, won't update the boot manager configuration"
238 for bootloader_conf in /etc/efi-boot/update.d/*.conf ; do
239 if [ ! -e "$bootloader_conf" ] ; then
243 CONFIG_NAME="$(basename "$bootloader_conf" .conf)"
252 . "$bootloader_conf" || continue
254 LABEL="$LABEL_PREFIX$LABEL"
256 if ! is_yes "$ENABLED" ; then
257 remove_bootmgr_entry "$LABEL" >/dev/null
262 if [[ "$ARCH" = i?86 || "$ARCH" = pentium[45] || "$ARCH" = "athlon" ]] ; then
265 elif [[ "$ARCH" = "x86_64" || "$ARCH" = "amd64" || "$ARCH" = "ia32e" ]] ; then
272 PLATFORM_PATH="EFI/$(echo -nE "$PLATFORM_DIR"|sed -e's/@ARCH@/'"$efi_arch"'/')"
273 local escaped_EFI_PLATFORM_PATH="$(echo -nE "$PLATFORM_PATH"|sed -e's;/;\\\\;g')"
274 DESTDIR="/boot/efi/$PLATFORM_PATH"
275 ARGS="$(echo -nE "$ARGS"|sed -e's/@ARCH@/'"$efi_arch"'/;s/@EFI_PLATFORM_PATH@/'"$escaped_EFI_PLATFORM_PATH"'/g')"
277 verbose "ARGS: '$ARGS'"
281 verbose "Updating $LABEL..."
283 if [ -n "$BINARY" ] ; then
284 bootnum="$(add_bootmgr_entry "$LABEL" "$BINARY" "$ARGS")"
285 eval "_$(safe_string ${CONFIG_NAME})_bootnum=\"$bootnum\""
289 if [ -n "$ORDER" -a "$EFIBOOTMGR" != "/bin/true" ] ; then
290 # set up the configured boot order, not removing any existing entries
291 tail="$($EFIBOOTMGR | awk '/^BootOrder:/ {gsub(/,/," ",$2); print $2}')"
293 for config_name in $ORDER ; do
294 eval "bootnum=\$_$(safe_string ${config_name})_bootnum"
295 if [ -z "$bootnum" ] ; then
296 verbose "Cannot find '$config_name' config - won't add to boot order."
299 tail="$(list_remove "$tail" "$bootnum")"
300 head="$head $bootnum"
302 bootorder="$(echo -n $head $tail | sed -e's/ /,/g')"
303 if [ -n "$bootorder" ] ; then
304 verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet --bootorder "$bootorder"
308 if ! is_yes "$ALLOW_AUTO" && ! is_yes "$AUTO_RUN"; then
309 msg "ALLOW_AUTO is not enabled in /etc/efi-boot/update.conf,"
310 msg "files will not be automatically updated on upgrades."
313 # vi: ft=sh sw=4 sts=4 et