heads/initrd/bin/kexec-boot
Jonathon Hall 55e5a41eca
tpmr: Add kexec_finalize command to finalize TPM before boot
TPM2 locks the platform heirarchy, flushes transient objects, and
flushes sessions.  (This now cleans up sessions created during
startsession that previously were not cleaned up, although the OS might
flush all sessions as well.)

TPM1 currently does not do anything, but the command is accepted so
kexec-boot does not need to differentiate TPM1/2.

Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
2023-03-08 12:45:49 -05:00

143 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
# Launches kexec from saved configuration entries
set -e -o pipefail
. /tmp/config
. /etc/functions
TRACE "Under /bin/kexec-boot"
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"
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"
}
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\""
else
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
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"
eval "$kexeccmd" \
|| die "Failed to load the new kernel"
if [ "$CONFIG_TPM" = "y" ]; then
tpmr kexec_finalize
fi
echo "Starting the new kernel"
exec kexec -e