--- /dev/null
+The documentaion can be found here:
+https://wiki.tizen.org/wiki/IVI/artem-setup-ivi
+
+Some coding style notes for the shell scripts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1. Do not use bashisms, install 'dash' and use it to verify that the
+ scripts are free of bashisms.
+
+2. Do not use all capitals for variables
+
+3. For shared files, prefix all symbols which are not supposed to be
+ used from outside with "__".
+
+4. Be consistent with my style. If you see that something makes no sense
+ or could be improved, change that globally.
+
+--
+Artem Bityutskiy
--- /dev/null
+# This file can be used for testing setup-ivi-* scripts. This file corresponds
+# to an EFI boot image (boot partition has the EFS type GUID). Do the following
+# to start debugging
+#
+# mkdir /tmp/boot
+# touch /tmp/boot/vmlinuz-3.12-x86-ivi
+# mkdir -p /tmp/usr/lib/gummiboot
+# touch /tmp/usr/lib/gummiboot/gummibootia32.efi
+# mkdir /tmp/etc
+# echo 'PRETTY_NAME="My test OS"' > /tmp/etc/os-release
+
+export INSTALLERFW_MOUNT_PREFIX="/tmp"
+export INSTALLERFW_KERNEL_OPTS="rootwait rootfstype=ext4 quiet"
+export INSTALLERFW_PART0_ALIGN=1024
+export INSTALLERFW_PART0_BOOTFLAG=True
+export INSTALLERFW_PART0_FSOPTS=defaults,noatime
+export INSTALLERFW_PART0_FSTYPE=vfat
+export INSTALLERFW_PART0_LABEL=boot
+export INSTALLERFW_PART0_MOUNTPOINT=/boot
+export INSTALLERFW_PART0_PARTUUID=AC5A15ED-743A-42DC-88DD-97837EB802FD
+export INSTALLERFW_PART0_SIZE=64
+export INSTALLERFW_PART0_TYPE_ID=C12A7328-F81F-11D2-BA4B-00A0C93EC93B
+export INSTALLERFW_PART0_UUID=89A6-BDC8
+export INSTALLERFW_PART1_ALIGN=1024
+export INSTALLERFW_PART1_BOOTFLAG=False
+export INSTALLERFW_PART1_FSOPTS=defaults,noatime
+export INSTALLERFW_PART1_FSTYPE=ext4
+export INSTALLERFW_PART1_LABEL=platform
+export INSTALLERFW_PART1_MOUNTPOINT=/
+export INSTALLERFW_PART1_PARTUUID=7D723C77-2EB1-4AD6-B585-54D8E243CD87
+export INSTALLERFW_PART1_SIZE=3748
+export INSTALLERFW_PART1_TYPE_ID=
+export INSTALLERFW_PART1_UUID=a9bf2448-17b6-4113-99d7-061435a0a8a6
+export INSTALLERFW_PART_COUNT=2
+export INSTALLERFW_PTABLE_FORMAT=gpt
--- /dev/null
+# Copyright 2013 Intel Corporation
+# Author: Artem Bityutskiy
+# License: GPLv2
+
+# This file contains common functions for setup-ivi-* programs
+
+# Own name
+__PROG="${PROG:-installerfw-sh-functions}"
+
+# Installer framework variables are saved in this file
+__installerfw_file="/etc/installerfw-environment"
+# The OS release information file
+__osrelease_file="/etc/os-release"
+# EFI System Partition PARTUUID
+__esp_ptypeid="C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
+
+# Mount prefix is assumed to be "/" if it is not defined
+[ -n "${INSTALLERFW_MOUNT_PREFIX:-}" ] || export INSTALLERFW_MOUNT_PREFIX="/"
+
+__fatal()
+{
+ IFS= printf "%s\n" "$__PROG: error: $*" 1>&2
+ exit 1
+}
+
+__verbose()
+{
+ if [ -n "$verbose" ]; then
+ IFS= printf "%s\n" "$__PROG (verbose): $*" >&2
+ fi
+}
+
+# Verify that an environment variable is defined
+__verify_defined()
+{
+ local variable="$1"
+
+ printenv "$variable" > /dev/null ||
+ __fatal "cannot find required environment variable" \
+ "\"$variable\""
+}
+
+# Add the INSTALLERFW_MOUNT_PREFIX prefix to a path. This does not really
+# require a separate function unless we want to be fancy and avoid double or
+# tripple "/" in the resulting path.
+installerfw_mnt_prefix()
+{
+ __verify_defined "INSTALLERFW_MOUNT_PREFIX"
+
+ local path="$INSTALLERFW_MOUNT_PREFIX/$1"
+
+ printf "%s" "$path" | LC_ALL=C sed -e 's/\/\+/\//g'
+}
+
+# Return full path to the file which contains the installer framework
+# environment variables.
+installerfw_get_env_file_name()
+{
+ printf "%s" "$(installerfw_mnt_prefix "$__installerfw_file")"
+}
+
+# Save installer framework environment variables. Note, all the variables can
+# be split on 2 classes - those which make sense only inside the particular
+# installer and those which make sense in the OS environment. We only save the
+# latter.
+installerfw_save_env()
+{
+ local file="$(installerfw_get_env_file_name)"
+ local opts="\
+-e '^INSTALLERFW_KERNEL_OPTS=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_ALIGN=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_BOOTFLAG=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_FSOPTS=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_FSTYPE=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_LABEL=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_MOUNTPOINT=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_PARTUUID=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_SIZE=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_TYPE_ID=' \
+-e '^INSTALLERFW_PART[[:digit:]]\+_UUID=' \
+-e '^INSTALLERFW_PART_COUNT=' \
+-e '^INSTALLERFW_PTABLE_FORMAT=' \
+"
+
+ local variables="$(printenv | eval "LC_ALL=C grep $opts")"
+
+ if [ "$(printf "%s" "$variables" | wc -l)" -eq "0" ]; then
+ __fatal "no installer framework environment variables" \
+ "found, nothing to save"
+ fi
+
+ printf "%s" "$variables" | LC_ALL=C sed -n -e \
+ "s/\(^INSTALLERFW_[^=]\+\)=\(.*\)/\1=\"\2\"/p" > "$file"
+ __verbose "installerfw_save_env(): saved installer framework" \
+ "environment in \"$file\""
+}
+
+# Restore installer framework environment variables.
+installerfw_restore_env()
+{
+ local file="$(installerfw_get_env_file_name)"
+
+ [ -f "$file" ] || \
+ __fatal "installerfw_restore_env(): can't restore the" \
+ "installer framework environment: can't find" \
+ "\"$file\""
+
+ while IFS= read -r line; do
+ eval "export $line"
+ done < "$file"
+
+ __verbose "installerfw_restore_env(): restored installer" \
+ "framework environment from \"$file\""
+}
+
+# Check if the system is an EFI boot system by checking whether the boot
+# partition is a FAT 32 partition with the magic EFI type GUID.
+installerfw_is_efi_boot_system()
+{
+ installerfw_get_part_info "/boot" "TYPE_ID" "__ptypeid"
+
+ # Make sure the UUID uses capital letters
+ __ptypeid="$(printf "%s" "$__ptypeid" | tr "[:lower:]" "[:upper:]")"
+
+ __verify_defined "INSTALLERFW_PTABLE_FORMAT"
+
+ if [ "${INSTALLERFW_PTABLE_FORMAT:-}" = "gpt" ] && \
+ [ "$__ptypeid" = "$__esp_ptypeid" ]; then
+ __verbose "installerfw_is_efi_boot_system(): /boot is" \
+ "the EFI system partition (type is" "\"$__ptypeid\")"
+ return 0
+ else
+ __verbose "installerfw_is_efi_boot_system(): no EFI" \
+ "system partition found (type is" "\"$__ptypeid\")"
+ return 1
+ fi
+}
+
+# Get a piece of installer framework data for a partition. At the moment the
+# partition is specified by it's mount point (in $1), but this can be extended
+# to also accept the partition number, if needed.
+#
+# The second parameter ($2) is the a partial installer framework variable name
+# which should be returned. For example, "PARTUUID" would correspond to
+# "INSTALLERFW_PARTx_PARTUUID", and so on.
+#
+# The third parameter ($3) is name of the variable to store the result at. If
+# the requested installer framework variable is undefined or null, the shell
+# variable with name stored in $3 will have null value upon exit.
+installerfw_get_part_info()
+{
+ local __mntpoint="$1"; shift
+ local __var="$1"; shift
+ local __res_var="$1"; shift
+ local __pnum="0"
+
+ __verify_defined "INSTALLERFW_PART_COUNT"
+
+ while [ "$__pnum" -lt "$INSTALLERFW_PART_COUNT" ]; do
+ local __mp="INSTALLERFW_PART${__pnum}_MOUNTPOINT"
+ __verify_defined "$__mp"
+
+ __mp="$(eval printf "%s" "\"\$$__mp\"")"
+
+ [ "$__mp" != "$__mntpoint" ] || break
+
+ __pnum="$((__pnum+1))"
+ done
+
+ local installerfw_var="INSTALLERFW_PART${__pnum}_${__var}"
+
+ local __value=
+ if printenv "$installerfw_var" > /dev/null; then
+ __value="$(eval printf "%s" "\"\$$installerfw_var\"")"
+ fi
+
+ __verbose "installerfw_get_part_info(): $__res_var=$__value"
+ eval "$__res_var"="\"\$__value\""
+}
--- /dev/null
+# This file can be used for testing setup-ivi-* scripts. This file corresponds
+# to an MBR boot image. Do the following to start debugging:
+#
+# mkdir /tmp/boot
+# touch /tmp/boot/vmlinux-3.12-x86-ivi
+# mkdir -p /tmp/usr/share/syslinux/
+# touch /tmp/usr/share/syslinux/gptmbr.bin
+# mkdir /tmp/etc
+# echo 'PRETTY_NAME="My test OS"' > /tmp/etc/os-release
+
+export INSTALLERFW_MOUNT_PREFIX="/tmp"
+export INSTALLERFW_KERNEL_OPTS="rootwait rootfstype=ext4 quiet"
+export INSTALLERFW_PART0_ALIGN=1024
+export INSTALLERFW_PART0_BOOTFLAG=True
+export INSTALLERFW_PART0_FSOPTS=defaults,noatime
+export INSTALLERFW_PART0_FSTYPE=ext4
+export INSTALLERFW_PART0_LABEL=boot
+export INSTALLERFW_PART0_MOUNTPOINT=/boot
+export INSTALLERFW_PART0_PARTUUID=FC86A97B-3E8F-46F7-82F8-995A397A0523
+export INSTALLERFW_PART0_SIZE=64
+export INSTALLERFW_PART0_DEVNODE_NOW=/dev/null
+export INSTALLERFW_PART0_DISK_DEVNODE_NOW=/dev/null
+unset INSTALLERFW_PART0_TYPE_ID
+export INSTALLERFW_PART0_UUID=A775922D-D42F-4114-9089-35332B6F896E
+export INSTALLERFW_PART1_ALIGN=1024
+export INSTALLERFW_PART1_BOOTFLAG=False
+export INSTALLERFW_PART1_FSOPTS=defaults,noatime
+export INSTALLERFW_PART1_FSTYPE=ext4
+export INSTALLERFW_PART1_LABEL=platform
+export INSTALLERFW_PART1_MOUNTPOINT=/
+export INSTALLERFW_PART1_PARTUUID=B3EA5880-0737-4B0B-8858-B8933A50E44D
+export INSTALLERFW_PART1_SIZE=3748
+unset INSTALLERFW_PART1_TYPE_ID
+export INSTALLERFW_PART1_UUID=50C898EF-DC27-4CA2-A48C-326A2DE8E018
+export INSTALLERFW_PART_COUNT=2
+export INSTALLERFW_PTABLE_FORMAT=mbr
--- /dev/null
+* Thu Dec 19 14:29:23 UTC 2013 Artem Bityutskiy <artem.bityutskiy@linux.intel.com> 1.0
+- Initial implementation
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+Name: setup-ivi
+Version: 1.0
+Release: 1
+License: GPL-2.0
+Summary: Various early setup programs
+Url: http://www.tizen.org
+Group: System/Configuration
+Source: %{name}_%{version}.tar.gz
+Requires: /usr/bin/sed
+Requires: /usr/bin/grep
+Requires: /usr/bin/printf
+Requires: /usr/bin/printenv
+Requires: /usr/bin/sort
+Requires: virtual-setup-ivi-bootloader
+BuildArchitectures: noarch
+
+%package -n setup-gummiboot
+Summary: Command-line tool for tweaking gummiboot configuration
+Provides: virtual-setup-ivi-bootloader
+Requires: %{name}
+Requires: gummiboot
+
+%package -n setup-extlinux
+Summary: Command-line tool for tweaking extlinux configuration
+Provides: virtual-setup-ivi-bootloader
+Requires: %{name}
+Requires: syslinux-extlinux
+
+%description
+This package provides various early system setup programs
+
+%description -n setup-gummiboot
+This package provides a command-line tool for changing the gummiboot bootloader
+configuration files.
+
+%description -n setup-extlinux
+This package provides a command-line tool for changing the extlinux bootloader
+configuration file.
+
+###
+### PREP
+###
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+
+###
+### INSTALL
+###
+%install
+install -d %{buildroot}/%{_sbindir}
+install -d %{buildroot}/%{_prefix}/share/setup-ivi
+
+install -m755 setup-ivi-boot %{buildroot}/%{_sbindir}
+install -m755 setup-ivi-bootloader-conf %{buildroot}/%{_sbindir}
+install -m755 setup-gummiboot-conf %{buildroot}/%{_sbindir}
+install -m755 setup-extlinux-conf %{buildroot}/%{_sbindir}
+install -m644 setup-ivi-sh-functions %{buildroot}/%{_prefix}/share/setup-ivi
+install -m644 installerfw-sh-functions %{buildroot}/%{_prefix}/share/setup-ivi
+
+###
+### CLEAN
+###
+%clean
+rm -rf %{buildroot}
+
+###
+### FILES
+###
+%files
+%defattr(-,root,root)
+%{_sbindir}/setup-ivi-boot
+%{_sbindir}/setup-ivi-bootloader-conf
+%{_prefix}/share/setup-ivi/setup-ivi-sh-functions
+%{_prefix}/share/setup-ivi/installerfw-sh-functions
+
+%files -n setup-gummiboot
+%defattr(-,root,root)
+%{_sbindir}/setup-gummiboot-conf
+
+%files -n setup-extlinux
+%defattr(-,root,root)
+%{_sbindir}/setup-extlinux-conf
--- /dev/null
+#!/bin/sh -euf
+
+# Copyright 2013 Intel Corporation
+# Author: Artem Bityutskiy
+# License: GPLv2
+
+PROG="setup-extlinux-conf"
+VER="1.0"
+
+srcdir="$(readlink -ev -- ${0%/*})"
+PATH="/usr/share/setup-ivi:$srcdir:$PATH"
+
+. setup-ivi-sh-functions
+
+# This is a small trick which I use to make sure my scripts are portable -
+# check if 'dash' is present, and if yes - use it.
+if can_switch_to_dash; then
+ exec dash -euf "$srcdir/$PROG" "$@"
+ exit $?
+fi
+
+# Common preparations for all subcommands.
+prepare()
+{
+ verbose "Boot directory is $bootdir"
+ [ -d "$bootdir" ] || \
+ fatal "boot directory path \"$bootdir\" does not exist"
+
+ # The extlinux configuration directory
+ conf_dir="$bootdir/extlinux"
+ # The extlinux configuration file
+ conf_file="$conf_dir/extlinux.conf"
+}
+
+# Create the default extlinux configuration file.
+create_default_conf_file()
+{
+ verbose "creating the default configuration file \"$conf_file\""
+
+ mkdir -p $verbose "$conf_dir" >&2
+ cat > "$conf_file" <<-EOF
+ ui vesamenu.c32
+ prompt 0
+ timeout 1
+ default $1
+ EOF
+}
+
+# Check wheter the extlinux configuration file exist and if not:
+# o create the default one if --force option was specified
+# o fail if no --force option was specified
+check_and_create_default_conf_file()
+{
+ if [ -s "$conf_file" ]; then
+ return 0
+ fi
+
+ if [ -n "$force" ]; then
+ create_default_conf_file "$1"
+ else
+ fatal "cannot find the extlinux configuration file" \
+ "(\"$conf_file\") (use -f to force creating the" \
+ "default one)"
+ fi
+}
+
+# Get a regular expression for matching extlinux configuration file option "$1"
+get_regexp()
+{
+ local opt="$(esc_regexp "$1")"
+
+ opt="$(case_insensitive_regexp "$opt")"
+ printf "%s" "\(^[[:blank:]]*$opt[[:blank:]]\+\)\([^[:blank:]]\+\)\([[:blank:]]*$\)"
+}
+
+# Return a regular expression for matching label with name "$1".
+label_regexp()
+{
+ local opt="$(case_insensitive_regexp "label")"
+ local label="$(esc_regexp "$1")"
+
+ printf "%s" "\(^[[:blank:]]*$opt[[:blank:]]\+\)\($label\)\([[:blank:]]*$\)"
+}
+
+remove_label()
+{
+ local label="$1"
+ local l_regexp="$(label_regexp "$label")"
+ local anyl_regexp="$(get_regexp "label")"
+
+ LC_ALL=C sed -i -n -e "/$l_regexp/ { # mathes our label line
+ :l n; # get the next line
+ /$l_regexp/bl # same label again, keep skipping
+ /$anyl_regexp/!bl # a different label, stop skipping
+ }
+ /$l_regexp/!p # print all other lines
+ " "$conf_file"
+
+ remove_trailing_empty_lines "$conf_file"
+}
+
+#
+# -----------------------------------------------------------------------------
+# The "add" subcommand
+# -----------------------------------------------------------------------------
+#
+
+show_add_usage()
+{
+ cat <<-EOF
+Usage: $PROG add [options] <label> <title> <kernel> <options>
+
+Add a new extlinux boot menu entry. The mandatory arguments are:
+
+ <label> - a unique name of the boot menu entry to add, the entry will be
+ further refurred by the label
+ <title> - the boot menu entry title
+ <kernel> - name of the kernel binary corresponding to the entry
+ <options> - kernel boot options
+
+Options:
+ -f, --force if <label> already exists - re-create it, if
+ <bootdir>/extlinux/extlinux.conf does not exist - create it, if
+ <bootdir>/<kernel> does not exist - do not fail
+ -h, --help show this text and exit
+EOF
+}
+
+show_add_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_add_usage >&2
+ exit 1
+}
+
+add_subcommand()
+{
+ if [ "$#" -eq 0 ]; then
+ show_add_usage
+ exit 0
+ fi
+
+ local tmp
+ tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
+ show_add_usage_fail "cannot parse command-line options"
+ eval set -- "$tmp"
+
+ local force=
+ while true; do
+ case "$1" in
+ -f|--force)
+ force="-f"
+ ;;
+ -h|--help)
+ show_add_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_add_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+ done
+
+ if [ "$#" -lt 4 ]; then
+ show_add_usage_fail "too little arguments"
+ fi
+ if [ "$#" -gt 4 ]; then
+ show_add_usage_fail "too many arguments: \"$1\""
+ fi
+
+ prepare
+
+ local label="$1"; shift
+ local title="$1"; shift
+ local kernel="$1"; shift
+ local options="$1"; shift
+ local kernel_path="$bootdir/$kernel"
+
+ verbose "label is \"$label\""
+ verbose "title is \"$title\""
+ verbose "kernel is \"$kernel\""
+ verbose "options are \"$options\""
+
+ if ! [ -f "$kernel_path" ] && [ -z "$force" ]; then
+ fatal "cannot find kernel \"$kernel_path\"" \
+ "(use -f to ignore this error)"
+ fi
+
+ # Make sure the extlinux configuration file exists
+ check_and_create_default_conf_file "$label"
+
+ if LC_ALL=C grep -q -e "$(label_regexp "$label")" "$conf_file" && \
+ [ -z "$force" ]; then
+ fatal "extlinux boot menu label \"$label\" already exists" \
+ "(use -f to force re-creating it)"
+ fi
+
+ # Find out the kernel version from its name
+ local kernel_version="$(printf "%s" "$kernel" | LC_ALL=C \
+ sed -e 's/[^[:digit:]]\+-\([[:digit:]]\+.*\)/\1/')"
+ [ -n "$kernel_version" ] || \
+ fatal "cannot fetch kernel version from \"$kernel\""
+
+ # Remove the label if it exists, since we are going to add a new one
+ remove_label "$label"
+
+ local block="label $label
+ menu label $title ($kernel_version)
+ linux /$kernel
+ append $options"
+
+ printf "\n%s\n" "$block" >> "$conf_file"
+
+ if [ -n "$verbose" ]; then
+ verbose "Added the following to \"$conf_file\":"
+ printf "%s\n" "$block" >&2
+ fi
+}
+
+#
+# -----------------------------------------------------------------------------
+# The "remove" subcommand
+# -----------------------------------------------------------------------------
+#
+
+show_remove_usage()
+{
+ cat <<-EOF
+Usage: $PROG remove [options] <label>
+
+Delete extlinux boot entry which has label <label>.
+
+Options:
+ -f, --force do not fail if the entry doesn't exist
+ -h, --help show this text and exit
+EOF
+}
+
+show_remove_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_remove_usage >&2
+ exit 1
+}
+
+remove_subcommand()
+{
+ if [ "$#" -eq 0 ]; then
+ show_remove_usage
+ exit 0
+ fi
+
+ local tmp
+ tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
+ show_remove_usage_fail "cannot parse command-line options"
+ eval set -- "$tmp"
+
+ local force=
+ while true; do
+ case "$1" in
+ -f|--force)
+ force="-f"
+ ;;
+ -h|--help)
+ show_remove_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_remove_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+ done
+
+ if [ "$#" -lt 1 ]; then
+ show_remove_usage_fail "too little arguments"
+ fi
+ if [ "$#" -gt 1 ]; then
+ show_remove_usage_fail "too many arguments: \"$1\""
+ fi
+
+ prepare
+
+ local label="$1"
+
+ if ! LC_ALL=C grep -q -e "$(label_regexp "$label")" "$conf_file" && \
+ [ -z "$force" ]; then
+ fatal "cannot find label \"$label\" in \"$conf_file\"" \
+ "(use -f to ignore this error)"
+ fi
+
+ remove_label "$label"
+ verbose "removed $label"
+}
+
+#
+# -----------------------------------------------------------------------------
+# The "default" subcommand
+# -----------------------------------------------------------------------------
+#
+
+# Get the kernel binary name by its extlinux.conf label name
+get_kernel_by_label()
+{
+ local label="$1"
+ local l_regexp="$(label_regexp "$label")" # Regexp for our label
+ local anyl_regexp="$(get_regexp "label")" # Regexp for any label
+ local linux_regexp="$(get_regexp "linux")"
+ local kernel_regexp="$(get_regexp "kernel")"
+ local result
+
+ [ -z "$label" ] && return 0
+
+ result="$(LC_ALL=C sed -n -e "/$l_regexp/ {
+ :l n;
+ /$linux_regexp/ { s/$linux_regexp/\2/p }
+ /$kernel_regexp/ { s/$kernel_regexp/\2/p }
+ /$anyl_regexp/!bl # Loop till the next label
+ }" "$conf_file")"
+
+ printf "%s" "${result##*/}"
+}
+
+show_default_usage()
+{
+ cat <<-EOF
+Usage: $PROG default [options] <label>
+
+Set the default boot kernel to be the kernel which is marked with label <label>
+the extlinux configuration file. If <label> is omited, this command prints the
+currently default entry name.
+
+Options:
+ -f, --force <bootdir>/extlinux/extlinux.conf does not exist - create it, if
+ <label> does not exist - do not fail
+ -h, --help show this text and exit
+EOF
+}
+
+show_default_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_default_usage >&2
+ exit 1
+}
+
+default_subcommand()
+{
+ local tmp
+ tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
+ show_default_usage_fail "cannot parse command-line options"
+ eval set -- "$tmp"
+
+ local force=
+ while true; do
+ case "$1" in
+ -f|--force)
+ force="-f"
+ ;;
+ -h|--help)
+ show_default_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_default_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+ done
+
+ if [ "$#" -gt 1 ]; then
+ show_default_usage_fail "too many arguments: \"$1\""
+ fi
+
+ prepare
+
+ local label="${1:-}";
+
+ # Make sure the extlinux configuration file exists
+ check_and_create_default_conf_file "$label"
+
+ # Find the current default label
+ local regexp="$(get_regexp "default")"
+ local default_label="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$conf_file")"
+
+ if [ -z "$label" ]; then
+ printf "%s\n" "label: $default_label"
+ printf "%s\n" "kernel: $(get_kernel_by_label "$default_label")"
+ return 0
+ fi
+
+ local l_regexp="$(label_regexp "$label")"
+ local labels="$(LC_ALL=C grep -e "$l_regexp" "$conf_file" | wc -l)"
+
+ if [ "$labels" -eq "0" ] && [ -z "$force" ]; then
+ fatal "cannot find label \"$label\" in \"$conf_file\"" \
+ "(use -f to ignore this error)"
+ fi
+
+ if [ "$labels" -gt "1" ]; then
+ fatal "more than one labels \"$label\" in \"$conf_file\""
+ fi
+
+ if [ -z "$default_label" ]; then
+ verbose "no default label found, adding \"$label\""
+
+ local def="$(esc_sed_replacement "default $label")"
+ local anyl_regexp="$(get_regexp "label")"
+
+ LC_ALL=C sed -i -e "
+ $ { s/.*/&\n$def/; q }
+ /^[[:blank:]]*$/ { s/.*/$def\n&/; q }
+ /$(anyl_regexp)/ { s/.*/$def\n&/; q }
+ " "$conf_file"
+ return 0
+ fi
+
+ # Escape special sed characters in "$entry" and replace the old default
+ # entry with the new one
+ local esc_label="$(esc_sed_replacement "$label")"
+ LC_ALL=C sed -i -e "s/$regexp/\1$esc_label\3/" "$conf_file"
+ verbose "set the default boot kernel to \"$label"\"
+}
+
+#
+# -----------------------------------------------------------------------------
+#
+
+show_usage()
+{
+ cat <<-EOF
+Usage: $PROG [options] <subcommand> [options] <arguments>
+
+This program changes the extlinux bootloader configuration. Supported
+subcommands are:
+ add - add an extlinux boot menu entry for a kernel
+ remove - remove an extlinux boot menu entry
+ default - get or set the default extlinux boot menu entry
+
+Run "$PROG <subcommand>" to see subcommand-specific help.
+
+Options:
+ -b, --bootdir path to the boot directory (default is "/boot")
+ --version show the program version and exit
+ -v, --verbose be verbose
+ -h, --help show this text and exit
+EOF
+}
+
+show_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_usage >&2
+ exit 1
+}
+
+bootdir="/boot"
+verbose=
+while [ -n "${1:-""}" ] && [ -z "${1##-*}" ]; do
+ case "$1" in
+ -b|--bootdir)
+ shift
+ # If there is no argument or it starts with "-", complain
+ if [ -z "${1:-""}" ] || [ -z "${1##-*}" ]; then
+ fatal "--bootdir requires an argument"
+ fi
+ bootdir="$1"
+ ;;
+ --version)
+ printf "%s\n" "$VER"
+ exit 0
+ ;;
+ -v|--verbose)
+ verbose="-v"
+ ;;
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+done
+
+# Parse subcommands
+
+if [ "$#" -eq 0 ]; then
+ show_usage
+ exit 0
+fi
+
+
+subcommand="$1"; shift
+
+case "$subcommand" in
+add)
+ add_subcommand "$@"
+ break
+ ;;
+remove)
+ remove_subcommand "$@"
+ break
+ ;;
+default)
+ default_subcommand "$@"
+ break
+ ;;
+*) show_usage_fail "unrecognized subcommand \"$subcommand\""
+ ;;
+esac
--- /dev/null
+#!/bin/sh -euf
+
+# Copyright 2013 Intel Corporation
+# Author: Artem Bityutskiy
+# License: GPLv2
+
+PROG="setup-gummiboot-conf"
+VER="1.0"
+
+srcdir="$(readlink -ev -- ${0%/*})"
+PATH="/usr/share/setup-ivi:$srcdir:$PATH"
+
+. setup-ivi-sh-functions
+
+# This is a small trick which I use to make sure my scripts are portable -
+# check if 'dash' is present, and if yes - use it.
+if can_switch_to_dash; then
+ exec dash -euf "$srcdir/$PROG" "$@"
+ exit $?
+fi
+
+# Common preparations for all subcommands.
+prepare()
+{
+ verbose "Boot directory is $bootdir"
+ [ -d "$bootdir" ] || \
+ fatal "boot directory path \"$bootdir\" does not exist"
+
+ # The gummiboot configuration directory
+ conf_dir="$bootdir/loader"
+ # The gummiboot configuration file
+ conf_file="$conf_dir/loader.conf"
+ # The gummiboot kernel entries directory
+ entries_dir="$bootdir/loader/entries"
+}
+
+# Get a regular expression for matching gummiboot configuration file option
+# "$1"
+get_regexp()
+{
+ local opt="$(esc_regexp "$1")"
+
+ opt="$(case_insensitive_regexp "$opt")"
+ printf "%s" "\(^[[:blank:]]*$opt[[:blank:]]\+\)\([^[:blank:]]\+\)\([[:blank:]]*$\)"
+}
+
+# Create the default gummiboot configuration file.
+create_default_conf_file()
+{
+ verbose "creating the default configuration file \"$conf_file\""
+
+ mkdir -p $verbose "$conf_dir" >&2
+ cat > "$conf_file" <<-EOF
+ timeout 0
+ default $1
+ EOF
+}
+
+# Check wheter the gummiboot configuration file exist, and if not:
+# o create the default one if --force option was specified
+# o fail if no --force option was specified
+check_and_create_default_conf_file()
+{
+ if [ -s "$conf_file" ]; then
+ return 0
+ fi
+
+ if [ -n "$force" ]; then
+ create_default_conf_file "$1"
+ else
+ fatal "cannot find the gummiboot configuration file" \
+ "(\"$conf_file\") (use -f to create the default" \
+ "one)"
+ fi
+}
+
+#
+# -----------------------------------------------------------------------------
+# The "add" subcommand
+# -----------------------------------------------------------------------------
+#
+
+show_add_usage()
+{
+ cat <<-EOF
+Usage: $PROG add [options] <entry> <title> <kernel> <options>
+
+Add a new gummiboot entry. The mandatory arguments are:
+
+ <entry> - name of the gummiboot entry to add
+ (<bootdir>/loader/entries/<entry>.conf)
+ <title> - the title of the entry
+ <kernel> - name of the kernel binary to add the entry for
+ (<bootdir>/<kernel>)
+ <options> - kernel boot options
+
+Options:
+ -f, --force if the entry already exists - re-write it, if
+ <bootdir>/loader/loader.conf does not exist - create one,
+ if <bootdir>/<kernel> does not exist - do not fail
+ -h, --help show this text and exit
+EOF
+}
+
+show_add_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_add_usage >&2
+ exit 1
+}
+
+add_subcommand()
+{
+ if [ "$#" -eq 0 ]; then
+ show_add_usage
+ exit 0
+ fi
+
+ local tmp
+ tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
+ show_add_usage_fail "cannot parse command-line options"
+ eval set -- "$tmp"
+
+ local force=
+ while true; do
+ case "$1" in
+ -f|--force)
+ force="-f"
+ ;;
+ -h|--help)
+ show_add_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_add_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+ done
+
+ if [ "$#" -lt 4 ]; then
+ show_add_usage_fail "too little arguments"
+ fi
+ if [ "$#" -gt 4 ]; then
+ show_add_usage_fail "too many arguments: \"$1\""
+ fi
+
+ prepare
+
+ local entry="$1"; shift
+ local title="$1"; shift
+ local kernel="$1"; shift
+ local options="$1"; shift
+ local kernel_path="$bootdir/$kernel"
+ local entry_path="$entries_dir/${entry}.conf"
+
+ verbose "entry is \"$entry\""
+ verbose "title is \"$title\""
+ verbose "kernel is \"$kernel\""
+ verbose "options are \"$options\""
+
+ if [ -f "$entry_path" ] && [ -z "$force" ]; then
+ fatal "gummiboot entry \"$entry_path\" already exists" \
+ "(use -f to force re-creating it)"
+ fi
+
+ if ! [ -f "$kernel_path" ] && [ -z "$force" ]; then
+ fatal "cannot find kernel \"$kernel_path\"" \
+ "(use -f to ignore this error)"
+ fi
+
+ # Make sure the gummiboot configuration file exists
+ check_and_create_default_conf_file "$entry"
+
+ # Find out the kernel version from its name
+ local kernel_version="$(printf "%s" "$kernel" | LC_ALL=C \
+ sed -e 's/[^[:digit:]]\+-\([[:digit:]]\+.*\)/\1/')"
+ [ -n "$kernel_version" ] || \
+ fatal "cannot fetch kernel version from \"$kernel\""
+
+ # Create the new entry
+ mkdir -p $verbose "$entries_dir" >&2
+ cat > "$entry_path" <<-EOF
+ title $title
+ version $kernel_version
+ efi /$kernel
+ options $options
+ EOF
+
+ if [ -n "$verbose" ]; then
+ verbose "contents of \"$entry_path\":"
+ cat "$entry_path" >&2
+ fi
+}
+
+#
+# -----------------------------------------------------------------------------
+# The "remove" subcommand
+# -----------------------------------------------------------------------------
+#
+
+show_remove_usage()
+{
+ cat <<-EOF
+Usage: $PROG remove [options] <entry>
+
+Delete gummiboot entry <entry> (<bootdir>/loader/entries/<entry>.conf).
+
+Options:
+ -f, --force do not fail if the entry doesn't exist
+ -h, --help show this text and exit
+EOF
+}
+
+show_remove_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_remove_usage >&2
+ exit 1
+}
+
+remove_subcommand()
+{
+ if [ "$#" -eq 0 ]; then
+ show_remove_usage
+ exit 0
+ fi
+
+ local tmp
+ tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
+ show_remove_usage_fail "cannot parse command-line options"
+ eval set -- "$tmp"
+
+ local force=
+ while true; do
+ case "$1" in
+ -f|--force)
+ force="-f"
+ ;;
+ -h|--help)
+ show_remove_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_remove_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+ done
+
+ if [ "$#" -lt 1 ]; then
+ show_remove_usage_fail "too little arguments"
+ fi
+ if [ "$#" -gt 1 ]; then
+ show_remove_usage_fail "too many arguments: \"$1\""
+ fi
+
+ prepare
+
+ local entry="$1"
+ local entry_path="$entries_dir/${entry}.conf"
+
+ if ! [ -f "$entry_path" ] && [ -z "$force" ]; then
+ fatal "gummiboot entry \"$entry_path\" doesn't exist" \
+ "(use -f to ignore this error)"
+ fi
+
+ rm -rf $verbose "$entry_path" >&2
+ verbose "removed $entry_path"
+}
+
+#
+# -----------------------------------------------------------------------------
+# The "default" subcommand
+# -----------------------------------------------------------------------------
+#
+
+# Get the kernel name from a gummiboot entry
+get_kernel_from_entry()
+{
+ local result=
+ local entry="$entries_dir/$1.conf"
+
+ if [ -f "$entry" ]; then
+ local regexp="$(get_regexp "efi")"
+ local result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$entry")"
+
+ if [ -z "$result" ]; then
+ regexp="$(get_regexp "linux")"
+ result="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$entry")"
+
+ [ -n "$result" ] || return 0
+ fi
+ fi
+
+ printf "%s" "${result##*/}"
+}
+
+show_default_usage()
+{
+ cat <<-EOF
+Usage: $PROG default [options] <entry>
+
+Set the default boot kernel to <entry>, which is the gummiboot entry name to
+become the default (without the ".conf" suffix, like in
+<bootdir>/loader/entries/<entry>.conf). If <entry> is omited, this command
+prints the currently default entry name.
+
+Options:
+ -f, --force if <bootdir>/loader/loader.conf does not exist - create the
+ default one, if <bootdir>/loader/entries/<entry>.conf does not
+ exist - do not fail
+ -h, --help show this text and exit
+EOF
+}
+
+show_default_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_default_usage >&2
+ exit 1
+}
+
+default_subcommand()
+{
+ local tmp
+ tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
+ show_default_usage_fail "cannot parse command-line options"
+ eval set -- "$tmp"
+
+ local force=
+ while true; do
+ case "$1" in
+ -f|--force)
+ force="-f"
+ ;;
+ -h|--help)
+ show_default_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_default_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+ done
+
+ if [ "$#" -gt 1 ]; then
+ show_default_usage_fail "too many arguments: \"$1\""
+ fi
+
+ prepare
+
+ local entry="${1:-}";
+
+ # Make sure the gummiboot configuration file exists
+ check_and_create_default_conf_file "$entry"
+
+ # Find the current default entry
+ local regexp="$(get_regexp "default")"
+ local default_entry="$(LC_ALL=C sed -n -e "s/$regexp/\2/p" "$conf_file")"
+
+ if [ -z "$entry" ]; then
+ printf "%s\n" "entry: $default_entry"
+ printf "%s\n" "kernel: $(get_kernel_from_entry "$default_entry")"
+ return 0
+ fi
+
+ local entry_path="$entries_dir/${entry}.conf"
+ if ! [ -f "$entry_path" ] && [ -z "$force" ]; then
+ fatal "cannot find the gummiboot entry \"$entry_path\"" \
+ "(use -f to ignore this error)"
+ fi
+
+ if [ -z "$default_entry" ]; then
+ verbose "no default entry found, adding \"$entry\""
+ printf "%s" "default $entry" >> "$conf_file"
+ return 0
+ fi
+
+ [ "$(printf "%s\n" "$default_entry" | wc -l)" -eq "1" ] || \
+ fatal "more than one default entry in \"$conf_file\""
+
+ # Escape special sed characters in "$entry" and replace the old default
+ # entry with the new one
+ local entry_esc="$(esc_sed_replacement "$entry")"
+ LC_ALL=C sed -i -e "s/$regexp/\1$entry_esc\3/" "$conf_file"
+
+ verbose "set the default boot kernel to \"$entry"\"
+}
+
+#
+# -----------------------------------------------------------------------------
+#
+
+show_usage()
+{
+ cat <<-EOF
+Usage: $PROG [options] <subcommand> [options] <arguments>
+
+This program changes the gummiboot bootloader configuration. Supported
+subcommands are:
+ add - add a gummiboot entry for a kernel
+ remove - remove a gummiboot entry
+ default - get or set the default gummiboot entry
+
+Run "$PROG <subcommand>" to see subcommand-specific help.
+
+Options:
+ -b, --bootdir path to the boot directory (default is "/boot")
+ --version show the program version and exit
+ -v, --verbose be verbose
+ -h, --help show this text and exit
+EOF
+}
+
+show_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_usage >&2
+ exit 1
+}
+
+bootdir="/boot"
+verbose=
+while [ -n "${1:-""}" ] && [ -z "${1##-*}" ]; do
+ case "$1" in
+ -b|--bootdir)
+ shift
+ # If there is no argument or it starts with "-", complain
+ if [ -z "${1:-""}" ] || [ -z "${1##-*}" ]; then
+ fatal "--bootdir requires an argument"
+ fi
+ bootdir="$1"
+ ;;
+ --version)
+ printf "%s\n" "$VER"
+ exit 0
+ ;;
+ -v|--verbose)
+ verbose="-v"
+ ;;
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+done
+
+# Parse subcommands
+
+if [ "$#" -eq 0 ]; then
+ show_usage
+ exit 0
+fi
+
+
+subcommand="$1"; shift
+
+case "$subcommand" in
+add)
+ add_subcommand "$@"
+ break
+ ;;
+remove)
+ remove_subcommand "$@"
+ break
+ ;;
+default)
+ default_subcommand "$@"
+ break
+ ;;
+*) show_usage_fail "unrecognized subcommand \"$subcommand\""
+ ;;
+esac
--- /dev/null
+#!/bin/sh -euf
+
+# Copyright 2013 Intel Corporation
+# Author: Artem Bityutskiy
+# License: GPLv2
+
+PROG="setup-ivi-boot"
+VER="1.0"
+
+srcdir="$(readlink -ev -- ${0%/*})"
+PATH="/usr/share/setup-ivi:$srcdir:$PATH"
+
+. setup-ivi-sh-functions
+. installerfw-sh-functions
+
+# This is a small trick which I use to make sure my scripts are portable -
+# check if 'dash' is present, and if yes - use it.
+if can_switch_to_dash; then
+ exec dash -euf "$srcdir/$PROG" "$@"
+ exit $?
+fi
+
+install_gummiboot()
+{
+ verbose "installing gummiboot to $bootdir"
+
+ local installdir="$bootdir/EFI/boot"
+ local gummiboot_path="$(installerfw_mnt_prefix "/usr/lib/gummiboot")"
+
+ # Make sure gummiboot is installed in the system
+ if ! ([ -f $gummiboot_path/gummibootia32.efi ] || \
+ [ -f $gummiboot_path/gummibootx64.efi ]); then
+ fatal "\"$gummiboot_path/gummiboot*.efi\" files not found!"
+ fi
+
+ # Install gummiboot
+ mkdir -p $verbose "$installdir" >&2
+ [ -f "$gummiboot_path/gummibootia32.efi" ] && \
+ cp $verbose "$gummiboot_path/gummibootia32.efi" \
+ "$installdir/bootia32.efi" >&2
+ [ -f "$gummiboot_path/gummibootx64.efi" ] && \
+ cp $verbose "$gummiboot_path/gummibootx64.efi" \
+ "$installdir/bootx64.efi"
+
+ verbose "installed gummiboot to $bootdir"
+}
+
+install_extlinux()
+{
+ verbose "installing extlinux to $bootdir"
+
+ local installdir="$bootdir/extlinux"
+ local extlinux="extlinux"
+
+ # Check if extlinux is available
+ if ! command -v "extlinux" >/dev/null 2>&1; then
+ extlinux="$(installerfw_mnt_prefix "/sbin/extlinux")"
+ [ -f "$extlinux" ] ||
+ fatal "cannot find \"$extlinux\""
+ fi
+
+ # Get device node name for the boot partition
+ local boot_devnode
+ installerfw_get_part_info "/boot" "DEVNODE_NOW" "boot_devnode"
+ [ -n "$boot_devnode" ] || \
+ fatal "cannot find device node of the boot disk, probably" \
+ "INSTALLERFW_PARTx_DEVNODE_NOW environment" \
+ "variable is not defined"
+
+ # Install extlinux
+ mkdir -p $verbose "$installdir" >&2
+ "$extlinux" --device "$boot_devnode" -i "$installdir" || \
+ fatal "cannot install extlinux to \"$installdir\"" \
+ "(requires extlinux version 5 or greater)"
+
+
+ # Get device node name for the boot disk
+ local mbr_devnode
+ installerfw_get_part_info "/boot" "DISK_DEVNODE_NOW" "mbr_devnode"
+ [ -n "$mbr_devnode" ] || \
+ fatal "cannot find device node of the boot disk, probably" \
+ "INSTALLERFW_PARTx_DISK_DEVNODE_NOW environment" \
+ "variable is not defined"
+
+ # Install the MBR part of extlinux
+ local mbr_bin="$(installerfw_mnt_prefix "/usr/share/syslinux/gptmbr.bin")"
+ dd if="$mbr_bin" of="$mbr_devnode" count=1 || \
+ fatal "cannot install MBR: dd if=$mbr_bin of=$mbr_devnode"
+
+ verbose "installed extlinux to $bootdir"
+}
+
+show_usage()
+{
+ cat <<-EOF
+Usage: $PROG [options]
+
+Install the EFI bootloader (gummiboot) and create the initial configuration
+for all the currently installed kernels. This program depends on various
+"installer framework" variables.
+
+Options:
+ -v, --verbose be verbose
+ --version show the program version and exit
+ -h, --help show this text and exit
+EOF
+}
+
+show_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_usage >&2
+ exit 1
+}
+
+# Parse the options
+tmp=`getopt -n $PROG -o v,h --long verbose,version,help -- "$@"` ||
+ show_usage_fail "cannot parse command-line options"
+eval set -- "$tmp"
+
+verbose=
+while true; do
+ case "$1" in
+ -v|--verbose)
+ verbose="-v"
+ ;;
+ --version)
+ printf "%s\n" "$VER"
+ exit 0
+ ;;
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+done
+
+bootdir="$(installerfw_mnt_prefix "/boot")"
+
+# Save the installer framework variables
+installerfw_file="$(installerfw_get_env_file_name)"
+if [ -f "$installerfw_file" ]; then
+ installerfw_restore_env
+else
+ installerfw_save_env
+fi
+
+# Get OS name
+get_os_name "os_name"
+
+if installerfw_is_efi_boot_system; then
+ install_gummiboot
+else
+ install_extlinux
+fi
+
+# Create bootloader entries for each kernel
+kernels="$(ls -1 "$bootdir" | LC_ALL=C grep "^vmlinuz-" | sort -r)"
+
+[ -n "$kernels" ] || \
+ fatal "no kernels (vmlinuz-*) found in \"$bootdir\""
+
+printf "%s\n" "$kernels" | while IFS= read -r kernel; do
+ setup-ivi-bootloader-conf $verbose add --force "$kernel"
+done
+
+# Set the default kernel to the kernel with highest version
+newest_kernel="$(get_newest_kernel "$bootdir")"
+setup-ivi-bootloader-conf $verbose default "$newest_kernel"
--- /dev/null
+#!/bin/sh -euf
+
+# Copyright 2013 Intel Corporation
+# Author: Artem Bityutskiy
+# License: GPLv2
+
+PROG="setup-ivi-bootloader-conf"
+VER="1.0"
+
+srcdir="$(readlink -ev -- ${0%/*})"
+PATH="/usr/share/setup-ivi:$srcdir:$PATH"
+
+. setup-ivi-sh-functions
+. installerfw-sh-functions
+
+# This is a small trick which I use to make sure my scripts are portable -
+# check if 'dash' is present, and if yes - use it.
+if can_switch_to_dash; then
+ exec dash -euf "$srcdir/$PROG" "$@"
+ exit $?
+fi
+
+# Preparation stuff common for all subcommands
+prepare()
+{
+ # Get the installer framework environment
+ installerfw_restore_env
+
+ bootdir="$(installerfw_mnt_prefix "/boot")"
+
+ if installerfw_is_efi_boot_system; then
+ boot="gummiboot"
+ else
+ boot="extlinux"
+ fi
+}
+
+#
+# -----------------------------------------------------------------------------
+# The "add" subcommand
+# -----------------------------------------------------------------------------
+#
+
+show_add_usage()
+{
+ cat <<-EOF
+Usage: $PROG add [options] <kernel>
+
+Add bootloader entries for kernel <kernel>.
+
+Options:
+ -f, --force if bootloader entries for <kernel> already exist in bootloader's
+ config file(s) - re-write them, if <kernel> does not exist - do
+ not fail
+ -h, --help show this text and exit
+EOF
+}
+
+show_add_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_add_usage >&2
+ exit 1
+}
+
+add_subcommand()
+{
+ if [ "$#" -eq 0 ]; then
+ show_add_usage
+ exit 0
+ fi
+
+ local tmp
+ tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
+ show_add_usage_fail "cannot parse command-line options"
+ eval set -- "$tmp"
+
+ local force=
+ while true; do
+ case "$1" in
+ -f|--force)
+ force="-f"
+ ;;
+ -h|--help)
+ show_add_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_add_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+ done
+
+ if [ "$#" -lt 1 ]; then
+ show_add_usage_fail "please, specify the kernel"
+ fi
+ if [ "$#" -gt 1 ]; then
+ show_add_usage_fail "too many arguments: \"$1\""
+ fi
+
+ prepare
+
+ local kernel="$1"
+ local kernel_path="$bootdir/$kernel"
+
+ if ! [ -f "$kernel_path" ] && [ -z "$force" ]; then
+ fatal "cannot find kernel \"$kernel_path\"" \
+ "(use -f to ignore this error)"
+ fi
+
+ # Get root partition PARTUUID
+ installerfw_get_part_info "/" "PARTUUID" "root_partuuid"
+ [ -n "$root_partuuid" ] || \
+ fatal "cannot find PARTUUID of the root partition"
+
+ # Get kernel options
+ local options="${INSTALLERFW_KERNEL_OPTS:-} root=PARTUUID=$root_partuuid"
+
+ # Get OS name
+ local os_name=
+ get_os_name "os_name"
+
+ # Add the bootloader entry
+ setup-$boot-conf $verbose --bootdir "$bootdir" add $force \
+ "$kernel" "$os_name" "$kernel" "$options"
+
+ # If there is the "quiet" option, create a non-quiet configuration
+ local dbgopts="$(printf "%s" "$options" | LC_ALL=C \
+ sed -e "s/[[:blank:]]\+quiet[[:blank:]]\+/ /
+ s/^quiet[[:blank:]]\+//
+ s/[[:blank:]]\+quiet$//
+ s/^quiet$//")"
+
+ dbgopts="$dbgopts ignore_loglevel initcall_debug log_buf_len=2M"
+
+ setup-$boot-conf $verbose --bootdir "$bootdir" add \
+ $force "$kernel-debug" "$os_name (debug)" \
+ "$kernel" "$dbgopts"
+}
+
+#
+# -----------------------------------------------------------------------------
+# The "remove" subcommand
+# -----------------------------------------------------------------------------
+#
+
+show_remove_usage()
+{
+ cat <<-EOF
+Usage: $PROG remove [options] <kernel>
+
+Delete bootloader entries for kernel <kernel> (only those which were previously
+created with "$PROG add").
+
+Options:
+ -f, --force do not fail if <kernel> does not have corresponding bootloader
+ entries
+ -h, --help show this text and exit
+EOF
+}
+
+show_remove_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_remove_usage >&2
+ exit 1
+}
+
+remove_subcommand()
+{
+ if [ "$#" -eq 0 ]; then
+ show_remove_usage
+ exit 0
+ fi
+
+ local tmp
+ tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
+ show_remove_usage_fail "cannot parse command-line options"
+ eval set -- "$tmp"
+
+ local force=
+ while true; do
+ case "$1" in
+ -f|--force)
+ force="-f"
+ ;;
+ -h|--help)
+ show_remove_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_remove_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+ done
+
+ if [ "$#" -lt 1 ]; then
+ show_add_usage_fail "please, specify the kernel"
+ fi
+ if [ "$#" -gt 1 ]; then
+ show_remove_usage_fail "too many arguments: \"$1\""
+ fi
+
+ local kernel="$1"
+
+ prepare
+
+ # Get the current default entry
+ local default="$(setup-$boot-conf $verbose --bootdir "$bootdir" \
+ default $force)"
+ [ $? -eq 0 ] || \
+ fatal "cannot get the default kernel, setup-$boot-conf failed"
+
+ local default_kernel="$(printf "%s" "$default" | LC_ALL=C \
+ sed -n -e 's/^kernel: \(.\+\)$/\1/p')"
+
+ if [ -n "$default_kernel" ]; then
+ verbose "current default boot kernel is " \
+ "\"$default_kernel\""
+ else
+ verbose "did not find the default kernel," \
+ "setup-$boot-conf returned: $default"
+ fi
+
+ # Remove the kernel
+ setup-$boot-conf $verbose --bootdir "$bootdir" \
+ remove $force "$kernel" || \
+ fatal "setup-$boot-conf failed to remove" \
+ "entry \"$kernel\""
+ setup-$boot-conf $verbose --bootdir "$bootdir" \
+ remove $force "$kernel-verbose" || \
+ fatal "setup-$boot-conf failed to remove" \
+ "entry \"$kernel-verbose\""
+
+ # If this is not the default kernel, we are done
+ [ "$kernel" = "$default_kernel" ] || return 0
+
+ # We've just removed the default kernel, find the kernel with the
+ # latest version and make it to be the default
+
+ verbose "removed the default kernel, find the newest available"
+
+ local newest_kernel="$(get_newest_kernel "$bootdir" "$kernel")"
+
+ if [ -z "$newest_kernel" ]; then
+ verbose "no more kernels, set the kernel to none"
+ setup-$boot-conf $verbose --bootdir "$bootdir" \
+ default --force "<none>"
+ else
+ verbose "new default kernel is \"$newest_kernel\""
+ setup-$boot-conf $verbose --bootdir "$bootdir" \
+ default "$newest_kernel"
+ fi
+
+ if [ "$?" -ne 0 ]; then
+ fatal "cannot set default kernel, \"setup-$boot-conf\" failed"
+ fi
+}
+
+#
+# -----------------------------------------------------------------------------
+# The "default" subcommand
+# -----------------------------------------------------------------------------
+#
+
+show_default_usage()
+{
+ cat <<-EOF
+Usage: $PROG default [options] <kernel>
+
+Set the default boot kernel to <kernel>. If <kernel> is omited, print the
+current default boot kernel name.
+
+Options:
+ -f, --force do not fail if <kernel> doesn't exist
+ -h, --help show this text and exit
+EOF
+}
+
+show_default_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_default_usage >&2
+ exit 1
+}
+
+default_subcommand()
+{
+ local tmp
+ tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
+ show_default_usage_fail "cannot parse command-line options"
+ eval set -- "$tmp"
+
+ local force=
+ while true; do
+ case "$1" in
+ -f|--force)
+ force="-f"
+ ;;
+ -h|--help)
+ show_default_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_default_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+ done
+
+ if [ "$#" -gt 1 ]; then
+ show_default_usage_fail "too many arguments: \"$1\""
+ fi
+
+ prepare
+
+ local kernel="${1:-}"
+ local kernel_path="$bootdir/$kernel"
+
+ if [ -n "$kernel" ] && ! [ -f "$kernel_path" ] && [ -z "$force" ]; then
+ fatal "cannot find kernel \"$kernel_path\"" \
+ "(use -f to ignore this error)"
+ fi
+
+ setup-$boot-conf $verbose --bootdir "$bootdir" default $force "$kernel"
+}
+
+#
+# -----------------------------------------------------------------------------
+#
+
+show_usage()
+{
+ cat <<-EOF
+Usage: $PROG [options] <subcommand> [options] <arguments>
+
+This program adds or removes a kernel to/from the bootloader configuration
+file(s). This is a Tizen IVI-specific program and it currently supports only 2
+bootloader types - extlinux and gummiboot. Each new kernel gets 2 boot menu
+entries - the default and verbose, and both of these are removed by the
+"remove" subcommand.
+
+The supported subcommands are:
+ add - add bootloader entries for a kernel
+ remove - remove bootloader entries for a kernel
+ default - get or set the default boot kernel
+
+Run "$PROG <subcommand>" to see subcommand-specific help.
+
+Options:
+ --version show the program version and exit
+ -v, --verbose be verbose
+ -h, --help show this text and exit
+EOF
+}
+
+show_usage_fail()
+{
+ IFS= printf "%s\n\n" "$PROG: error: $*" >&2
+ show_usage >&2
+ exit 1
+}
+
+verbose=
+while [ -n "${1:-""}" ] && [ -z "${1##-*}" ]; do
+ case "$1" in
+ --version)
+ printf "%s\n" "$VER"
+ exit 0
+ ;;
+ -v|--verbose)
+ verbose="-v"
+ ;;
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ --) shift; break
+ ;;
+ *) show_usage_fail "unrecognized option \"$1\""
+ ;;
+ esac
+ shift
+done
+
+if [ "$#" -eq 0 ]; then
+ show_usage
+ exit 0
+fi
+
+# Parse subcommands
+
+subcommand="$1"; shift
+
+case "$subcommand" in
+add)
+ add_subcommand "$@"
+ break
+ ;;
+remove)
+ remove_subcommand "$@"
+ break
+ ;;
+default)
+ default_subcommand "$@"
+ break
+ ;;
+*) show_usage_fail "unrecognized subcommand \"$subcommand\""
+ ;;
+esac
--- /dev/null
+# Copyright 2013 Intel Corporation
+# Author: Artem Bityutskiy
+# License: GPLv2
+
+# This file contains common functions for setup-ivi-* programs
+
+# Own name
+__PROG="$PROG:-setup-ivi-sh-functions"
+
+fatal()
+{
+ IFS= printf "%s\n" "$PROG: error: $*" 1>&2
+ exit 1
+}
+
+verbose()
+{
+ if [ -n "$verbose" ]; then
+ IFS= printf "%s\n" "$PROG (verbose): $*" >&2
+ fi
+}
+
+# Finds out the OS name and sets the "$1" variable to the OS name upon exit.
+get_os_name()
+{
+ local osrelease_path="$(installerfw_mnt_prefix "$__osrelease_file")"
+
+ # Make sure the OS release information file is present
+ [ -f "$osrelease_path" ] ||
+ fatal "the \"$osrelease_path\" file not found"
+
+ # Get the OS name
+ local __os_name="$(LC_ALL=C sed -n -e 's/^PRETTY_NAME="\(.*\)"$/\1/p' "$osrelease_path")"
+ [ -n "$__os_name" ] || \
+ fatal "cannot find \"PRETTY_NAME\" variable in \"$osrelease_path\""
+
+ if [ "${1:-%}" != "%" ]; then
+ eval $1="\$__os_name"
+ verbose "get_os_name(): OS name: $1=$__os_name"
+ fi
+}
+
+# Escape a string which is going to be used in a regexp. Shuould work for both
+# sed and grep regexps.
+esc_regexp()
+{
+ local regexp="$1";
+
+ printf "%s" "$regexp" | LC_ALL=C sed -e 's/[]\/()$*.^|[]/\\&/g'
+}
+
+# Escape a string which is going to be used at the "replacement" part of the
+# sed "substitute" command (as in s/regexp/replacement/flags')
+# Usage: esc_sed_replacement <replacement>
+esc_sed_replacement()
+{
+ local replacement="$1";
+
+ printf "%s" "$replacement" | LC_ALL=C sed -e "s/[\&/]/\\&/g"
+}
+
+# Turn strings "abc" into "[Aa][Bb][Cc]" for case-insensitive matching in
+# regular expressions.
+case_insensitive_regexp()
+{
+ local regexp="$1"
+
+ printf "%s" "$regexp" | LC_ALL=C sed -e 's/[[:alpha:]]/[\U&\l&]/g'
+}
+
+# Check if dash is available and we are not running in dash
+can_switch_to_dash()
+{
+ if command -v "dash" >/dev/null 2>&1; then
+ if [ -n "${BASH_VERSION:-}" ]; then
+ return 0
+ fi
+ fi
+
+ return 1
+}
+
+# Get the newest kernel, "$1" is the directory to search at, "$2" is an
+# optional argument, and if it present, it tells which kernel should not be
+# returned by this function.
+get_newest_kernel()
+{
+ local bootdir="$1"; shift
+
+ # Generate the list of installed kernels
+ local kernels="$(ls -1 "$bootdir" | LC_ALL=C grep "^vmlinuz-" | sort -r)"
+
+ # Exclude the unwanted kernel, if any
+ if [ -n "${1:-}" ]; then
+ local kernel="$(esc_regexp "$1")"
+ kernels="$(printf "%s" "$kernels" | LC_ALL=C grep -v "^$kernel$")"
+ fi
+
+ printf "%s" "$kernels" | head -n1
+}
+
+# Remove all empty lines from the end of file, including lines which contain
+# nothing but blanks (tabs and spaces).
+remove_trailing_empty_lines()
+{
+ local file="$1"
+
+ LC_ALL=C sed -i -n -e '
+ :l # sed jump lable named "l"
+ /^[[:blank:]\n]*$/ { # matches multiple blank lines with any
+ # number of spaces or tabs
+ $d # if these are last lines, delete them
+ N; # otherwise append to the current pattern buf
+ bl # and start over
+ }
+ /^[[:blank:]]*$/!p # print the pattern buffer for non-blank lines
+ ' "$file"
+}