diff options
-rw-r--r-- | perl-install/bootloader.pm | 126 |
1 files changed, 114 insertions, 12 deletions
diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm index 7e52ad4fd..758d7842b 100644 --- a/perl-install/bootloader.pm +++ b/perl-install/bootloader.pm @@ -185,6 +185,7 @@ sub add_entry { sub add_kernel { my ($lilo, $version, $ext, $root, $v) = @_; + my $boot="/boot"; #- new versions of yaboot don't handle symlinks my $ppcext = $ext; @@ -192,16 +193,20 @@ sub add_kernel { $ext = "-$version"; } + # If itanium architecture store kernel & initrd in /boot/efi + if (arch() =~ /ia64/) { + $boot="/boot/efi"; + } + log::l("adding vmlinuz$ext as vmlinuz-$version"); - -e "$::prefix/boot/vmlinuz-$version" or log::l("unable to find kernel image $::prefix/boot/vmlinuz-$version"), return; - my $image = "/boot/vmlinuz" . ($ext ne "-$version" && - symlinkf("vmlinuz-$version", "$::prefix/boot/vmlinuz$ext") ? $ext : "-$version"); + -e "$::prefix$boot/vmlinuz-$version" or log::l("unable to find kernel image $::prefix$boot/vmlinuz-$version"), return; + my $image = "$boot/vmlinuz" . ($ext ne "-$version" && symlinkf("vmlinuz-$version", "$::prefix$boot/vmlinuz$ext") ? $ext : "-$version"); - my $initrd = "/boot/initrd-$version.img"; + my $initrd = "$boot/initrd-$version.img"; mkinitrd($version, $initrd) or undef $initrd; if ($initrd && $ext ne "-$version") { - $initrd = "/boot/initrd$ext.img"; - symlinkf("initrd-$version.img", "$::prefix$initrd") or cp_af("$::prefix/boot/initrd-$version.img", "$::prefix$initrd"); + $initrd = "$boot/initrd$ext.img"; + symlinkf("initrd-$version.img", "$::prefix$initrd") or cp_af("$::prefix$boot/initrd-$version.img", "$::prefix$initrd"); } my $label = $ext =~ /-(default)/ ? $1 : ($ext =~ /\d\./ ? sanitize_ver("linux$ext") : "linux$ext"); @@ -275,11 +280,17 @@ sub configure_entry { my ($entry) = @_; if ($entry->{type} eq 'image') { my $specific_version; + my $boot="/boot/"; + + if (arch() =~ /ia64/) { + $boot="/boot/efi"; + } + $entry->{kernel_or_dev} =~ /vmlinu.-(.*)/ and $specific_version = $1; readlink("$::prefix/$entry->{kernel_or_dev}") =~ /vmlinu.-(.*)/ and $specific_version = $1; if ($specific_version) { - $entry->{initrd} or $entry->{initrd} = "/boot/initrd-$specific_version.img"; + $entry->{initrd} or $entry->{initrd} = "$boot/initrd-$specific_version.img"; mkinitrd($specific_version, $entry->{initrd}) or undef $entry->{initrd}; } } @@ -296,6 +307,9 @@ sub dev2prompath { #- SPARC only sub get_kernels_and_labels() { my $dir = "$::prefix/boot"; + if ( arch() =~ /ia64/ ) { + $dir = "$::prefix/boot/efi"; } + my @l = grep { /^vmlinuz-/ } all($dir); my @kernels = grep { ! -l "$dir/$_" } @l; @@ -409,16 +423,21 @@ sub suggest { enablecdboot => 1, useboot => $boot, xfsroot => $xfsroot, + } : arch() =~ /ia64/ ? + { + default => "linux", + entries => [], + timeout => 5, } : { bootUnsafe => $unsafe, entries => [], timeout => $onmbr && 10, nowarn => 1, - if_(arch() !~ /ia64/, + lba32 => 1, boot => "/dev/" . ($onmbr ? $hds->[0]{device} : fsedit::get_root($fstab, 'boot')->{device}), map => "/boot/map", - ), + install => "/boot/boot.b", }); if (!$lilo->{message} || $lilo->{message} eq "1") { @@ -525,9 +544,10 @@ wait %d seconds for default boot. my %l = ( yaboot => to_bool(arch() =~ /ppc/), silo => to_bool(arch() =~ /sparc/), - lilo => to_bool(arch() !~ /sparc|ppc/) && !isLoopback(fsedit::get_root($fstab)), - grub => to_bool(arch() !~ /sparc|ppc|x86_64/ && !isRAID(fsedit::get_root($fstab))), - loadlin => to_bool(arch() !~ /sparc|ppc|x86_64/) && -e "/initrd/loopfs/lnx4win", + elilo => to_bool(arch() =~ /ia64/), + lilo => to_bool(arch() !~ /sparc|ppc|ia64/) && !isLoopback(fsedit::get_root($fstab)), + grub => to_bool(arch() !~ /sparc|ppc|x86_64|ia64/ && !isRAID(fsedit::get_root($fstab))), + loadlin => to_bool(arch() !~ /sparc|ppc|x86_64|ia64/) && -e "/initrd/loopfs/lnx4win", ); unless ($lilo->{methods}) { $lilo->{methods} ||= { map { $_ => 1 } grep { $l{$_} } keys %l }; @@ -872,6 +892,88 @@ sub install_lilo { unlink "$::prefix/tmp/.error"; } +sub write_elilo_conf { + my ($lilo, $fstab, $hds) = @_; + my $prefix = $::prefix ; + $lilo->{prompt} = $lilo->{timeout}; + + my $file2fullname = sub { + my ($file) = @_; + $file =~ s|/boot/efi/||; + $file + }; + + { + local *F; + local $\ = "\n"; + my $f = "$prefix/boot/efi/elilo.conf"; + + open F, ">$f" or die "cannot create lilo config file: $f"; + log::l("writing elilo config to $f"); + + $lilo->{$_} and print F "$_=$lilo->{$_}" foreach qw(default append); + $lilo->{$_} and print F $_ foreach qw(prompt); + print F "timeout=", round(10 * $lilo->{timeout}) if $lilo->{timeout}; + + foreach (@{$lilo->{entries}}) { + print F "$_->{type}=", $file2fullname->($_->{kernel_or_dev}); + my $label = substr($_->{label}, 0, 15); + $label =~ s/\s/_/g; + print F "\tlabel=$label"; + print F "\troot=$_->{root}"; + print F "\tinitrd=", $file2fullname->($_->{initrd}) if $_->{initrd}; + print F "\tappend=\"$_->{append}\"" if $_->{append}; + print F "\tread-only" if !$_->{'read-write'}; + } + } +} + + +sub install_efi_boot_menu { + my ($lilo, $fstab, $hds, $prefix) = @_; + + die "/proc filesystem is not mounted, nvram will not be updated\n" if + ( ! -f "/proc/uptime" ); + + die "/proc/efi/vars not available, nvram will not be updated\n" if + ( ! -d "/proc/efi/vars" ); + + + my $part = fsedit::mntpoint2part "/boot/efi", $fstab; + (my ($bootdisk, $bootpart) = ($1, $2)) = ("/dev/" . $part->{device}) =~ m|(/dev/.+)([0-9]+)|; + # print STDERR "DEBUG: boot-disk = $bootdisk\n"; + # print STDERR "DEBUG: boot-partition = $bootpart\n"; + die "empty bootdisk or bootpart variables" if !($bootdisk) || !($bootpart); + + + my $os_vendor = "Mandrake Linux"; + my $efibootmgr = "/usr/sbin/efibootmgr"; + + die "failed to retrieve current EFI boot entries\n" unless + (open F, "$efibootmgr|"); + while (<F>) { + if (/Boot(\w+).*$os_vendor/) { + die "efibootmgr could not remove entry $1\n" if + (system("$efibootmgr -b $1 -B >/dev/null")); + } + } + close F; + + die "efibootmgr could not add entry for $bootdisk$bootpart\n" if + (system("$efibootmgr -c -d $bootdisk -p $bootpart -w -L \"$os_vendor\"")); +} + +sub install_elilo { + my ($elilo, $fstab, $hds, $prefix) = @_; + write_elilo_conf($elilo, $fstab, $hds, $prefix); + log::l("Installing elilo boot loader..."); + $::testing and return; + install_efi_boot_menu($elilo, $fstab, $hds, $prefix); + unlink "$prefix/tmp/.error"; +} + + + sub dev2bios { my ($hds, $where) = @_; $where =~ s|/dev/||; |