diff --git a/elilo-high_base_mem.diff b/elilo-high_base_mem.diff new file mode 100644 index 0000000..900281c --- /dev/null +++ b/elilo-high_base_mem.diff @@ -0,0 +1,66 @@ +--- + x86_64/system.c | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +--- a/x86_64/system.c ++++ b/x86_64/system.c +@@ -44,7 +44,9 @@ + #include "loader.h" + #include "rmswitch.h" + ++#ifndef DEBUG_CREATE_BOOT_PARAMS + #define DEBUG_CREATE_BOOT_PARAMS 0 ++#endif + #if DEBUG_CREATE_BOOT_PARAMS + #define DPR(a) do { if (elilo_opt.debug) { Print a; } } while ( 0 ) + #else +@@ -100,6 +102,7 @@ UINTN sizeof_init_gdt = sizeof init_gdt; + */ + + UINTN high_base_mem = 0x90000; ++VOID *high_base_mem_address = NULL; + + /* + * Highest available extended memory address. +@@ -128,6 +131,30 @@ sysdeps_init(EFI_HANDLE dev) + { + DBG_PRT((L"sysdeps_init()\n")); + ++ DBG_PRT((L"fix high_base_mem and gdt_addr\n")); ++ while (!high_base_mem_address) { ++ high_base_mem_address = alloc_pages(5, EfiLoaderData, ++ AllocateAddress, ++ (void *)high_base_mem); ++ if (!high_base_mem_address) { ++ if (high_base_mem > (1 << 16)) { ++ high_base_mem -= (1 << 16); ++ } else { ++ /* fall back to previous behavior */ ++ high_base_mem = 0x90000; ++ break; ++ } ++ } ++ } ++ if (high_base_mem_address) { ++ VERB_PRT(3, Print(L"high_base_mem="PTR_FMT"\n", ++ high_base_mem_address)); ++ gdt_addr.base = high_base_mem + 0x4000; ++ } else { ++ ERR_PRT((L"Failed to allocate high_base_mem, " ++ "stomping over heritage 0x90000.\n")); ++ } ++ + /* + * Register our loader(s)... + */ +@@ -624,6 +651,10 @@ sysdeps_create_boot_params( + ERR_PRT((L"bp="PTR_FMT" cmdline="PTR_FMT" initrd="PTR_FMT" cookie="PTR_FMT"", + bp, cmdline, initrd, cookie)); + ++ if (high_base_mem_address != NULL) { ++ free(high_base_mem_address); ++ high_base_mem_address = NULL; ++ } + if (param_start != NULL) { + free(param_start); + param_start = NULL; diff --git a/elilo-textmenu-disable-print-devices.diff b/elilo-textmenu-disable-print-devices.diff new file mode 100644 index 0000000..a336369 --- /dev/null +++ b/elilo-textmenu-disable-print-devices.diff @@ -0,0 +1,26 @@ +--- + choosers/textmenu.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/choosers/textmenu.c ++++ b/choosers/textmenu.c +@@ -308,11 +308,19 @@ reprint: + + switch (key.UnicodeChar) { + /* XXX Do we really want this in textmenual mode? */ ++#if 0 ++ /* ++ * Definitely not, as '?' is a valid character on a ++ * kernel command line and sometimes needed for URLs ++ * while booting an installation. (And the output ++ * is barely visible anyhow...) ++ */ + case L'?': + Print(L"\n"); + print_devices(); + first_time = 0; + goto reprint; ++#endif + case CHAR_BACKSPACE: + case CHAR_DEL: + if (PromptLen == 0) break; diff --git a/elilo.changes b/elilo.changes index 15b3c63..c0248e4 100644 --- a/elilo.changes +++ b/elilo.changes @@ -1,3 +1,28 @@ +------------------------------------------------------------------- +Fri Nov 23 14:29:41 UTC 2018 - rw@suse.com + +- elilo.efi + * Try to properly allocate high_base_mem. (bsc#1000769) + (elilo-high_base_mem.diff) + +------------------------------------------------------------------- +Thu Nov 22 16:17:20 UTC 2018 - rw@suse.com + +- elilo.spec + * Work around glitches introduced by gnu-efi. + * Add '-mno-red-zone' to work around Microsoft/SystemV AMD64 ABI + discrepancies. (bsc#953502) +- elilo.pl + * Support 'ucode=' for XEN. (bsc#1102567) + * SecureBoot: Support detached configuration template. + * Add support for 'UUID='/'LABEL=' to specify EFI system partition + and fix bug introduced by NVMe device handling. (bsc#917195) + * Handle NVMe device names. (fate#317591) + * Don't abort, when "skip" is announced. (bsc#917130) +- elilo.efi + * Remove special handling for '?' in textmenu-mode. (bsc#928546) + (elilo-textmenu-disable-print-devices.diff) + ------------------------------------------------------------------- Sat Mar 3 11:12:54 UTC 2018 - bwiedemann@suse.com @@ -13,7 +38,7 @@ Thu Jul 31 12:41:32 UTC 2014 - dimstar@opensuse.org Fri Oct 25 13:37:55 UTC 2013 - rw@suse.de - elilo.efi - * update to elilo-3.16 to fix OBS download check. + * Update to elilo-3.16 to fix OBS download check. Essentially "white-space" changes, plus bumping version number, minus Debian idiosyncrasies. - elilo.spec diff --git a/elilo.pl b/elilo.pl index 58ded54..2423e29 100644 --- a/elilo.pl +++ b/elilo.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# $Id: elilo.pl,v 0.86 2013/10/25 14:22:33 rw Exp $ +# $Id: elilo.pl,v 0.94 2018/11/22 15:48:50 rw Exp $ use strict; my $C = $0; $C =~ s{^.*/}{}; @@ -18,6 +18,7 @@ my %Flist = (); my $Sconf = "$dbg/etc/" . $Fconf; my $Xconf = "xen.cfg"; my $Gconf = "grub.cfg"; +my $GconfT = "$dbg/etc/default/elilo2grub.in"; my @eBinaries = ("elilo.efi", "xen.efi", "shim.efi"); my ($elilo, $xen, $shim) = @eBinaries; @@ -57,7 +58,7 @@ EoD $| = 1; sub Version() { - my $v = q($Revision: 0.86 $ ); + my $v = q($Revision: 0.94 $ ); $v =~ s/^\$ Rev.*:\ ([0-9.]+)\ \$\ /$1/x; $v .= " (part of elilo-$Edition)" if ( $Edition ne "\@EDITION\@" ); print "$C version $v\n"; @@ -226,7 +227,7 @@ sub section2Econf($$%) { my $Xsections = 0; sub section2Xconf($$%) { my( $in, $lnr, %current) = @_; - my( $label, $image, $initrd, $append, $root, $vmm, $vmmopts, $desc); + my( $label, $image, $initrd, $append, $root, $vmm, $vmmopts, $ucode, $desc); if ( ! $current{xencfg} ) { Info( 3, "=== Xconf: skipping ". @@ -256,6 +257,8 @@ sub section2Xconf($$%) { $root = ($root ? " root=$root " : " "); $vmm = (exists( $current{VMM}) ? $current{VMM} : (exists( $Sconf{vmm}) ? $Sconf{vmm} : "")); + $ucode = (exists( $current{ucode}) ? $current{ucode} : + (exists( $Sconf{ucode}) ? $Sconf{ucode} : "")); if ( exists( $current{description}) ) { $desc = $current{description}; } else { @@ -273,6 +276,7 @@ sub section2Xconf($$%) { return( 0 ); } Info( 2, sprintf "=== %2d. Xconf: $label\n", ++$sections); + $Xconf{$label}{ucode} = $ucode if ($ucode); $Xconf{$label}{vmm} = $vmm; $Xconf{$label}{options} = $vmmopts; $Xconf{$label}{kernel} = $image; @@ -289,7 +293,6 @@ sub section2Xconf($$%) { $Xconf{$label}{cfg} = "xen". ++$Xsections .".cfg"; } - return( 0 ); } @@ -344,11 +347,11 @@ sub Parse($$) { $current{$1} = (defined($2)) ? $2 : "true"; next; } - if ( m{^\s*(?:image|initrd|vmm)\s*=\s*} ) { + if ( m{^\s*(?:image|initrd|vmm|ucode)\s*=\s*} ) { my $orig = $_; chomp; s{(vmm\s*=\s*)"([^"]+)"\s*(#.*)?$}{$1$2}; - s{^(\s*(image|initrd|vmm)\s*=\s*)(/\S+/)?([^/\s]+)\s*(.*?)\s*$}{$1$4}; + s{^(\s*(image|initrd|vmm|ucode)\s*=\s*)(/\S+/)?([^/\s]+)\s*(.*?)\s*$}{$1$4}; my( $k, $p, $f, $o) = ($2, $3, $4, $5); #Info( 8, ">>> $.: k=$k p=$p f=$f\n"); $_ .= "\n"; @@ -368,6 +371,11 @@ sub Parse($$) { } elsif ( defined( $o) && $o ) { Warn( "$in: $.: ignoring trailing garbage...\n"); } + if ( $k eq "ucode" ) { + $Sconf{$k} = $f if (!exists( $current{image}) && !exists( $Sconf{$k})); + $_ = "# $_"; # hide 'ucode' from elilo.conf -- it's only for XEN! + $opt = 0; # ucode is *never* optional! + } if ( ! defined( $p) ) { $p = "/boot/"; } @@ -396,7 +404,7 @@ sub Parse($$) { } elsif ( $opt ) { Info( 0, "$C: Info: $in: $.: missing optional '$p$f' skipped\n"); } else { - Warn( "$in: $.: missing '$p$f' skipped\n"); + Warn( "$in: $.: missing '$p$f'\n"); } } next if ( $k eq "VMM" ); # omit efi-based "vmm" lines from elilo.conf! @@ -564,6 +572,7 @@ sub GconfProbeFSuuid($) { sub GconfFSuuid($) { my( $spec) = @_; return ( "" ) unless ( $Sconf{SB} ); + $spec =~ s{^UUID=}{/dev/disk/by-uuid/}; return ( $GconfFSuuid{$spec} ) if ( exists( $GconfFSuuid{$spec}) ); my $uuid = ""; @@ -571,17 +580,20 @@ sub GconfFSuuid($) { if ( -x $cmd ) { my $dop = (-b $spec) ? "--device" : ""; chomp( $uuid = qx{$cmd --target=fs_uuid $dop "$spec"}); - } else { + } + if ( ! defined( $uuid) || ! $uuid ) { $uuid = GconfProbeFSuuid( $spec); } if ( ! defined( $uuid) || ! $uuid ) { - Panic( 3, "couldn't determine fs_uuid -- skip SecureBoot/grub2 config!\n"); + Warn( "couldn't determine fs_uuid -- skip SecureBoot/grub2 config!\n"); $Sconf{SB} = ""; + return ( "" ); } $GconfFSuuid{$spec} = $uuid; return ( $uuid ); } -sub Gconf() { +sub Gconf($) { + my ($data) = @_; my @parts = ("pre", "Econf", "Xconf", "post"); my @keys = ("label", "kernel", "ramdisk", "options", "description", "rootfsuuid", "bootfsuuid", "disknr", "partnr", "vmm", "cfg"); @@ -593,7 +605,7 @@ sub Gconf() { $re = qr{^\>\>grub\.($re|.*)\<\<}ox; - while ( ) { + while ( <$data> ) { if ( m{^__(END)__} || ($current && m{$re}o) ) { Info( 9, "<<$current\n$lines>>$current => $_"); $S{$current} = $lines; @@ -695,8 +707,16 @@ sub Transfer ($$) { my( $in, $dir) = @_; my $c = $Sconf{'__warn-count'}; - - Gconf() if ( $Sconf{SB} ); + if ( $Sconf{SB} ) { + my $fh; + if ( -r $GconfT ) { + open( $fh, "< $GconfT") || Panic( 1, "$GconfT: failed to open: $!\n"); + } else { + open( $fh, "<&DATA") || Panic( 1, ": failed to dup: $!\n"); + } + Gconf($fh) if ( $Sconf{SB} ); + close( $fh); + } Warn( "no complete section for $Xconf!\n") if ( $Sconf{xencfg} && ! exists( $Labels{Xconf}) ); @@ -844,16 +864,36 @@ sub MP($) { my ( $d) = @_; my @I = ("/etc/fstab", "/proc/mounts", "/etc/mtab"); Info( 3, "### MP($d):"); - foreach my $f ( @I ) { + SOURCE: foreach my $f ( @I ) { open( IN, "< $f") || next; while ( ) { chomp; next if ( m{^#} ); my @F = split; + my $lno; if ( $F[1] eq $d ) { - Info( 3, " found in '$f' line $. => true\n"); - close( IN); - return( $F[0]); + my $dev = $F[0]; + $dev =~ s{^UUID=}{/dev/disk/by-uuid/}; + $dev =~ s{^LABEL=}{/dev/disk/by-label/}; + $lno = $.; + close( IN); + while ( -l $dev ) { + my $t = `readlink -en "$dev"`; + if ( ! defined( $t) ) { + Info( 0, "readlink failed for line $lno in '$f'.\n"); + next SOURCE; + } + if ( ! -b $dev ) { + Info( 0, "no block-device on line $lno in '$f': $dev.\n"); + next SOURCE; + } + if ( $t =~ m{^(/dev/|(../)*)dm-[0-9a-f]+$}i ) { + last; + } + $dev = $t; + } + Info( 3, " found '$dev' in '$f' line $lno => true\n"); + return( $dev); } } close( IN); @@ -920,8 +960,8 @@ sub ebm($$$$$) { my $entry; if ( ! -r "$MP$path" ) { - #Warn( "refusing to create EBM for non-existant binary ($MP$path).\n"); - Warn( "refusing to create EBM for non-existant binary.\n"); + #Warn( "refusing to create EBM for non-existent binary ($MP$path).\n"); + Warn( "refusing to create EBM for non-existent binary.\n"); return unless ( $test ); Info( 1, "#"); } @@ -942,10 +982,10 @@ sub ebm($$$$$) { next unless ( hwpEqual( $hwp, $3) ); if ( $file eq $4 ) { my $c = hex($1); -# This effort below to elliminate holes in the boot enry list voids +# This effort below to eliminate holes in the boot entry list voids # the attempt to order EBM entries by simply calling '--refresh-EBM'. # The full solution would require adding an interface to 'efibootmgr -o', -# which is unfortunately not feasable this late in the release cycle. +# which is unfortunately not feasible this late in the release cycle. # if ( $lbl eq $2 ) { # # delete label with higher number # my $n = ($num < $c) ? $c : $num; @@ -969,26 +1009,33 @@ sub ebm($$$$$) { sub Refresh($$) { my ( $device, $dir) = @_; - my ($dev, $part, $path, $label, $ret); + my ($dev, $sep, $part, $path, $label, $ret); my $shim_opts = ""; #$sBinaries[1]; # device & partition - if ( $device =~ m{^(.*)-part(\d+)$} ) { + if ( $device =~ m{^(.*)([-_]part)(\d+)$} ) { $dev = $1; - $part = $2; - } elsif ( $device =~ m{^(.*)_part(\d+)$} ) { - # /dev/mapper/... should not be used + $sep = $2; + $part = $3; + } elsif ( $device =~ m{^(.*/[a-z0-9]+)(p)(\d+)$}i ) { + # accept things like 'c0d0p1' or 'nvme0n0p1' $dev = $1; - $part = $2; - } elsif ( $device =~ m{^(.*/c\d+d\d+)p(\d+)$} ) { - $dev = $1; - $part = $2; - } elsif ( $device =~ m{^(/dev/\D+)(\d+)$} ) { + $sep = $2; + $part = $3; + } elsif ( $device =~ m{^(/dev/[a-z]+)(\d+)$}i ) { + # accept '/dev/sda1', but refuse '/dev/dm-1' $dev = $1; + $sep = ""; $part = $2; } else { Panic( 2, "parse error on EFI partition $device.\n"); } + if ( ! -b $dev ) { + Panic( 2, "EFI partition parent device $dev not found.\n"); + } + if ( ! -b "$dev$sep$part" ) { + Panic( 2, "EFI partition $part on device $dev not found.\n"); + } Info( 4, "#### dev=$dev, part=$part\n"); # path $path = "/efi/$VD/"; @@ -1002,6 +1049,11 @@ sub Refresh($$) { $label = "SUSE Linux Enterprise"; } Info( 4, "#### label=$label\n"); + if ( $Sconf{SB} && ! exists($Sconf{'SB-fallback'}) && + ! -r "$MP$path$shim" ) { + # try to force "fallback" when primary target went missing! + $Sconf{'SB-fallback'} = "true"; + } if ( ! $Sconf{SB} || exists($Sconf{'SB-fallback'}) ) { my $lbl = $label . ($Sconf{'SB'} ? " (fallback)" : ""); $ret = ebm( "XEN ".$lbl, $dev, $part, $path . $xen, "") diff --git a/elilo.spec b/elilo.spec index 7a1af7e..bbf690d 100644 --- a/elilo.spec +++ b/elilo.spec @@ -1,7 +1,7 @@ # # spec file for package elilo # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -23,6 +23,7 @@ BuildRequires: binutils219 %endif %endif BuildRequires: gnu-efi >= 3.0u +BuildRequires: xz BuildRequires: perl(Pod::Man) Name: elilo @@ -52,6 +53,8 @@ Patch2: elilo-mac-conf.diff Patch3: elilo-auto-add_efi_memmap.diff Patch4: elilo-blocksize.diff Patch5: elilo-text-mode.diff +Patch6: elilo-textmenu-disable-print-devices.diff +Patch7: elilo-high_base_mem.diff Patch10: elilo-de-debianify.diff Patch11: eliloalt-no-date.diff @@ -68,23 +71,32 @@ The EFI Linux boot loader. %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 +%patch7 -p1 %patch10 -p1 %patch11 -p1 +# work around b0rked 'Str'-ops in newer 'gnu-efi' ... :-( +find . -type f -name '*.[ch]' -print0 | xargs -0rn 1 \ + perl -pi -e 's{Str(Chr|n(X?Cpy|Cat))}{eliloStr$1}g' %build perl -pi -e 's{/usr/lib}{%{_libdir}}' Make.defaults ################################################################## ## DO NOT ADD RPM OPT FLAGS! THIS DOES NOT BUILD AGAINST GLIBC. ## ################################################################## -make OPTIMFLAGS="-fmessage-length=0" +OPTFLAGS="-fmessage-length=0" +%ifnarch ia64 +OPTFLAGS="$OPTFLAGS -mno-red-zone" +%endif +make OPTIMFLAGS="$OPTFLAGS" perl -pe 's{\@EDITION\@}{%{version}}; s{\@LIBDIR\@}{%{_libdir}}; s{\@ARCH\@}{%{_target_cpu}}; ' < %{SOURCE1} > elilo.pl && -chmod 555 elilo.pl && touch -r %{SOURCE1} elilo.pl -! grep -F '%%{version}-%%{release}' elilo.pl +chmod 555 elilo.pl && touch -r %{SOURCE1} elilo.pl +! grep -F '%%{version}' elilo.pl pod2man -s 8 -c "System Boot" -r "SuSE Linux" \ - -n elilo -d "%{version}-%{release}" elilo.pl elilo.8 + -n elilo -d "%{version}" elilo.pl elilo.8 touch -r elilo.pl elilo.8 %install