mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-19 13:07:58 +00:00
87eff7b775
Blob jail provides device firmware blobs to the OS, so the OS does not have to ship them. The firmware is passed through the initrd to /run/firmware, so it works with both installed and live OSes, and there are no race conditions between firmware load and firmware availability. The injection method in the initrd is specific to the style of init script used by PureOS, since it must add a copy command to copy the firmware from the initrd to /run. If the init script is not of this type, boot proceeds without device firmware. This feature can be enabled or disabled from the config GUI. Blob jail is enabled automatically if the Intel AX200 Wi-Fi module is installed and the feature hasn't been explicitly configured. Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
163 lines
3.7 KiB
Bash
Executable File
163 lines
3.7 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=/run/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_TPM" = "y" ]; then
|
|
tpmr kexec_finalize
|
|
fi
|
|
|
|
echo "Starting the new kernel"
|
|
exec kexec -e
|