e5cc58fd2a486cb63a30a355482758af4431aa6d
[profile/ivi/setup-efi-ivi.git] / setup-gummiboot-conf
1 #!/bin/sh -efu
2
3 # Copyright 2013 Intel Corporation
4 # Author: Artem Bityutskiy
5 # License: GPLv2
6
7 # This scripts then scans ESP, finds out which kernels are available, and
8 # updates the gummiboot kernel entries: adds missing kernel entries and delets
9 # non-existing kernel entries.  The default entry is always set to the newest
10 # kernel version.
11 #
12 # This scripts makes several assumptions.
13 # 1. There is already a valid gummiboot configuration in ESP
14 # 2. The kernel binary names are 'vmlinuz-<version>', and the gummiboot kernel
15 #    entry file names are 'vmlinuz-<version>.conf'
16 # 3. There is always the "default" keyword in loader.conf.
17 # 4. The default entry (in 'loader.conf) can safely be used as a pattern for
18 #    adding new entries (e.g., the kernel arguments are taken from there)
19 # 4. The 'default' entry name does not have wildcards ("*")
20 # 5. Kernels binaries are placed in the root of ESP
21 #
22 # May be there are few more implicit assumption.
23 #
24 #This script requires a number of environment variables to be defined. Namely:
25 #
26 # 1. INSTALLERFW_MOUNT_PREFIX - where the target partitions are mounted (the
27 #    "root" directory of the file-system we install gummiboot to)
28
29 PROG="setup-gummiboot-conf"
30
31 # This is a helper function which printfs an error message and exits
32 fatal()
33 {
34         printf "%s\n" "$PROG: error: $1" 1>&2
35         exit 1
36 }
37
38 #
39 # Parse the input parameters
40 #
41 TEMP=`getopt -n $PROG --long default-kernel:,verbose,help -- "$@"` ||
42         fail_usage ""
43 eval set -- "$TEMP"
44
45 verbose=
46 default_kernel=
47
48 while true; do
49         case "$1" in
50         -w|--workdir)
51                 mkdir $verbose -p -- "$2" >&2
52                 tmpdir="$(mktemp --tmpdir="$(readlink -fv -- "$2")" -dt "$PROG.XXXX")"
53                 shift
54                 ;;
55         -p|--preserve)
56                 preserve="--preserve"
57                 ;;
58         -v|--verbose) verbose=-v
59                 ;;
60         -h|--help)
61                 show_usage
62                 exit 0
63                 ;;
64         --) shift; break
65                 ;;
66         *) fail_usage "Unrecognized option: $1"
67                 ;;
68         esac
69         shift
70 done
71
72 [ "$#" = 3 ] || fatal 'Insufficient or too many arguments.'
73
74
75 # Make sure the installer framework variables are defined
76 [ "${INSTALLERFW_MOUNT_PREFIX:+x}" == "x" ] ||
77        fatal "installer framework environment variables not found"
78
79 # Get the ESP location
80 esp="$INSTALLERFW_MOUNT_PREFIX/boot"
81
82 # The gummiboot configuration file
83 conf_file="$esp/loader/loader.conf"
84 # The gummiboot kernel entries directory
85 entries_dir="$esp/loader/entries"
86
87 # Make sure the gummiboot configuration file exists
88 [ -f "$conf_file" ] || \
89         fatal "cannot find the gummiboot configuration file (\"$conf_file\")"
90
91 # Get the list of installed kernels
92 kernels="$(ls -1 "$esp" | grep '^vmlinuz-' | sort -r)"
93 [ -n "$kernels" ] || \
94         fatal "no vmlinuz-* files found in \"$esp\""
95
96 # Get the list of gummiboot kernel entries
97 entries="$(ls -1 "$entries_dir" | sed -e 's/\.conf$//g' | sort -r)"
98 [ -n "$entries" ] || \
99         fatal "no gummiboot entries found in \"$entries_dir\""
100
101 # Get the default entry name
102 default_entry="$(cat "$conf_file" | sed -n -e 's/[ \t]*default[ \t]\+\(.\+\)[ \t]*/\1/p')"
103 [ -n "$default_entry" ] || \
104         fatal "cannot find the default entry in \"$conf_file\""
105 [ "$(printf "%s\n" "$default_entry" | wc -l)" -eq "1" ] || \
106         fatal "more than one default entry in \"$conf_file\""
107
108 if ! [ -f "$entries_dir/$default_entry" ]; then
109         # The default entry does not exist anymore. Pick the entry
110         # corresponding to the newest kernel then.
111         default_entry="$(printf "%s" "$entries" | head -n1)"
112 fi
113
114 # Use the default entry to prepare the pattern for other entries
115 pattern="$(cat "$entries_dir/$default_entry")"
116 # Drop few keywords which we won't need
117 pattern="$(printf "%s" "$pattern" | sed -e '/[ \t]*linux[ \t]\+/d')"
118 pattern="$(printf "%s" "$pattern" | sed -e '/[ \t]*efi[ \t]\+/d')"
119 pattern="$(printf "%s" "$pattern" | sed -e '/[ \t]*version[ \t]\+/d')"
120
121 # Create a gummiboot entry for every new kernel
122 printf "%s\n" "$kernels" | while IFS= read -r kernel; do
123         if [ -f "$entries_dir/$kernel.conf" ]; then
124                 continue
125         fi
126
127         kernel_version="$(printf "%s" $kernel | sed -e 's/vmlinuz-\(.*\)/\1/')"
128
129         printf "%s" "$pattern" > "$entries_dir/$kernel.conf"
130         printf "\n%s" "version $kernel_version" >> "$entries_dir/$kernel.conf"
131         printf "\n%s" "efi /$kernel" >> "$entries_dir/$kernel.conf"
132 done
133
134 # Update the default entry
135 newest_kernel="$(printf "%s" "$kernels" | head -n1)"
136 sed -i -e "s/[ \t]*default[ \t]\+.*/default $newest_kernel.conf/" "$conf_file"
137
138 # Remove gummiboot entries for non-existing kernels
139 printf "%s\n" "$entries" | while IFS= read -r entry; do
140         kernel="$entry"
141         [ -f "$esp/$kernel" ] || rm "$entries_dir/$entry.conf"
142 done