mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-18 20:47:55 +00:00
a767347afd
LOG() is added to log to the log only (not kmsg, more verbose than TRACE). DO_WITH_DEBUG only captures stdout/stderr to the log with LOG(). kexec-boot silences stderr from kexec, we don't want it on the console. No need to repeat the kexec command when asking in debug to continue boot, it's no longer hidden behind verbose output from kexec. Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
179 lines
4.2 KiB
Bash
Executable File
179 lines
4.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Launches kexec from saved configuration entries
|
|
set -e -o pipefail
|
|
. /tmp/config
|
|
. /etc/functions
|
|
|
|
TRACE_FUNC
|
|
|
|
dryrun="n"
|
|
printfiles="n"
|
|
printinitrd="n"
|
|
while getopts "b:e:r:a:o:fi" arg; do
|
|
case $arg in
|
|
b) bootdir="$OPTARG" ;;
|
|
e) entry="$OPTARG" ;;
|
|
r) cmdremove="$OPTARG" ;;
|
|
a) cmdadd="$OPTARG" ;;
|
|
o) override_initrd="$OPTARG" ;;
|
|
f) dryrun="y"; printfiles="y" ;;
|
|
i) dryrun="y"; printinitrd="y" ;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$bootdir" -o -z "$entry" ]; then
|
|
die "Usage: $0 -b /boot -e 'kexec params|...|...'"
|
|
fi
|
|
|
|
bootdir="${bootdir%%/}"
|
|
|
|
kexectype=`echo $entry | cut -d\| -f2`
|
|
kexecparams=`echo $entry | cut -d\| -f3- | tr '|' '\n'`
|
|
kexeccmd="kexec"
|
|
|
|
cmdadd="$CONFIG_BOOT_KERNEL_ADD $cmdadd"
|
|
cmdremove="$CONFIG_BOOT_KERNEL_REMOVE $cmdremove"
|
|
|
|
if [ "$(load_config_value CONFIG_USE_BLOB_JAIL)" = "y" ]; then
|
|
cmdadd="$cmdadd firmware_class.path=/firmware/"
|
|
fi
|
|
|
|
fix_file_path() {
|
|
if [ "$printfiles" = "y" ]; then
|
|
# output file relative to local boot directory
|
|
echo ".$firstval"
|
|
fi
|
|
|
|
filepath="$bootdir$firstval"
|
|
|
|
if ! [ -r $filepath ]; then
|
|
die "Failed to find file $firstval"
|
|
fi
|
|
}
|
|
|
|
adjusted_cmd_line="n"
|
|
adjust_cmd_line() {
|
|
if [ -n "$cmdremove" ]; then
|
|
for i in $cmdremove; do
|
|
cmdline=$(echo $cmdline | sed "s/\b$i\b//g")
|
|
done
|
|
fi
|
|
|
|
if [ -n "$cmdadd" ]; then
|
|
cmdline="$cmdline $cmdadd"
|
|
fi
|
|
adjusted_cmd_line="y"
|
|
}
|
|
|
|
if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then
|
|
#If expecting debug output, have kexec load (-l) output debug info
|
|
kexeccmd="$kexeccmd -d"
|
|
fi
|
|
|
|
module_number="1"
|
|
while read line
|
|
do
|
|
key=`echo $line | cut -d\ -f1`
|
|
firstval=`echo $line | cut -d\ -f2`
|
|
restval=`echo $line | cut -d\ -f3-`
|
|
if [ "$key" = "kernel" ]; then
|
|
fix_file_path
|
|
if [ "$kexectype" = "xen" ]; then
|
|
# always use xen with custom arguments
|
|
kexeccmd="$kexeccmd -l $filepath"
|
|
kexeccmd="$kexeccmd --command-line \"$restval no-real-mode reboot=no vga=current\""
|
|
elif [ "$kexectype" = "multiboot" ]; then
|
|
kexeccmd="$kexeccmd -l $filepath"
|
|
kexeccmd="$kexeccmd --command-line \"$restval\""
|
|
elif [ "$kexectype" = "elf" ]; then
|
|
DEBUG "kexectype= $kexectype"
|
|
DEBUG "restval= $restval"
|
|
DEBUG "filepath= $filepath"
|
|
kexeccmd="$kexeccmd -l $filepath"
|
|
DEBUG "kexeccmd= $kexeccmd"
|
|
else
|
|
DEBUG "unknown kexectype!!!!"
|
|
kexeccmd="$kexeccmd -l $filepath"
|
|
fi
|
|
fi
|
|
if [ "$key" = "module" ]; then
|
|
fix_file_path
|
|
cmdline="$restval"
|
|
if [ "$kexectype" = "xen" ]; then
|
|
if [ "$module_number" -eq 1 ]; then
|
|
adjust_cmd_line
|
|
elif [ "$module_number" -eq 2 ]; then
|
|
if [ "$printinitrd" = "y" ]; then
|
|
# output the current path to initrd
|
|
echo $filepath
|
|
fi
|
|
if [ -n "$override_initrd" ]; then
|
|
filepath="$override_initrd"
|
|
fi
|
|
fi
|
|
fi
|
|
module_number=`expr $module_number + 1`
|
|
kexeccmd="$kexeccmd --module \"$filepath $cmdline\""
|
|
fi
|
|
if [ "$key" = "initrd" ]; then
|
|
fix_file_path
|
|
if [ "$printinitrd" = "y" ]; then
|
|
# output the current path to initrd
|
|
echo $filepath
|
|
fi
|
|
if [ -n "$override_initrd" ]; then
|
|
filepath="$override_initrd"
|
|
fi
|
|
firmware_initrd="$(inject_firmware.sh "$filepath" || true)"
|
|
if [ -n "$firmware_initrd" ]; then
|
|
filepath="$firmware_initrd"
|
|
fi
|
|
kexeccmd="$kexeccmd --initrd=$filepath"
|
|
fi
|
|
if [ "$key" = "append" ]; then
|
|
cmdline="$firstval $restval"
|
|
adjust_cmd_line
|
|
kexeccmd="$kexeccmd --append=\"$cmdline\""
|
|
fi
|
|
done << EOF
|
|
$kexecparams
|
|
EOF
|
|
|
|
if [ "$adjusted_cmd_line" = "n" ]; then
|
|
if [ "$kexectype" = "elf" ]; then
|
|
kexeccmd="$kexeccmd --append=\"$cmdadd\""
|
|
else
|
|
die "Failed to add required kernel commands: $cmdadd"
|
|
fi
|
|
fi
|
|
|
|
if [ "$dryrun" = "y" ]; then exit 0; fi
|
|
|
|
echo "Loading the new kernel:"
|
|
echo "$kexeccmd"
|
|
# DO_WITH_DEBUG captures the debug output from stderr to the log, we don't need
|
|
# it on the console as well
|
|
DO_WITH_DEBUG eval "$kexeccmd" 2>/dev/null \
|
|
|| die "Failed to load the new kernel"
|
|
|
|
if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then
|
|
#Ask user if they want to continue booting without echoing back the input (-s)
|
|
read -s -n 1 -p "[DEBUG] Continue booting? [Y/n]: " debug_boot_confirm
|
|
echo
|
|
if [ "${debug_boot_confirm^^}" = N ]; then
|
|
# abort
|
|
die "Boot aborted"
|
|
fi
|
|
fi
|
|
|
|
if [ "$CONFIG_TPM" = "y" ]; then
|
|
tpmr kexec_finalize
|
|
fi
|
|
|
|
if [ -x /bin/io386 -a "$CONFIG_FINALIZE_PLATFORM_LOCKING_PRESKYLAKE" = "y" ]; then
|
|
lock_chip
|
|
fi
|
|
|
|
echo "Starting the new kernel"
|
|
exec kexec -e
|