]> git.pld-linux.org Git - packages/efi-boot-update.git/blob - efi-boot-update
It is not 'x32', it is 'ia32'
[packages/efi-boot-update.git] / efi-boot-update
1 #!/bin/sh
2
3 _SCRIPT_NAME=efi-boot-update
4 _SCRIPT_VERSION=0.0
5
6 . /etc/rc.d/init.d/functions
7
8 usage () {
9
10     echo "Usage: $0 OPTIONS"
11     echo "Update EFI boot loaders"
12     echo
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 }
19
20 msg () {
21     echo "efi-boot-update: $*" >&2
22 }
23
24 verbose () {
25     if is_yes "$VERBOSE" ; then 
26         echo "efi-boot-update: $*" >&2
27     fi
28 }
29
30 verbose_cmd () {
31     if is_yes "$VERBOSE" ; then
32         echo "+$*" >&2
33     fi
34     "$@"
35 }
36
37
38 list_remove () {
39
40     for item in $1 ; do
41         if [ "$item" = "$2" ] ; then
42             continue
43         fi
44         echo -n "$item "
45     done
46 }
47
48 update_file () {
49     local cmd
50     local src
51     local dest
52     while [ -n "$1" ] ; do
53         case $1 in 
54             --missingok)
55                 shift
56                 [ -e "$1" ] || return 0
57                 ;;
58             --*)
59                 msg "update_file: ignoring unknown option: $1"
60                 shift
61                 ;;
62             *)
63                 break
64                 ;;
65         esac
66     done
67     src="$1"; shift
68     dst="$2"; shift
69     if [ -n "$*" ] ; then
70         msg "update_file: unexpected arguments: $*"
71         return 1
72     fi
73     if [ "${dst#/}" = "${dst}" ] ; then
74         # relative path
75         dst="$DESTDIR/$dst"
76     fi
77     if is_yes "$FORCE_UPDATES" ; then
78         is_yes "$VERBOSE" && echo +cp --force --preserve=timestamps "$src" "$dst"
79         cp --force --preserve=timestamps "$src" "$dst"
80     else
81         is_yes "$VERBOSE" && echo +cp --update --preserve=timestamps "$src" "$dst"
82         cp --update --preserve=timestamps "$src" "$dst"
83     fi
84 }
85
86 get_efibootmgr_opts() {
87     local efi_disk
88     local efi_partnum
89     efi_disk=$(mount | awk '$3=="/boot/efi" {print $1}' 2>/dev/null)
90     EFIBOOTMGR_OPTS="--gpt"
91     if [ -n "$efi_disk" ] ; then
92         efi_partnum="$(echo $efi_disk|sed -e's;^.*[^0-9]\([0-9]\+\)$;\1;')"
93         efi_disk="$(echo $efi_disk|sed -e's;^\(.*\)[0-9]\+$;\1;')"
94         if [ -b "$efi_disk" -a -n "$efi_partnum" ] ; then 
95             EFIBOOTMGR_OPTS="$EFIBOOTMGR_OPTS --disk $efi_disk"
96             EFIBOOTMGR_OPTS="$EFIBOOTMGR_OPTS --part $efi_partnum"
97         fi
98     fi
99     echo -n $EFIBOOTMGR_OPTS
100 }
101
102 find_bootmgr_entry () {
103
104     $EFIBOOTMGR | awk -v find="$1" '
105 /^Boot[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\*?/ { 
106                                 sub(/^Boot/,""); 
107                                 sub(/\*/,""); 
108                                 num=$1; 
109                                 $1=""; 
110                                 gsub(/^[ \t]+|[ \t]+$/,""); 
111                                 if ($0 == find) print num
112                             }'
113 }
114         
115 remove_bootmgr_entry () {
116     local bootnum
117     bootnum=$(find_bootmgr_entry "$1")
118     [ -n "$bootnum" ] || return 0
119     verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet --delete-bootnum -b "$bootnum"
120     echo -n "$bootnum"
121 }
122
123 add_bootmgr_entry () {
124     local label=$1
125     local binary=$2
126     local args=$3
127     local bootnum
128     bootnum=$(find_bootmgr_entry "$label")
129
130     if [ "${binary#/}" = "${binary}" ] ; then
131         # relative path
132         binary="$DESTDIR/$binary"
133     fi
134     binary="${binary#/boot/efi}"
135     binary="$(echo -n "$binary"|sed -e's;/;\\;g')"
136
137     if [ -n "$bootnum" ] ; then
138         echo -n "$args" | verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet \
139                             --bootnum "$bootnum" --loader "$binary" -@ -
140     else
141         echo -n "$args" | verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --create \
142                             --quiet --label "$label" --loader "$binary" -@ -
143         bootnum="$(find_bootmgr_entry "$label")"
144     fi
145     echo -n "$bootnum"
146 }
147
148 safe_string () {
149     echo -n "$*" | tr -c '[a-zA-Z0-9_]' '_'
150 }
151
152 FORCE_UPDATES="no"
153 MOUNT_EFI_PARTITION="no"
154 LABEL_PREFIX=""
155 DEFAULT=""
156 VERBOSE="no"
157
158 [ -e /etc/efi-boot/update.conf ] && . /etc/efi-boot/update.conf
159
160 while [ -n "$*" ] ; do
161     local arg
162     arg="$1"
163     shift
164     case $arg in
165         --help|-h)
166             usage
167             exit 0
168             ;;
169         --version)
170             echo "$_SCRIPT_NAME $_SCRIPT_VERSION"
171             exit 0
172             ;;
173         --mount|-m)
174             MOUNT_EFI_PARTITION=yes
175             ;;
176         --verbose|-v)
177             VERBOSE=yes
178             ;;
179         --force)
180             FORCE_UPDATES="yes"
181             ;;
182         *)
183             usage >&2
184             exit 2
185             ;;
186     esac
187 done
188
189 if ! mountpoint -q /boot/efi ; then
190     mkdir -p /boot/efi
191     if is_yes "$MOUNT_EFI_PARTITION" ; then
192         # first try via fstab
193         if ! mount /boot/efi 2>/dev/null ; then
194             local efi_device
195             efi_device="$(/sbin/blkid -o device -l -t PARTUUID="54f69bcc-954d-4f97-8fef-80b359f9e4aa")"
196             if [ -z "$efi_device" ] ; then
197                 msg "EFI system partition not found."
198                 exit 1
199             fi
200             mount -t vfat "$efi_device" /boot/efi
201         fi
202     fi
203     if ! mountpoint -q /boot/efi ; then
204         msg "EFI system partition not mounted."
205         exit 1
206     fi
207 fi
208
209 if [ -x /usr/sbin/efibootmgr ] ; then
210     modprobe -q efivars
211     EFIBOOTMGR=/usr/sbin/efibootmgr
212     if ! $EFIBOOTMGR >/dev/null 2>&1 ; then
213         msg "efibootmgr does not work (efivars interface not available?)"
214         msg "won't update boot manager configuration"
215         EFIBOOTMGR=/bin/true
216     else
217         EFIBOOTMGR_OPTS="$(get_efibootmgr_opts)"
218     fi
219 else
220     msg "efibootmgr missing, won't update the boot manager configuration"
221     EFIBOOTMGR=/bin/true
222 fi
223
224 for bootloader_conf in /etc/efi-boot/update.d/*.conf ; do
225     if [ ! -e "$bootloader_conf" ] ; then
226         continue
227     fi
228     ENABLED=yes
229     CONFIG_NAME="$(basename "$bootloader_conf" .conf)"
230     LABEL="$CONFIG_NAME"
231     ARCH="$(uname -m)"
232     BINARY=""
233     ARGS=""
234     install_files() {
235         /bin/true
236     }
237
238     . "$bootloader_conf" || continue
239
240     LABEL="$LABEL_PREFIX$LABEL"
241
242     if ! is_yes "$ENABLED" ; then
243         remove_bootmgr_entry "$LABEL" >/dev/null
244         continue
245     fi
246
247     local efi_arch
248     if [[ "$ARCH" = i?86 || "$ARCH" = pentium[45] || "$ARCH" = "athlon" ]] ; then
249         # %ix86
250         efi_arch=ia32
251     elif [[ "$ARCH" = "x86_64" || "$ARCH" = "amd64" || "$ARCH" = "ia32e" ]] ; then
252         # %x8664
253         efi_arch=x64
254     else
255         efi_arch="$ARCH"
256     fi
257     DESTDIR="/boot/efi/EFI/$(echo -n "$PLATFORM_DIR"|sed -e's/@ARCH@/'"$efi_arch"'/')"
258     mkdir -p "$DESTDIR"
259
260     verbose "Updating $LABEL..."
261     install_files
262     if [ -n "$BINARY" ] ; then
263             bootnum="$(add_bootmgr_entry "$LABEL" "$BINARY" "$ARGS")"
264             eval "_$(safe_string ${CONFIG_NAME})_bootnum=\"$bootnum\""
265     fi
266 done
267
268 if [ -n "$ORDER" -a "$EFIBOOTMGR" != "/bin/true" ] ; then
269     # set up the configured boot order, not removing any existing entries
270     tail="$($EFIBOOTMGR | awk '/^BootOrder:/ {gsub(/,/," ",$2); print $2}')"
271     head=""
272     for config_name in $ORDER ; do
273         eval "bootnum=\$_$(safe_string ${config_name})_bootnum"
274         if [ -z "$bootnum" ] ; then
275             verbose "Cannot find '$config_name' config - won't add to boot order."
276             continue
277         fi
278         tail="$(list_remove "$tail" "$bootnum")"
279         head="$head $bootnum"
280     done
281     bootorder="$(echo -n $head $tail | sed -e's/ /,/g')"
282     if [ -n "$bootorder" ] ; then
283         verbose_cmd $EFIBOOTMGR $EFIBOOTMGR_OPTS --quiet --bootorder "$bootorder"
284     fi
285 fi
286
287 # vi: ft=sh sw=4 sts=4 et
This page took 0.091923 seconds and 3 git commands to generate.