#!/bin/sh -efu # Copyright 2013 Intel Corporation # Author: Artem Bityutskiy # License: GPLv2 # This script assumes there is a working gummiboot configuration exists. This # scripts then scanse the boot partition, 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 latest kernel. # # We make several assumptions in this script. # 1. The kernel binary names are 'vmlinuz-' # 2. Kernel entry file names are 'vmlinuz-.conf' # 3. There is always the "default" keyword in loader.conf, and we use the # corresponding kernel entry for adding new kernels. # 4. The 'default' entry in loader.conf does not does not use the wildcard ("*") # 5. Kernels binaries are placed in the ESP root # # May be there are few more implicit assumption. This all can be improved and # made to be more flexible if needed. PROG="setup-gummiboot-conf" # This is a helper function which printfs an error message and exits fatal() { printf "%s\n" "$PROG: error: $1\n" 1>&2 exit 1 } # Right now we assume that ESP is always in "/boot", but later we can add a # command line option for this. esp="/home/dedekind/tmp/boot" conf_file="$esp/loader/loader.conf" 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 an 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