[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH OSSTEST v4 21/21] Debian: Arrange to be able to chainload a xen.efi from grub2
Xen cannot (currently) be booted directly via the usual multiboot path on EFI systems of any arch. Instead it is necessary to either launch xen.efi direct from the UEFI shell or to chainload it from grub. In both cases the Xen command line as well as what would normally be the multiboot modules (kernel+command line, XSM policy, initrd) must be configured in a Xen configuration file. Here we add a new overlay/etc/grub.d/15_osstest_uefi grub script which arranges that if a xen.efi is found in the EFI System Partition (as arrange by a previous patch) a suitable entry is created in grub.cfg as well. When parsing the grub.cfg look for such an entry into addition to the regular/multiboot one and when necessary write the configuration file based on the regular entry and return the chainload one such that it gets booted. This is currently enabled only for Jessie ARM64 systems. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- v4: Use a separate grub script snippet, there's nothing we need in 20_linux_xen v3: Rewrap and reindent to avoid long lines Split out boot script --- Osstest/Debian.pm | 77 +++++++++++++++++++++++++++++++++++++- overlay/etc/grub.d/15_osstest_uefi | 49 ++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 2 deletions(-) create mode 100755 overlay/etc/grub.d/15_osstest_uefi diff --git a/Osstest/Debian.pm b/Osstest/Debian.pm index c76d63a..718a7e2 100644 --- a/Osstest/Debian.pm +++ b/Osstest/Debian.pm @@ -400,12 +400,18 @@ sub setupboot_grub2 ($$$$) { my $rmenu= '/boot/grub/grub.cfg'; my $kernkey= (defined $xenhopt ? 'KernDom0' : 'KernOnly'); - + + # Grub2 on Jessie/arm* doesn't do multiboot, so we must chainload. + my $need_uefi_chainload = + get_host_property($ho, "firmware") eq "uefi" && + $ho->{Suite} =~ m/jessie/ && $r{arch} =~ m/^arm/; + my $parsemenu= sub { my $f= bl_getmenu_open($ho, $rmenu, "$stash/$ho->{Name}--grub.cfg.1"); my @offsets = (0); my $entry; + my $chainentry; my $submenu; while (<$f>) { next if m/^\s*\#/ || !m/\S/; @@ -424,7 +430,13 @@ sub setupboot_grub2 ($$$$) { (defined $xenhopt ? qw(Title Hv KernDom0 KernVer) : qw(Title Hv KernOnly KernVer)); - if (@missing) { + if ($need_uefi_chainload && $entry->{Chainload}) { + # Needs to be before check of @missing, since a + # chained entry doesn't have anything useful in it + logm("Found chainload entry at $entry->{StartLine}..$."); + die "already got one" if $chainentry; + $chainentry = $entry; + } elsif (@missing) { logm("(skipping entry at $entry->{StartLine}..$.;". " no @missing)"); } elsif ($entry->{Hv} =~ m/xen-syms/) { @@ -456,9 +468,15 @@ sub setupboot_grub2 ($$$$) { $submenu={ StartLine =>$., MenuEntryPath => join ">", @offsets }; push @offsets,(0); } + if (m/^\s*chainloader\s*\/EFI\/osstest\/xen.efi/) { + die unless $entry; + $entry->{Hv}= $1; + $entry->{Chainload} = 1; + } if (m/^\s*multiboot\s*(?:\/boot)?\/(xen\S+)/) { die unless $entry; $entry->{Hv}= $1; + $entry->{Chainload} = 0; } if (m/^\s*multiboot\s*(?:\/boot)?\/(vmlinu[xz]-(\S+))\s+(.*)/) { die unless $entry; @@ -490,13 +508,68 @@ sub setupboot_grub2 ($$$$) { die unless $entry->{Hv}; } + if ($need_uefi_chainload) { + die 'chainload entry not found' unless $chainentry; + + # Propagate relevant fields of the main entry over to the + # chain entry for use of subsequent code. + foreach (qw(KernVer KernDom0 KernOnly KernOpts + Initrd Xenpolicy)) { + next unless $entry->{$_}; + die if $chainentry->{$_}; + $chainentry->{$_} = $entry->{$_}; + } + + $entry = $chainentry; + } + return $entry; }; $bl->{UpdateConfig}= sub { my ( $ho ) = @_; + + target_editfile_root($ho, '/etc/default/grub', sub { + while (<::EI>) { + next if m/^export GRUB_ENABLE_XEN_UEFI_CHAINLOAD\=/; + print ::EO; + } + print ::EO "export GRUB_ENABLE_XEN_UEFI_CHAINLOAD=\"osstest\"\n" + if $need_uefi_chainload; + }); + target_cmd_root($ho, "update-grub"); + + if ($need_uefi_chainload) { + my $entry= $parsemenu->(); + my $xencfg = <<END; +[global] +default=osstest + +[osstest] +options=$xenhopt +kernel=vmlinuz $entry->{KernOpts} +END + $xencfg .= "ramdisk=initrd.gz\n" if $entry->{Initrd}; + $xencfg .= "xsm=xenpolicy\n" if $entry->{Xenpolicy}; + + target_putfilecontents_root_stash($ho,30,$xencfg, + "/boot/efi/EFI/osstest/xen.cfg"); + + # /boot/efi should be a mounted EFI system partition, and + # /boot/efi/EFI/osstest/xen.efi should already exist. Hence no mkdir + # here. + target_cmd_root($ho, + <<END.($entry->{Initrd}?<<END:"").($entry->{Xenpolicy}?<<END:"")); +set -ex +cp -vL /boot/$entry->{KernDom0} /boot/efi/EFI/osstest/vmlinuz #/ +END +cp -vL /boot/$entry->{Initrd} /boot/efi/EFI/osstest/initrd.gz #/ +END +cp -vL /boot/$entry->{Xenpolicy} /boot/efi/EFI/osstest/xenpolicy #/ +END + } }; $bl->{GetBootKern}= sub { return $parsemenu->()->{$kernkey}; }; diff --git a/overlay/etc/grub.d/15_osstest_uefi b/overlay/etc/grub.d/15_osstest_uefi new file mode 100755 index 0000000..94fbcee --- /dev/null +++ b/overlay/etc/grub.d/15_osstest_uefi @@ -0,0 +1,49 @@ +#! /bin/sh + +set -e + +# grub-mkconfig helper script. +# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see <http://www.gnu.org/licenses/>. + +prefix="/usr" +exec_prefix="${prefix}" +datarootdir="${prefix}/share" + +. "${datarootdir}/grub/grub-mkconfig_lib" + +CLASS="--class gnu-linux --class gnu --class os --class xen" + +chain_xen_entry () { + vendor="$1" + if [ ! -f /boot/efi/EFI/$vendor/xen.efi ] ; then + return + fi + title=$(gettext_quoted "Chainload $vendor Xen") + xmessage="$(gettext_printf "Chainloading $vendor Xen ...")" + printf "menuentry '${title}' ${CLASS} {\n" + prepare_grub_to_access_device \ + `${grub_probe} --target=device /boot/efi/EFI/$vendor/xen.efi` \ + | grub_add_tab + cat <<EOF + echo '$xmessage' + chainloader /EFI/$vendor/xen.efi +} +EOF +} + +for i in ${GRUB_ENABLE_XEN_UEFI_CHAINLOAD} ; do + chain_xen_entry $i +done -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |