summaryrefslogtreecommitdiffstats
path: root/perl-install/bootloader.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/bootloader.pm')
-rw-r--r--perl-install/bootloader.pm126
1 files changed, 106 insertions, 20 deletions
diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm
index c2a75e8dc..f28c61f06 100644
--- a/perl-install/bootloader.pm
+++ b/perl-install/bootloader.pm
@@ -66,6 +66,8 @@ sub mkinitrd($$$) {
my $loop_boot = loopback::prepare_boot($prefix);
modules::load('loop');
+ # FIXME: (gb) temporary hack to force the creation of a new initrd (broken mkinitrd?)
+ unlink("$prefix/$initrdImage");
run_program::rooted($prefix, "mkinitrd", "-v", "-f", $initrdImage, "--ifneeded", $kernelVersion) or unlink("$prefix/$initrdImage");
loopback::save_boot($loop_boot);
@@ -150,12 +152,17 @@ sub add_kernel($$$$$) {
-e "$prefix/boot/$vmlinuz" or log::l("unable to find kernel image $prefix/boot/$vmlinuz"), return;
{
my $f = "initrd-$kernelVersion$specific.img";
- eval { mkinitrd($prefix, "$kernelVersion$specific", "/boot/$f") };
+ eval { mkinitrd($prefix, "$kernelVersion$specific", (arch() =~ /ia64/ ? "/boot/efi" : "/boot") . "/$f") };
undef $initrdImage if $@;
symlinkf $f, "$prefix$initrdImage" or $initrdImage = "/boot/$f"
if $initrdImage;
}
symlinkf "$vmlinuz", "$prefix/$image" or $image = "/boot/$vmlinuz";
+ #- On IA-64, kernels and initrd are now always in /boot/efi with the bootloader (elilo)
+ if (arch() =~ /ia64/) {
+ $image = "/boot/efi/vmlinuz-$kernelVersion$specific";
+ $initrdImage = "/boot/efi/initrd-$kernelVersion$specific.img";
+ }
add2hash($v,
{
type => 'image',
@@ -189,7 +196,9 @@ sub configure_entry($$) {
readlink("$prefix/$entry->{kernel_or_dev}") =~ /vmlinu.-(.*)/ and $specific_version = $1;
if ($specific_version) {
- $entry->{initrd} or $entry->{initrd} = "/boot/initrd-$specific_version.img";
+ #- On IA-64, kernels and initrd are now always in /boot/efi with the bootloader
+ $entry->{initrd} or $entry->{initrd} = (arch() =~ /ia64/ ? "/boot/efi" : "/boot") . "/initrd-$specific_version.img";
+ printf "configure_entry: $entry->{initrd}\n";
unless (-e "$prefix/$entry->{initrd}") {
eval { mkinitrd($prefix, $specific_version, "$entry->{initrd}") };
undef $entry->{initrd} if $@;
@@ -237,18 +246,21 @@ sub suggest {
enableofboot => 1,
enablecdboot => 1,
useboot => $boot,
+ } : arch() =~ /ia64/ ?
+ {
+ default => "linux",
+ entries => [],
+ timeout => 5,
} :
{
bootUnsafe => $unsafe,
default => "linux",
entries => [],
timeout => $onmbr && 5,
- 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") {
@@ -390,9 +402,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/ && !isRAID(fsedit::get_root($fstab))),
- loadlin => to_bool(arch() !~ /sparc|ppc/) && -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|ia64/ && !isRAID(fsedit::get_root($fstab))),
+ loadlin => to_bool(arch() !~ /sparc|ppc|ia64/) && -e "/initrd/loopfs/lnx4win",
);
unless ($lilo->{methods}) {
$lilo->{methods} ||= { map { $_ => 1 } grep { $l{$_} } keys %l };
@@ -623,14 +636,7 @@ sub write_lilo_conf {
my $file2fullname = sub {
my ($file) = @_;
- if (arch() =~ /ia64/) {
- (my $part, $file) = fsedit::file2part($prefix, $fstab, $file);
- my %hds = map_index { $_ => "hd$::i" } map { $_->{device} }
- sort { isFat($b) <=> isFat($a) || $a->{device} cmp $b->{device} } fsedit::get_fstab(@$hds);
- %hds->{$part->{device}} . ":" . $file;
- } else {
$file
- }
};
if ($lilo->{message}) {
@@ -649,14 +655,12 @@ sub write_lilo_conf {
last;
}
}
- if (arch() !~ /ia64/) {
-e "$prefix/boot/boot.b" && -e "$prefix/boot/message" or die "unable to get right lilo configuration in $prefix/boot";
- }
{
local *F;
local $\ = "\n";
- my $f = arch() =~ /ia64/ ? "$prefix/boot/efi/elilo.conf" : "$prefix/etc/lilo.conf";
+ my $f = "$prefix/etc/lilo.conf";
open F, ">$f" or die "cannot create lilo config file: $f";
log::l("writing lilo config to $f");
@@ -676,8 +680,8 @@ sub write_lilo_conf {
print F "disk=/dev/$dev bios=0x80";
}
- print F "message=/boot/message" if (arch() !~ /ia64/);
- print F "menu-scheme=wb:bw:wb:bw" if (arch() !~ /ia64/);
+ print F "message=/boot/message";
+ print F "menu-scheme=wb:bw:wb:bw";
foreach (@{$lilo->{entries}}) {
print F "$_->{type}=", $file2fullname->($_->{kernel_or_dev});
@@ -719,7 +723,89 @@ sub install_lilo {
log::l("Installing boot loader...");
$::testing and return;
- run_program::rooted_or_die($prefix, "lilo", "2>", "/tmp/.error") if (arch() !~ /ia64/);
+ run_program::rooted_or_die($prefix, "lilo", "2>", "/tmp/.error");
+ unlink "$prefix/tmp/.error";
+}
+
+sub write_elilo_conf {
+ my ($prefix, $lilo, $fstab, $hds) = @_;
+ $lilo->{prompt} = $lilo->{timeout};
+
+ my $file2fullname = sub {
+ #- The kernel now lays in the same directory as the bootloader
+ #- Therefore, it can be specified relative to it, i.e. without $prefix
+ 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); #- lilo doesn't handle more than 15 char long labels
+ $label =~ s/\s/_/g; #- lilo doesn't like spaces
+ 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 ($prefix, $lilo, $fstab, $hds) = @_;
+
+ #- efibootmgr requires /proc
+ 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" );
+
+ #- get boot disk and partition
+ 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);
+
+ #- delete other entries with name "Mandrake Linux"
+ 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;
+
+ #- add a new entry from the current installation
+ die "efibootmgr could not add entry for $bootdisk$bootpart\n" if
+ (system("$efibootmgr -c -d $bootdisk -p $bootpart -w -L \"$os_vendor\" >/dev/null"));
+}
+
+sub install_elilo {
+ my ($prefix, $elilo, $fstab, $hds) = @_;
+ write_elilo_conf($prefix, $elilo, $fstab, $hds);
+ log::l("Installing boot loader...");
+ $::testing and return;
+ install_efi_boot_menu($prefix, $elilo, $fstab, $hds);
unlink "$prefix/tmp/.error";
}