#!/bin/sh # Copyright 2013, 2016 Patrick Volkerding, Sebeka, Minnesota, USA # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Modified by Didier Spaier, Paris # # This script installs the elilo boot loader, the kernel, and optionally # an initrd into the EFI System Partition. A boot menu entry can also be # installed using efibootmgr. The kernel used will be whatever the symlink # /boot/vmlinuz points to, and if /boot/initrd.gz exists, that will be # installed as the initrd. # # The EFI System Partition is expected to be mounted on /boot/efi before # running this script. export TEXTDOMAIN=slint . gettext.sh TMP=/var/log/setup/tmp # Set the OS root directory (called T_PX for some unknown reason). # If an argument is given to this script and it is a directory, it # is taken to be the root directory. First though, we check for a # directory named $T_PX, and that gets the first priority. if [ ! -d "$T_PX" ]; then if [ ! "$1" = "" ]; then if [ -d "$1" ]; then T_PX="$1" fi else # Are we on the installer image? if [ -r /usr/lib/setup/SeTpartitions ]; then T_PX=/mnt # Or, are we on a running system? elif [ -r /etc/slint-version ]; then T_PX=/ # One more installer-likely thing: elif [ -r /usr/lib/setup/setup ]; then T_PX=/mnt else # We will have to assume we're on an installed and running system. T_PX=/ fi fi fi # Determine the root partition (such as /dev/sda1) ROOT_DEVICE=$2 if [ "$ROOT_DEVICE" = "" ]; then if [ -r $TMP/SeTrootdev ]; then ROOT_DEVICE="$(cat $TMP/SeTrootdev)" else ROOT_DEVICE="$(mount | cut -f 1 -d ' ' | head -n 1)" fi fi # If the system is not running under EFI, skip running this script: if [ ! -d /sys/firmware/efi ]; then if [ "$T_PX" = "/" ]; then gettext "ERROR: System is not running under UEFI." echo fi exit fi # If there's no vfat mounted on /boot/efi or /mnt/boot/efi, forget it: if ! mount | grep vfat | grep -wq /boot/efi ; then if ! mount | grep vfat | grep -wq /mnt/boot/efi ; then if [ "$T_PX" = "/" ]; then gettext "ERROR: No EFI System Partition mounted on /boot/efi." echo fi exit fi fi # Figure out the device and partition number of the ESP: DEVLEN=8 PARTLEN=9 if mount | grep vfat | grep -wq /boot/efi ; then mount | grep vfat | grep -w /boot/efi | grep -q -e nvme -e mmcblk && DEVLEN=12 && PARTLEN=14 EFI_DEVICE=$(mount | grep vfat | grep -w /boot/efi | cut -b 1-${DEVLEN}) EFI_PARTITION=$(mount | grep vfat | grep -w /boot/efi | cut -f 1 -d ' ' | cut -b ${PARTLEN}- | tr -d [a-z]) else mount | grep vfat | grep -w /mnt/boot/efi | grep -q -e nvme -e mmcblk && DEVLEN=12 && PARTLEN=14 EFI_DEVICE=$(mount | grep vfat | grep -w /mnt/boot/efi | cut -b 1-${DEVLEN}) EFI_PARTITION=$(mount | grep vfat | grep -w /mnt/boot/efi | cut -f 1 -d ' ' | cut -b ${PARTLEN}- | tr -d [a-z]) fi # There better be a kernel: if [ ! -r $T_PX/boot/vmlinuz ]; then if [ "$T_PX" = "/" ]; then gettext "ERROR: No kernel found at /boot/vmlinuz." echo fi exit fi dialog --visit-items --title "`gettext "INSTALL ELILO"`" \ --backtitle "`gettext "ELILO (EFI Linux Loader) installation"`" \ --menu "`gettext "ELILO is a Linux boot loader for \ EFI based systems. Installing ELILO will allow you to boot your Linux \ system from the hard drive after selecting it from the UEFI boot menu. \ Since an EFI System Partition was detected on this machine, it is \ recommended that you install ELILO now. Please select an option:"`" \ 0 0 0 \ "install" "`gettext "Install ELILO on the EFI System Partition"`" \ "skip" "`gettext "Do not install ELILO"`" 2> $TMP/reply if [ $? = 1 -o $? = 255 ]; then exit fi REPLY="`cat $TMP/reply`" rm -f $TMP/reply if [ "$REPLY" = "skip" ]; then exit fi mkdir -p $T_PX/boot/efi/EFI/Slint 1> /dev/null 2> /dev/null # If the firmware ships an EFI shell, use it to run elilo aka elilo.efi. cp $P_TX/boot/{customization.msg,help.msg,message.msg} $T_PX/boot/efi/EFI/Slint echo "EFI\Slint\elilo" > $T_PX/boot/efi/startup.nsh cat << EOF > $T_PX/boot/efi/EFI/Slint/elilo.conf chooser=textmenu prompt timeout=200 # # the files containing the text (with attributes) to display # message=message.msg # # files to load when the corresponding function key is pressed # f1=help.msg f2=customization.msg EOF # I hope that the user didn't just change the symlink /boot/vmlinuz - Didier SLINTVERSION=$(<$T_PX/etc/slint-version) cp -a $T_PX/boot/elilo-x86_64.efi $T_PX/boot/efi/EFI/Slint/elilo.efi 1> /dev/null 2> /dev/null cp $T_PX/boot/vmlinuz $T_PX/boot/efi/EFI/Slint 1> /dev/null 2> /dev/null cat << EOF >> $T_PX/boot/efi/EFI/Slint/elilo.conf image=vmlinuz label=Slint description="Start $SLINTVERSION" EOF touch -r $T_PX/boot/vmlinuz $T_PX/boot/efi/EFI/Slint/vmlinuz if [ -r $T_PX/boot/initrd.gz ]; then cp $T_PX/boot/initrd.gz $T_PX/boot/efi/EFI/Slint 1> /dev/null 2> /dev/null touch -r $T_PX/boot/initrd.gz $T_PX/boot/efi/EFI/Slint/initrd.gz cat << EOF >> $T_PX/boot/efi/EFI/Slint/elilo.conf initrd=Slint/initrd.gz EOF fi cat << EOF >> $T_PX/boot/efi/EFI/Slint/elilo.conf read-only append="root=$ROOT_DEVICE vga=normal" EOF dialog --visit-items --title "`gettext "INSTALL BOOT MENU ENTRY?"`" \ --backtitle "`gettext "ELILO (EFI Linux Loader) installation"`" \ --menu "`gettext "Would you like to install \ a boot menu entry so that you can easily select Slint when you boot your \ machine? WARNING: DO NOT install a boot menu entry on Apple hardware. \ Apple computers use a different type of EFI firmware, and efibootmgr has \ been known to damage them. On all other computers, it is recommended to add \ a boot menu entry. Please select an option:"`" \ 0 0 0 \ "install" "`gettext "Install a boot menu entry"`" \ "skip" "`gettext "Do not install a boot menu entry"`" 2> $TMP/reply if [ $? = 1 -o $? = 255 ]; then exit fi REPLY="`cat $TMP/reply`" rm -f $TMP/reply if [ "$REPLY" = "skip" ]; then exit fi if [ ! -d /sys/firmware/efi/vars ]; then modprobe efivars 1> /dev/null 2> /dev/null sleep 1 # Probably not needed, but playing it safe fi # If it's still gone, we fail silently: if [ ! -d /sys/firmware/efi/vars ]; then exit fi efibootmgr -v | rev | cut -f 2- | rev | grep Boot0 | grep Slint | while read line ; do # Reject entries that don't exactly match as not our business if [ ! "$(echo $line | cut -f 2- -d ' ')" = "Slint" ]; then continue fi ENTRY="$(efibootmgr -v | grep "^$(echo $line | cut -b1-8)")" dialog --title "`gettext "REMOVE OLD \"Slint\" EFI BOOT ENTRY?"`" \ --backtitle "`gettext "ELILO (EFI Linux Loader) installation"`" \ --yesno "`gettext "An old Slint boot entry has been found in your EFI boot menu. \ Would you like to remove this before installing the new Slint boot \ entry? This is recommended. Old EFI boot menu entry:"` $ENTRY" 0 0 if [ ! $? = 0 ]; then continue fi # Remove the boot entry: efibootmgr -q -B -b $(echo $line | cut -b5-8) done efibootmgr -q -c -d $EFI_DEVICE -p $EFI_PARTITION -l "\\EFI\\Slint\\elilo.efi" -L "Slint" efibootmgr -v | rev | cut -f 2- | rev | grep Boot0 | grep Slint | while read line ; do # Reject entries that don't exactly match as not our business if [ ! "$(echo $line | cut -f 2- -d ' ')" = "Slint" ]; then continue fi ENTRY="$(efibootmgr -v | grep "^$(echo $line | cut -b1-8)")" if echo $ENTRY | grep -q -F "\Slint\elilo.efi" ; then dialog --title "`gettext "EFI BOOT ENTRY INSTALLED"`" \ --backtitle "`gettext "ELILO (EFI Linux Loader) installation"`" \ --msgbox "`gettext "A Slint boot entry has been installed to your EFI boot menu. EFI boot menu entry:"` $ENTRY" 0 0 fi done # Done.