nixos/xen: Add v2 bootspec extension with multiboot support
This commit is contained in:
@@ -3,14 +3,15 @@
|
||||
|
||||
export LC_ALL=C
|
||||
|
||||
# Handle input argument and exit if the flag is invalid. See virtualisation.xen.efi.bootBuilderVerbosity below.
|
||||
[[ $# -ne 1 ]] && echo -e "\e[1;31merror:\e[0m xenBootBuilder must be called with exactly one verbosity argument. See the \e[1;34mvirtualisation.xen.efi.bootBuilderVerbosity\e[0m option." && exit 1
|
||||
# Handle input argument and exit if the flag is invalid. See virtualisation.xen.boot.builderVerbosity below.
|
||||
[[ $# -ne 1 ]] && echo -e "\e[1;31merror:\e[0m xenBootBuilder must be called with exactly one verbosity argument. See the \e[1;34mvirtualisation.xen.boot.builderVerbosity\e[0m option." && exit 1
|
||||
|
||||
case "$1" in
|
||||
"quiet") true ;;
|
||||
"default" | "info") echo -n "Installing Xen Project Hypervisor boot entries..." ;;
|
||||
"debug") echo -e "\e[1;34mxenBootBuilder:\e[0m called with the '$1' flag" ;;
|
||||
*)
|
||||
echo -e "\e[1;31merror:\e[0m xenBootBuilder was called with an invalid argument. See the \e[1;34mvirtualisation.xen.efi.bootBuilderVerbosity\e[0m option."
|
||||
echo -e "\e[1;31merror:\e[0m xenBootBuilder was called with an invalid argument. See the \e[1;34mvirtualisation.xen.boot.builderVerbosity\e[0m option."
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
@@ -46,8 +47,26 @@ for gen in "${gens[@]}"; do
|
||||
|
||||
# We do nothing if the Bootspec for the current $gen does not contain the Xen
|
||||
# extension, which is added as a configuration attribute below.
|
||||
# We determine this by checking for the v1 or v2 bootspec extension,
|
||||
# and setting the appropriate attributes based on version
|
||||
xenSpecVer=""
|
||||
xenParamVar=""
|
||||
xenEfiPath=""
|
||||
if grep -sq '"org.xenproject.bootspec.v1"' "$bootspecFile"; then
|
||||
[ "$1" = "debug" ] && echo -e " \e[1;32msuccess:\e[0m found Xen entries in $gen."
|
||||
xenSpecVer="v1"
|
||||
xenParamVar="xenParams"
|
||||
xenEfiPath="xen"
|
||||
fi
|
||||
# We prefer the v2 extension, so if both are present somehow,
|
||||
# we will use the v2 attributes
|
||||
if grep -sq '"org.xenproject.bootspec.v2"' "$bootspecFile"; then
|
||||
xenSpecVer="v2"
|
||||
xenParamVar="params"
|
||||
xenEfiPath="efiPath"
|
||||
fi
|
||||
# Check for a valid Xen spec being detected
|
||||
if [ -n "$xenSpecVer" ]; then
|
||||
[ "$1" = "debug" ] && echo -e " \e[1;32msuccess:\e[0m found $xenSpecVer Xen entries in $gen."
|
||||
|
||||
# TODO: Support DeviceTree booting. Xen has some special handling for DeviceTree
|
||||
# attributes, which will need to be translated in a boot script similar to this
|
||||
@@ -63,7 +82,7 @@ for gen in "${gens[@]}"; do
|
||||
# the corresponding nixos generation, substituting `nixos` with `xen`:
|
||||
# `xen-$profile-generation-$number-specialisation-$specialisation.{cfg,conf}`
|
||||
xenGen=$(echo "$gen" | sed 's_/loader/entries/nixos_/loader/entries/xen_g;s_^.*/xen_xen_g;s_.conf$__g')
|
||||
bootParams=$(jq -re '."org.xenproject.bootspec.v1".xenParams | join(" ")' "$bootspecFile")
|
||||
bootParams=$(jq -re ".\"org.xenproject.bootspec.$xenSpecVer\".$xenParamVar | join(\" \")" "$bootspecFile")
|
||||
kernel=$(jq -re '."org.nixos.bootspec.v1".kernel | sub("^/nix/store/"; "") | sub("/bzImage"; "-bzImage.efi")' "$bootspecFile")
|
||||
kernelParams=$(jq -re '."org.nixos.bootspec.v1".kernelParams | join(" ")' "$bootspecFile")
|
||||
initrd=$(jq -re '."org.nixos.bootspec.v1".initrd | sub("^/nix/store/"; "") | sub("/initrd"; "-initrd.efi")' "$bootspecFile")
|
||||
@@ -90,7 +109,7 @@ EOF
|
||||
# Create Xen UKI for $generation. Most of this is lifted from
|
||||
# https://xenbits.xenproject.org/docs/unstable/misc/efi.html.
|
||||
[ "$1" = "debug" ] && echo -e "\e[1;34mxenBootBuilder:\e[0m making Xen UKI..."
|
||||
xenEfi=$(jq -re '."org.xenproject.bootspec.v1".xen' "$bootspecFile")
|
||||
xenEfi=$(jq -re ".\"org.xenproject.bootspec.$xenSpecVer\".$xenEfiPath" "$bootspecFile")
|
||||
finalSection=$(objdump --header --wide "$xenEfi" | tail -n +6 | sort --key="4,4" | tail -n 1 | grep -Eo '\.[a-z]*')
|
||||
padding=$(objdump --header --section="$finalSection" "$xenEfi" | awk -v section="$finalSection" '$0 ~ section { printf("0x%016x\n", and(strtonum("0x"$3) + strtonum("0x"$4) + 0xfff, compl(0xfff)))};')
|
||||
[ "$1" = "debug" ] && echo " - padding: $padding"
|
||||
@@ -133,8 +152,8 @@ mapfile -t postGenerations < <(find "$efiMountPoint"/loader/entries -type f -nam
|
||||
# any hypervisor boot entries.
|
||||
if ((${#postGenerations[@]} == 0)); then
|
||||
case "$1" in
|
||||
"default" | "info") echo "none found." && echo -e "If you believe this is an error, set the \e[1;34mvirtualisation.xen.efi.bootBuilderVerbosity\e[0m option to \e[1;34m\"debug\"\e[0m and rebuild to print debug logs." ;;
|
||||
"debug") echo -e "\e[1;34mxenBootBuilder:\e[0m wrote \e[1;31mno generations\e[0m. Most likely, there were no generations with a valid \e[1;34morg.xenproject.bootspec.v1\e[0m entry." ;;
|
||||
"default" | "info") echo "none found." && echo -e "If you believe this is an error, set the \e[1;34mvirtualisation.xen.boot.builderVerbosity\e[0m option to \e[1;34m\"debug\"\e[0m and rebuild to print debug logs." ;;
|
||||
"debug") echo -e "\e[1;34mxenBootBuilder:\e[0m wrote \e[1;31mno generations\e[0m. Most likely, there were no generations with a valid \e[1;34morg.xenproject.bootspec.v1\e[0m or \e[1;34morg.xenproject.bootspec.v2\e[0m entry." ;;
|
||||
esac
|
||||
|
||||
# If the script is successful, change the default boot, say "done.", write a
|
||||
|
||||
Reference in New Issue
Block a user