summaryrefslogtreecommitdiff
path: root/setup-gummiboot-conf
blob: fa0cf58b8e86aecbf7c1ab1936a8b618fb54b1b3 (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
#!/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
}

# 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.conf/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_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