mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-21 22:07:52 +00:00
af5eb2edf9
Some device firmware, such as the graphics microcontroller, is needed during the initrd - i915 is often loaded in the initrd, and this is the only chance to load GuC firmware. Device firmware must still be available after the real root is mounted too, so update the custom firmware path in the kernel when the firmware is moved to /run. Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
180 lines
4.2 KiB
Bash
Executable File
180 lines
4.2 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"
|
|
|
|
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"
|
|
eval "$kexeccmd" \
|
|
|| die "Failed to load the new kernel"
|
|
|
|
if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then
|
|
#Repeat kexec command that will be executed since in debug
|
|
DEBUG "kexeccmd= $kexeccmd"
|
|
|
|
#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
|