3 # Copyright 2013-2014 Intel Corporation
4 # Author: Artem Bityutskiy
7 PROG="setup-gummiboot-conf"
10 srcdir="$(readlink -ev -- ${0%/*})"
11 if [ -f "$srcdir/setup-ivi-sh-functions" ]; then
12 . "$srcdir/setup-ivi-sh-functions"
14 . /usr/share/setup-ivi/setup-ivi-sh-functions
17 # This is a small trick which I use to make sure my scripts are portable -
18 # check if 'dash' is present, and if yes - use it.
19 if can_switch_to_dash; then
20 exec dash -euf -- "$srcdir/$PROG" "$@"
24 # Common preparations for all subcommands.
27 verbose "Boot directory is $bootdir"
28 [ -d "$bootdir" ] || \
29 fatal "boot directory path \"$bootdir\" does not exist"
31 # The gummiboot configuration directory
32 conf_dir="$bootdir/loader"
33 # The gummiboot configuration file
34 conf_file="$conf_dir/loader.conf"
35 # The gummiboot kernel entries directory
36 entries_dir="$bootdir/loader/entries"
39 # Get a regular expression for matching gummiboot configuration file option
43 local opt="$(esc_regexp "$1")"
45 opt="$(case_insensitive_regexp "$opt")"
46 printf "%s" "\(^[[:blank:]]*$opt[[:blank:]]\+\)\([^[:blank:]]\+\)\([[:blank:]]*$\)"
49 # Create the default gummiboot configuration file.
50 create_default_conf_file()
52 verbose "creating the default configuration file \"$conf_file\""
54 mkdir -p $verbose -- "$conf_dir" >&2
55 cat > "$conf_file" <<-EOF
62 # Check wheter the gummiboot configuration file exist, and if not:
63 # o create the default one if --force option was specified
64 # o fail if no --force option was specified
65 check_and_create_default_conf_file()
67 if [ -s "$conf_file" ]; then
71 if [ -n "$force" ]; then
72 create_default_conf_file "$1"
74 fatal "cannot find the gummiboot configuration file" \
75 "(\"$conf_file\") (use -f to create the default" \
81 # -----------------------------------------------------------------------------
82 # The "add" subcommand
83 # -----------------------------------------------------------------------------
89 Usage: $PROG add [options] <entry> <title> <kernel> <options>
91 Add a new gummiboot entry. The mandatory arguments are:
93 <entry> - name of the gummiboot entry to add
94 (<bootdir>/loader/entries/<entry>.conf)
95 <title> - the title of the entry
96 <kernel> - name of the kernel binary to add the entry for
98 <options> - kernel boot options
101 -f, --force if the entry already exists - re-write it, if
102 <bootdir>/loader/loader.conf does not exist - create one,
103 if <bootdir>/<kernel> does not exist - do not fail
105 add a splash field to the entry file. <file> is a
106 mandatory parameter to specify splash image location.
107 -h, --help show this text and exit
111 show_add_usage_fail()
113 IFS= printf "%s\n\n" "$PROG: error: $*" >&2
120 if [ "$#" -eq 0 ]; then
126 tmp=`getopt -n $PROG -o f,s:,h --long force,splash:,help -- "$@"` ||
127 show_add_usage_fail "cannot parse command-line options"
146 *) show_add_usage_fail "unrecognized option \"$1\""
152 if [ "$#" -lt 4 ]; then
153 show_add_usage_fail "too little arguments"
155 if [ "$#" -gt 4 ]; then
156 show_add_usage_fail "too many arguments: \"$1\""
158 if [ -n "$splash" ] && ! [ -f "$splash" ]; then
159 show_add_usage_fail "splash file not found: \"$splash\""
164 local entry="$1"; shift
165 local title="$1"; shift
166 local kernel="$1"; shift
167 local options="$1"; shift
168 local kernel_path="$bootdir/$kernel"
169 local entry_path="$entries_dir/${entry}.conf"
171 verbose "entry is \"$entry\""
172 verbose "title is \"$title\""
173 verbose "kernel is \"$kernel\""
174 verbose "options are \"$options\""
176 if [ -f "$entry_path" ] && [ -z "$force" ]; then
177 fatal "gummiboot entry \"$entry_path\" already exists" \
178 "(use -f to force re-creating it)"
181 if ! [ -f "$kernel_path" ] && [ -z "$force" ]; then
182 fatal "cannot find kernel \"$kernel_path\"" \
183 "(use -f to ignore this error)"
186 # Make sure the gummiboot configuration file exists
187 check_and_create_default_conf_file "$entry"
189 # Find out the kernel version from its name
190 local kernel_version="$(printf "%s" "$kernel" | LC_ALL=C \
191 sed -e 's/[^[:digit:]]\+-\([[:digit:]]\+.*\)/\1/')"
192 [ -n "$kernel_version" ] || \
193 fatal "cannot fetch kernel version from \"$kernel\""
195 # Create the new entry
196 mkdir -p $verbose -- "$entries_dir" >&2
197 cat > "$entry_path" <<-EOF
200 version $kernel_version
205 # Add an optional splash image entry if the image file exists
206 if [ -n "$splash" ]; then
207 cp $verbose -- "$splash" "$entries_dir"
208 printf "%s\n" "splash \\loader\\entries\\${splash##*/}" \
212 if [ -n "$verbose" ]; then
213 verbose "contents of \"$entry_path\":"
214 cat -- "$entry_path" >&2
219 # -----------------------------------------------------------------------------
220 # The "remove" subcommand
221 # -----------------------------------------------------------------------------
227 Usage: $PROG remove [options] <entry>
229 Delete gummiboot entry <entry> (<bootdir>/loader/entries/<entry>.conf).
232 -f, --force do not fail if the entry doesn't exist
233 -h, --help show this text and exit
237 show_remove_usage_fail()
239 IFS= printf "%s\n\n" "$PROG: error: $*" >&2
240 show_remove_usage >&2
246 if [ "$#" -eq 0 ]; then
252 tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
253 show_remove_usage_fail "cannot parse command-line options"
268 *) show_remove_usage_fail "unrecognized option \"$1\""
274 if [ "$#" -lt 1 ]; then
275 show_remove_usage_fail "too little arguments"
277 if [ "$#" -gt 1 ]; then
278 show_remove_usage_fail "too many arguments: \"$1\""
284 local entry_path="$entries_dir/${entry}.conf"
286 if ! [ -f "$entry_path" ] && [ -z "$force" ]; then
287 fatal "gummiboot entry \"$entry_path\" doesn't exist" \
288 "(use -f to ignore this error)"
291 rm -rf $verbose -- "$entry_path" >&2
292 verbose "removed $entry_path"
296 # -----------------------------------------------------------------------------
297 # The "default" subcommand
298 # -----------------------------------------------------------------------------
301 # Get the kernel name from a gummiboot entry
302 get_kernel_from_entry()
305 local entry="$entries_dir/$1.conf"
307 if [ -f "$entry" ]; then
308 local regexp="$(get_regexp "efi")"
309 local result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" -- \
312 if [ -z "$result" ]; then
313 regexp="$(get_regexp "linux")"
314 result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" -- \
317 [ -n "$result" ] || return 0
321 printf "%s" "${result##*/}"
327 Usage: $PROG default [options] <entry>
329 Set the default boot kernel to <entry>, which is the gummiboot entry name to
330 become the default (without the ".conf" suffix, like in
331 <bootdir>/loader/entries/<entry>.conf). If <entry> is omited, this command
332 prints the currently default entry name.
335 -f, --force if <bootdir>/loader/loader.conf does not exist - create the
336 default one, if <bootdir>/loader/entries/<entry>.conf does not
338 -h, --help show this text and exit
342 show_default_usage_fail()
344 IFS= printf "%s\n\n" "$PROG: error: $*" >&2
345 show_default_usage >&2
352 tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
353 show_default_usage_fail "cannot parse command-line options"
368 *) show_default_usage_fail "unrecognized option \"$1\""
374 if [ "$#" -gt 1 ]; then
375 show_default_usage_fail "too many arguments: \"$1\""
380 local entry="${1:-}";
382 # Make sure the gummiboot configuration file exists
383 check_and_create_default_conf_file "$entry"
385 # Find the current default entry
386 local regexp="$(get_regexp "default")"
387 local default_entry="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" -- \
390 if [ -z "$entry" ]; then
391 printf "%s\n" "entry: $default_entry"
392 printf "%s\n" "kernel: $(get_kernel_from_entry "$default_entry")"
396 local entry_path="$entries_dir/${entry}.conf"
397 if ! [ -f "$entry_path" ] && [ -z "$force" ]; then
398 fatal "cannot find the gummiboot entry \"$entry_path\"" \
399 "(use -f to ignore this error)"
402 if [ -z "$default_entry" ]; then
403 verbose "no default entry found, adding \"$entry\""
404 printf "%s" "default $entry" >> "$conf_file"
408 [ "$(printf "%s\n" "$default_entry" | wc -l)" -eq "1" ] || \
409 fatal "more than one default entry in \"$conf_file\""
411 # Escape special sed characters in "$entry" and replace the old default
412 # entry with the new one
413 local entry_esc="$(esc_sed_replacement "$entry")"
414 LC_ALL=C sed -i -e "s/$regexp/\1$entry_esc\3/" -- "$conf_file"
416 verbose "set the default boot kernel to \"$entry"\"
420 # -----------------------------------------------------------------------------
426 Usage: $PROG [options] <subcommand> [options] <arguments>
428 This program changes the gummiboot bootloader configuration. Supported
430 add - add a gummiboot entry for a kernel
431 remove - remove a gummiboot entry
432 default - get or set the default gummiboot entry
434 Run "$PROG <subcommand>" to see subcommand-specific help.
437 -b, --bootdir path to the boot directory (default is "/boot")
438 --version show the program version and exit
439 -v, --verbose be verbose
440 -h, --help show this text and exit
446 IFS= printf "%s\n\n" "$PROG: error: $*" >&2
453 while [ -n "${1:-""}" ] && [ -z "${1##-*}" ]; do
457 # If there is no argument or it starts with "-", complain
458 if [ -z "${1:-""}" ] || [ -z "${1##-*}" ]; then
459 fatal "--bootdir requires an argument"
476 *) show_usage_fail "unrecognized option \"$1\""
484 if [ "$#" -eq 0 ]; then
490 subcommand="$1"; shift
492 case "$subcommand" in
498 remove_subcommand "$@"
502 default_subcommand "$@"
505 *) show_usage_fail "unrecognized subcommand \"$subcommand\""