summaryrefslogtreecommitdiff
path: root/setup-gummiboot-conf
blob: e5cc58fd2a486cb63a30a355482758af4431aa6d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/bin/sh -efu

# Copyright 2013 Intel Corporation
# Author: Artem Bityutskiy
# License: GPLv2

# This scripts then scans ESP, finds out which kernels are available, and
# updates the gummiboot kernel entries: adds missing kernel entries and delets
# non-existing kernel entries.  The default entry is always set to the newest
# kernel version.
#
# This scripts makes several assumptions.
# 1. There is already a valid gummiboot configuration in ESP
# 2. The kernel binary names are 'vmlinuz-<version>', and the gummiboot kernel
#    entry file names are 'vmlinuz-<version>.conf'
# 3. There is always the "default" keyword in loader.conf.
# 4. The default entry (in 'loader.conf) can safely be used as a pattern for
#    adding new entries (e.g., the kernel arguments are taken from there)
# 4. The 'default' entry name does not have wildcards ("*")
# 5. Kernels binaries are placed in the root of ESP
#
# May be there are few more implicit assumption.
#
#This script requires a number of environment variables to be defined. Namely:
#
# 1. INSTALLERFW_MOUNT_PREFIX - where the target partitions are mounted (the
#    "root" directory of the file-system we install gummiboot to)

PROG="setup-gummiboot-conf"

# This is a helper function which printfs an error message and exits
fatal()
{
	printf "%s\n" "$PROG: error: $1" 1>&2
	exit 1
}

#
# Parse the input parameters
#
TEMP=`getopt -n $PROG --long default-kernel:,verbose,help -- "$@"` ||
        fail_usage ""
eval set -- "$TEMP"

verbose=
default_kernel=

while true; do
        case "$1" in
        -w|--workdir)
                mkdir $verbose -p -- "$2" >&2
                tmpdir="$(mktemp --tmpdir="$(readlink -fv -- "$2")" -dt "$PROG.XXXX")"
                shift
                ;;
        -p|--preserve)
                preserve="--preserve"
                ;;
        -v|--verbose) verbose=-v
                ;;
        -h|--help)
                show_usage
                exit 0
                ;;
        --) shift; break
                ;;
        *) fail_usage "Unrecognized option: $1"
                ;;
        esac
        shift
done

[ "$#" = 3 ] || fatal 'Insufficient or too many arguments.'


# Make sure the installer framework variables are defined
[ "${INSTALLERFW_MOUNT_PREFIX:+x}" == "x" ] ||
       fatal "installer framework environment variables not found"

# Get the ESP location
esp="$INSTALLERFW_MOUNT_PREFIX/boot"

# The gummiboot configuration file
conf_file="$esp/loader/loader.conf"
# The gummiboot kernel entries directory
entries_dir="$esp/loader/entries"

# Make sure the gummiboot configuration file exists
[ -f "$conf_file" ] || \
	fatal "cannot find the gummiboot configuration file (\"$conf_file\")"

# Get the list of installed kernels
kernels="$(ls -1 "$esp" | grep '^vmlinuz-' | sort -r)"
[ -n "$kernels" ] || \
	fatal "no vmlinuz-* files found in \"$esp\""

# Get the list of gummiboot kernel entries
entries="$(ls -1 "$entries_dir" | sed -e 's/\.conf$//g' | sort -r)"
[ -n "$entries" ] || \
	fatal "no gummiboot entries found in \"$entries_dir\""

# Get the default entry name
default_entry="$(cat "$conf_file" | sed -n -e 's/[ \t]*default[ \t]\+\(.\+\)[ \t]*/\1/p')"
[ -n "$default_entry" ] || \
	fatal "cannot find the default entry in \"$conf_file\""
[ "$(printf "%s\n" "$default_entry" | wc -l)" -eq "1" ] || \
	fatal "more than one default entry in \"$conf_file\""

if ! [ -f "$entries_dir/$default_entry" ]; then
	# The default entry does not exist anymore. Pick the entry
	# corresponding to the newest kernel then.
	default_entry="$(printf "%s" "$entries" | head -n1)"
fi

# Use the default entry to prepare the pattern for other entries
pattern="$(cat "$entries_dir/$default_entry")"
# Drop few keywords which we won't need
pattern="$(printf "%s" "$pattern" | sed -e '/[ \t]*linux[ \t]\+/d')"
pattern="$(printf "%s" "$pattern" | sed -e '/[ \t]*efi[ \t]\+/d')"
pattern="$(printf "%s" "$pattern" | sed -e '/[ \t]*version[ \t]\+/d')"

# Create a gummiboot entry for every new kernel
printf "%s\n" "$kernels" | while IFS= read -r kernel; do
	if [ -f "$entries_dir/$kernel.conf" ]; then
		continue
	fi

	kernel_version="$(printf "%s" $kernel | sed -e 's/vmlinuz-\(.*\)/\1/')"

	printf "%s" "$pattern" > "$entries_dir/$kernel.conf"
	printf "\n%s" "version $kernel_version" >> "$entries_dir/$kernel.conf"
	printf "\n%s" "efi /$kernel" >> "$entries_dir/$kernel.conf"
done

# Update the default entry
newest_kernel="$(printf "%s" "$kernels" | head -n1)"
sed -i -e "s/[ \t]*default[ \t]\+.*/default $newest_kernel.conf/" "$conf_file"

# Remove gummiboot entries for non-existing kernels
printf "%s\n" "$entries" | while IFS= read -r entry; do
	kernel="$entry"
	[ -f "$esp/$kernel" ] || rm "$entries_dir/$entry.conf"
done