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.pm1007
1 files changed, 0 insertions, 1007 deletions
diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm
deleted file mode 100644
index 453b7c7c6..000000000
--- a/perl-install/bootloader.pm
+++ /dev/null
@@ -1,1007 +0,0 @@
-package bootloader; # $Id$
-
-use diagnostics;
-use strict;
-use vars qw(%vga_modes);
-
-#-######################################################################################
-#- misc imports
-#-######################################################################################
-use common;
-use partition_table qw(:types);
-use log;
-use any;
-use fsedit;
-use devices;
-use loopback;
-use commands;
-use detect_devices;
-use partition_table_raw;
-use run_program;
-use modules;
-
-
-%vga_modes = (
- "Ask at boot" => 'ask',
- "Normal" => 'normal',
- "80x50" => '0x0f01',
- "80x43" => '0x0f02',
- "80x28" => '0x0f03',
- "80x30" => '0x0f04',
- "80x34" => '0x0f05',
- "80x60" => '0x0f06',
- "100x30" => '0x0122',
- "640x480 in 16 bits (FrameBuffer only)" => 785,
- "800x600 in 16 bits (FrameBuffer only)" => 788,
- "1024x768 in 16 bits (FrameBuffer only)" => 791,
- "1280x1024 in 16 bits (FrameBuffer only)" => 794,
-);
-
-my %vga_modes2nb = (
- 'ask' => -3,
- 'normal' => -1,
-#- other entries are identity
-);
-
-
-#-#####################################################################################
-#- Functions
-#-#####################################################################################
-
-sub get {
- my ($kernel, $bootloader) = @_;
- $_->{kernel_or_dev} && $_->{kernel_or_dev} eq $kernel and return $_ foreach @{$bootloader->{entries}};
- undef;
-}
-sub get_label {
- my ($label, $bootloader) = @_;
- $_->{label} && $_->{label} eq $label and return $_ foreach @{$bootloader->{entries}};
- undef;
-}
-
-sub mkinitrd($$$) {
- my ($prefix, $kernelVersion, $initrdImage) = @_;
-
- $::testing || -e "$prefix/$initrdImage" and return;
-
- my $loop_boot = loopback::prepare_boot($prefix);
-
- modules::load('loop');
- run_program::rooted($prefix, "mkinitrd", "-f", $initrdImage, "--ifneeded", $kernelVersion) or unlink("$prefix/$initrdImage");
-
- loopback::save_boot($loop_boot);
-
- -e "$prefix/$initrdImage" or die "mkinitrd failed";
-}
-
-sub mkbootdisk($$$;$) {
- my ($prefix, $kernelVersion, $dev, $append) = @_;
-
- modules::load_multi(arch() =~ /sparc/ ? 'romfs' : (), 'loop');
- my @l = qw(mkbootdisk --noprompt);
- push @l, "--appendargs", $append if $append;
- if ($dev =~ /fd/) {
- devices::make($dev . 'H1440');
- } else {
- push @l, "--bios", 0, if $dev !~ /fd/;
- }
- eval { modules::load_multi(qw(msdos vfat)) };
- run_program::rooted_or_die($prefix, @l, "--device", "/dev/$dev", $kernelVersion);
-}
-
-sub read($$) {
- my ($prefix, $file) = @_;
- my $global = 1;
- my ($e, $v, $f);
- my %b;
- foreach (cat_("$prefix$file")) {
- ($_, $v) = /^\s*(.*?)\s*(?:=\s*(.*?))?\s*$/;
-
- if (/^(image|other)$/) {
- push @{$b{entries}}, $e = { type => $_, kernel_or_dev => $v };
- $global = 0;
- } elsif ($global) {
- $b{$_} = $v || 1;
- } else {
- if ((/map-drive/ .. /to/) && /to/) {
- $e->{mapdrive}{$e->{'map-drive'}} = $v;
- } else {
- $e->{$_} = $v || 1;
- }
- }
- }
- delete $b{timeout} unless $b{prompt};
- $_->{append} =~ s/^\s*"?(.*?)"?\s*$/$1/ foreach \%b, @{$b{entries}};
- $b{timeout} = $b{timeout} / 10 if $b{timeout};
- $b{message} = cat_("$prefix$b{message}") if $b{message};
- \%b;
-}
-
-sub suggest_onmbr ($) {
- my ($hds) = @_;
-
- my $type = partition_table_raw::typeOfMBR($hds->[0]{device});
- !$type || member($type, qw(dos dummy lilo grub empty)), !$type;
-}
-
-sub compare_entries ($$) {
- my ($a, $b) = @_;
- my %entries;
-
- @entries{keys %$a, keys %$b} = ();
- $a->{$_} eq $b->{$_} and delete $entries{$_} foreach keys %entries;
- scalar keys %entries;
-}
-
-sub add_entry($$) {
- my ($entries, $v) = @_;
- my (%usedold, $freeold);
-
- do { $usedold{$1 || 0} = 1 if $_->{label} =~ /^old([^_]*)_/ } foreach @$entries;
- foreach (0..scalar keys %usedold) { exists $usedold{$_} or $freeold = $_ || '', last }
-
- foreach (@$entries) {
- if ($_->{label} eq $v->{label}) {
- compare_entries($_, $v) or return; #- avoid inserting it twice as another entry already exists !
- $_->{label} = "old${freeold}_$_->{label}";
- }
- }
- push @$entries, $v;
-}
-
-sub add_kernel($$$$$) {
- my ($prefix, $lilo, $kernelVersion, $specific, $v) = @_;
- my $ext = $specific && "-$specific"; $specific =~ s/\d+\.\d+|hack//;
- my ($vmlinuz, $image, $initrdImage) = ("vmlinuz-$kernelVersion$specific", "/boot/vmlinuz$ext", "/boot/initrd$ext.img");
- -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") };
- undef $initrdImage if $@;
- symlinkf $f, "$prefix$initrdImage" or $initrdImage = "/boot/$f"
- if $initrdImage;
- }
- symlinkf "$vmlinuz", "$prefix/$image" or $image = "/boot/$vmlinuz";
- add2hash($v,
- {
- type => 'image',
- label => 'linux',
- kernel_or_dev => $image,
- initrd => $initrdImage,
- append => $lilo->{perImageAppend},
- });
- add_entry($lilo->{entries}, $v);
- $v;
-}
-
-sub get_append {
- my ($b, $key) = @_;
- ($b->{perImageAppend} =~ /\b$key=(\S*)/)[0];
-}
-sub add_append {
- my ($b, $key, $val) = @_;
-
- foreach ({ append => $b->{perImageAppend} }, @{$b->{entries}}) {
- $_->{append} =~ s/\b$key=\S*\s*//;
- $_->{append} =~ s/\s*$/ $key=$val)/ if $val;
- }
-}
-
-sub configure_entry($$) {
- my ($prefix, $entry) = @_;
- if ($entry->{type} eq 'image') {
- my $specific_version;
- $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";
- unless (-e "$prefix/$entry->{initrd}") {
- eval { mkinitrd($prefix, $specific_version, "$entry->{initrd}") };
- undef $entry->{initrd} if $@;
- }
- }
- }
- $entry;
-}
-
-sub dev2prompath { #- SPARC only
- my ($dev) = @_;
- my ($wd, $num) = $dev =~ /^(.*\D)(\d*)$/;
- require c;
- $dev = c::disk2PromPath($wd) and $dev = $dev =~ /^sd\(/ ? "$dev$num" : "$dev;$num";
- $dev;
-}
-
-sub suggest {
- my ($prefix, $lilo, $hds, $fstab, $kernelVersion, $vga_fb) = @_;
- my $root_part = fsedit::get_root($fstab);
- my $root = isLoopback($root_part) ? "loop7" : $root_part->{device};
- my $boot = fsedit::get_root($fstab, 'boot')->{device};
- my $partition = first($boot =~ /\D*(\d*)/);
-
- require c; c::initSilo() if arch() =~ /sparc/;
-
- my ($onmbr, $unsafe) = $lilo->{crushMbr} ? (1, 0) : suggest_onmbr($hds);
- add2hash_($lilo, arch() =~ /sparc/ ?
- {
- default => "linux",
- entries => [],
- timeout => 5,
- use_partition => 0, #- we should almost always have a whole disk partition.
- root => "/dev/$root",
- partition => $partition || 1,
- boot => $root eq $boot && "/boot", #- this helps for getting default partition for silo.
- } : arch =~ /ppc/ ?
- {
- defaultos => "linux",
- default => "linux",
- entries => [],
- initmsg => "Welcome to Mandrake Linux!",
- delay => 30, #- OpenFirmware delay
- timeout => 50,
- enableofboot => 1,
- enablecdboot => 1,
- useboot => $boot,
- } :
- {
- 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") {
- $lilo->{message} = join('', cat_("$prefix/boot/message"));
- if (!$lilo->{message}) {
- my $msg_en =
-#-PO: these messages will be displayed at boot time in the BIOS, use only ASCII (7bit)
-__("Welcome to %s the operating system chooser!
-
-Choose an operating system in the list above or
-wait %d seconds for default boot.
-
-");
- my $msg = translate($msg_en);
- #- use the english version if more than 20% of 8bits chars
- $msg = $msg_en if int(grep { $_ & 0x80 } unpack "c*", $msg) / length($msg) > 0.2;
- $lilo->{message} = sprintf $msg, arch() =~ /sparc/ ? "SILO" : "LILO", $lilo->{timeout};
- }
- }
-
-
- add2hash_($lilo, { getVarsFromSh("$prefix/etc/sysconfig/system") }); #- for CLEAN_TMP
- add2hash_($lilo, { memsize => $1 }) if cat_("/proc/cmdline") =~ /mem=(\S+)/;
-
- #- give more priority to secure kernel because if the user want security, he will got it...
- my $isSecure = -e "$prefix/boot/vmlinuz-${kernelVersion}secure";
- my $isEnterprise = -e "$prefix/boot/vmlinuz-${kernelVersion}enterprise";
-
- my $isSMP = detect_devices::hasSMP();
- if ($isSMP && !-e "$prefix/boot/vmlinuz-${kernelVersion}smp") {
- log::l("SMP machine, but no SMP kernel found") unless $isSecure;
- $isSMP = 0;
- }
- my $entry = add_kernel($prefix, $lilo, $kernelVersion,
- $isSecure ? 'secure' : $isEnterprise ? 'enterprise' : $isSMP ? 'smp' : '',
- {
- label => 'linux',
- root => "/dev/$root",
- if_($vga_fb, vga => $vga_fb), #- using framebuffer
- });
- add_kernel($prefix, $lilo, $kernelVersion, '',
- {
- label => $isSecure || $isEnterprise || $isSMP ? 'linux-up' : 'linux-nonfb',
- root => "/dev/$root",
- }) if $isSecure || $isEnterprise || $isSMP || $vga_fb;
- my $failsafe = add_kernel($prefix, $lilo, $kernelVersion, '',
- {
- label => 'failsafe',
- root => "/dev/$root",
- });
- $entry->{append} .= " quiet" if $vga_fb;
- $failsafe->{append} .= " failsafe" if $failsafe && !$lilo->{password};
-
- #- manage prioritary default kernel (given as /boot/vmlinuz-default).
- if (-e "$prefix/boot/vmlinuz-default") {
- #- we use directly add_entry as no initrd should be done.
- add_entry($lilo->{entries},
- {
- type => 'image',
- label => 'default',
- root => "/dev/$root",
- kernel_or_dev => '/boot/vmlinuz-default',
- append => $lilo->{perImageAppend},
- });
- $lilo->{default} = 'default'; #- this one should be booted by default now.
- }
-
- #- manage older kernel if installed.
- foreach (qw(2.2 hack)) {
- my $hasOld = -e "$prefix/boot/vmlinuz-$_";
- if ($hasOld) {
- my $oldVersion = first(readlink("$prefix/boot/vmlinuz-$_") =~ /vmlinuz-(.*mdk)/);
- my $oldSecure = -e "$prefix/boot/vmlinuz-${_}secure";
- my $oldSMP = $isSMP && -e "$prefix/boot/vmlinuz-${_}smp";
-
- add_kernel($prefix, $lilo, $oldVersion, $oldSecure ? "${_}secure" : $oldSMP ? "${_}smp" : $_,
- {
- label => "linux-$_",
- root => "/dev/$root",
- $vga_fb ? ( vga => $vga_fb) : (), #- using framebuffer
- });
- add_kernel($prefix, $lilo, $oldVersion, $_,
- {
- label => $oldSecure || $oldSMP ? "linux-${_}up" : "linux-${_}nonfb",
- root => "/dev/$root",
- }) if $oldSecure || $oldSMP || $vga_fb;
- my $entry = add_kernel($prefix, $lilo, $oldVersion, $_,
- {
- label => "failsafe-$_",
- root => "/dev/$root",
- });
- $entry->{append} .= " failsafe" if $entry && !$lilo->{password};
- }
- }
-
- if (arch() =~ /sparc/) {
- #- search for SunOS, it could be a really better approach to take into account
- #- partition type for mounting point.
- my $sunos = 0;
- foreach (@$hds) {
- foreach (@{$_->{primary}{normal}}) {
- my $path = $_->{device} =~ m|^/| && $_->{device} !~ m|^/dev/| ? $_->{device} : dev2prompath($_->{device});
- add_entry($lilo->{entries},
- {
- type => 'other',
- kernel_or_dev => $path,
- label => "sunos" . ($sunos++ ? $sunos : ''),
- }) if $path && isSunOS($_) && type2name($_->{type}) =~ /root/i;
- }
- }
- } elsif (arch() =~ /ppc/) {
- #- if we identified a MacOS partition earlier - add it
- if (defined $partition_table_mac'macos_part) {
- add_entry($lilo->{entries},
- {
- label => "macos",
- kernel_or_dev => $partition_table_mac'macos_part
- });
- }
- } else {
- #- search for dos (or windows) boot partition. Don't look in extended partitions!
- my %nbs;
- foreach (@$hds) {
- foreach (@{$_->{primary}{normal}}) {
- my $label = isNT($_) ? 'NT' : isDos($_) ? 'dos' : 'windows';
- add_entry($lilo->{entries},
- {
- type => 'other',
- kernel_or_dev => "/dev/$_->{device}",
- label => $label . ($nbs{$label}++ ? $nbs{$label} : ''),
- table => "/dev/$_->{rootDevice}",
- unsafe => 1
- }) if isNT($_) || isFat($_) && isFat({ type => fsedit::typeOfPart($_->{device}) });
- }
- }
- }
- 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/ && availableRamMB() < 800), #- don't use grub if more than 800MB
- loadlin => to_bool(arch() !~ /sparc|ppc/) && -e "/initrd/loopfs/lnx4win",
- );
- unless ($lilo->{methods}) {
- $lilo->{methods} ||= { map { $_ => 1 } grep { $l{$_} } keys %l };
- if ($lilo->{methods}{lilo} && -e "$prefix/boot/lilo-graphic") {
- $lilo->{methods}{lilo} = "lilo-graphic";
- exists $lilo->{methods}{grub} and $lilo->{methods}{grub} = undef;
- }
- }
-}
-
-sub suggest_floppy {
- my ($bootloader) = @_;
-
- my $floppy = detect_devices::floppy() or return;
- $floppy eq 'fd0' or log::l("suggest_floppy: not adding $floppy"), return;
-
- add_entry($bootloader->{entries},
- {
- type => 'other',
- kernel_or_dev => '/dev/fd0',
- label => 'floppy',
- unsafe => 1
- });
-}
-
-sub keytable($$) {
- my ($prefix, $f) = @_;
- local $_ = $f;
- if ($_ && !/\.klt$/) {
- $f = "/boot/$_.klt";
- run_program::rooted($prefix, "keytab-lilo.pl", ">", $f, $_) or undef $f;
- }
- $f && -r "$prefix/$f" && $f;
-}
-
-sub has_profiles { to_bool(get_label("office", $b)) }
-sub set_profiles {
- my ($b, $want_profiles) = @_;
-
- my $office = get_label("office", $b);
- if ($want_profiles xor $office) {
- my $e = get_label("linux", $b);
- if ($want_profiles) {
- push @{$b->{entries}}, { %$e, label => "office", append => "$e->{append} prof=Office" };
- $e->{append} .= " prof=Home";
- } else {
- # remove profiles
- $e->{append} =~ s/\s*prof=\w+//;
- @{$b->{entries}} = grep { $_ != $office } @{$b->{entries}};
- }
- }
-
-}
-
-sub get_of_dev($$) {
- my ($prefix, $unix_dev) = @_;
- #- don't care much for this - need to run ofpath rooted, and I need the result
- #- In test mode, just run on "/", otherwise you can't get to the /proc files
- if ($::testing) {
- $prefix = "";
- }
- run_program::rooted_or_die($prefix, "/usr/local/sbin/ofpath $unix_dev", ">", "/tmp/ofpath");
- open(FILE, "$prefix/tmp/ofpath") || die "Can't open $prefix/tmp/ofpath";
- my $of_dev = "";
- local $_ = "";
- while (<FILE>){
- $of_dev = $_;
- }
- chop($of_dev);
- my @del_file = ($prefix . "/tmp/ofpath");
- unlink (@del_file);
- log::l("OF Device: $of_dev");
- $of_dev;
-}
-
-sub install_yaboot($$$) {
- my ($prefix, $lilo, $fstab, $hds) = @_;
- $lilo->{prompt} = $lilo->{timeout};
-
- if ($lilo->{message}) {
- local *F;
- open F, ">$prefix/boot/message" and print F $lilo->{message} or $lilo->{message} = 0;
- }
- {
- local *F;
- local $\ = "\n";
- my $f = "$prefix/etc/yaboot.conf";
- open F, ">$f" or die "cannot create yaboot config file: $f";
- log::l("writing yaboot config to $f");
-
- print F "#yaboot.conf - generated by DrakX";
- print F "init-message=\"\\n$lilo->{initmsg}\\n\"" if $lilo->{initmsg};
-
- if ($lilo->{boot}) {
- print F "boot=$lilo->{boot}";
- my $of_dev = get_of_dev($prefix, $lilo->{boot});
- print F "ofboot=$of_dev";
- } else {
- die "no bootstrap partition defined."
- }
-
- $lilo->{$_} and print F "$_=$lilo->{$_}" foreach qw(delay timeout);
- print F "install=/usr/local/lib/yaboot/yaboot";
- print F "magicboot=/usr/local/lib/yaboot/ofboot";
- $lilo->{$_} and print F $_ foreach qw(enablecdboot enableofboot);
- $lilo->{$_} and print F "$_=$lilo->{$_}" foreach qw(defaultos default);
- print F "nonvram";
- my $boot = "/dev/" . $lilo->{useboot} if $lilo->{useboot};
-
- foreach (@{$lilo->{entries}}) {
-
- if ($_->{type} eq "image") {
- my $of_dev = '';
- if ($boot !~ /$_->{root}/) {
- $of_dev = get_of_dev($prefix, $boot);
- print F "$_->{type}=$of_dev," . substr($_->{kernel_or_dev}, 5);
- } else {
- $of_dev = get_of_dev($prefix, $_->{root});
- print F "$_->{type}=$of_dev,$_->{kernel_or_dev}";
- }
- print F "\tlabel=", substr($_->{label}, 0, 15); #- lilo doesn't handle more than 15 char long labels
- print F "\troot=$_->{root}";
- if ($boot !~ /$_->{root}/) {
- print F "\tinitrd=$of_dev," . substr($_->{initrd}, 5) if $_->{initrd};
- } else {
- print F "\tinitrd=$of_dev,$_->{initrd}" if $_->{initrd};
- }
- print F "\tappend=\"$_->{append}\"" if $_->{append};
- print F "\tread-write" if $_->{'read-write'};
- print F "\tread-only" if !$_->{'read-write'};
- } else {
- my $of_dev = get_of_dev($prefix, $_->{kernel_or_dev});
- print F "$_->{label}=$of_dev";
- }
- }
- }
- log::l("Installing boot loader...");
- my $f = "$prefix/tmp/of_boot_dev";
- my $of_dev = get_of_dev($prefix, $lilo->{boot});
- output($f, "$of_dev\n");
- $::testing and return;
- if (defined $install_steps_interactive::new_bootstrap) {
- run_program::run("hformat", "$lilo->{boot}") or die "hformat failed";
- }
- run_program::rooted($prefix, "/sbin/ybin", "2>", "/tmp/.error") or die "ybin failed";
- unlink "$prefix/tmp/.error";
-}
-
-sub install_silo($$$) {
- my ($prefix, $silo, $fstab) = @_;
- my $boot = fsedit::get_root($fstab, 'boot')->{device};
- my ($wd, $num) = $boot =~ /^(.*\D)(\d*)$/;
-
- #- setup boot promvars for.
- require c;
- if ($boot =~ /^md/) {
- #- get all mbr devices according to /boot are listed,
- #- then join all zero based partition translated to prom with ';'.
- #- keep bootdev with the first of above.
- log::l("/boot is present on raid partition which is not currently supported for promvars");
- } else {
- if (!$silo->{use_partition}) {
- foreach (@$fstab) {
- if (!$_->{start} && $_->{device} =~ /$wd/) {
- $boot = $_->{device};
- log::l("found a zero based partition in $wd as $boot");
- last;
- }
- }
- }
- $silo->{bootalias} = c::disk2PromPath($boot);
- $silo->{bootdev} = $silo->{bootalias};
- log::l("preparing promvars for device=$boot");
- }
- c::hasAliases() or log::l("clearing promvars alias as non supported"), $silo->{bootalias} = '';
-
- if ($silo->{message}) {
- local *F;
- open F, ">$prefix/boot/message" and print F $silo->{message} or $silo->{message} = 0;
- }
- {
- local *F;
- local $\ = "\n";
- my $f = "$prefix/boot/silo.conf"; #- always write the silo.conf file in /boot ...
- symlinkf "../boot/silo.conf", "$prefix/etc/silo.conf"; #- ... and make a symlink from /etc.
- open F, ">$f" or die "cannot create silo config file: $f";
- log::l("writing silo config to $f");
-
- $silo->{$_} and print F "$_=$silo->{$_}" foreach qw(partition root default append);
- $silo->{$_} and print F $_ foreach qw(restricted);
- #- print F "password=", $silo->{password} if $silo->{restricted} && $silo->{password}; #- done by msec
- print F "timeout=", round(10 * $silo->{timeout}) if $silo->{timeout};
- print F "message=$silo->{boot}/message" if $silo->{message};
-
- foreach (@{$silo->{entries}}) {#my ($v, $e) = each %{$silo->{entries}}) {
- my $type = "$_->{type}=$_->{kernel_or_dev}"; $type =~ s|/boot|$silo->{boot}|;
- print F $type;
- print F "\tlabel=$_->{label}";
-
- if ($_->{type} eq "image") {
- my $initrd = $_->{initrd}; $initrd =~ s|/boot|$silo->{boot}|;
- print F "\tpartition=$_->{partition}" if $_->{partition};
- print F "\troot=$_->{root}" if $_->{root};
- print F "\tinitrd=$initrd" if $_->{initrd};
- print F "\tappend=\"$1\"" if $_->{append} =~ /^\s*"?(.*?)"?\s*$/;
- print F "\tread-write" if $_->{'read-write'};
- print F "\tread-only" if !$_->{'read-write'};
- }
- }
- }
- log::l("Installing boot loader...");
- $::testing and return;
- run_program::rooted($prefix, "silo", "2>", "/tmp/.error", $silo->{use_partition} ? ("-t") : ()) or
- run_program::rooted($prefix, "silo", "2>", "/tmp/.error", "-p", "2", $silo->{use_partition} ? ("-t") : ()) or
- die "silo failed";
- unlink "$prefix/tmp/.error";
-
- #- try writing in the prom.
- log::l("setting promvars alias=$silo->{bootalias} bootdev=$silo->{bootdev}");
- require c;
- c::setPromVars($silo->{bootalias}, $silo->{bootdev});
-}
-
-sub write_lilo_conf {
- my ($prefix, $lilo, $fstab, $hds) = @_;
- $lilo->{prompt} = $lilo->{timeout};
-
- 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
- }
- };
-
- #- try to use a specific stage2 if defined and present.
- -e "$prefix/boot/$lilo->{methods}{lilo}" and symlinkf $lilo->{methods}{lilo}, "$prefix/boot/lilo";
- log::l("stage2 of lilo used is " . readlink "$prefix/boot/lilo");
-
- if ($lilo->{methods}{lilo} eq "lilo-graphic") {
- -e "$prefix/boot/$lilo->{methods}{lilo}/message" and symlinkf "$lilo->{methods}{lilo}/message", "$prefix/boot/message";
- } else {
- -e "$prefix/boot/message" and unlink "$prefix/boot/message";
- print "-->$prefix/boot/messag<--\n";
-
- my $msg_en =
- #-PO: these messages will be displayed at boot time in the BIOS, use only ASCII (7bit)
-__("Welcome to %s the operating system chooser!
-
-Choose an operating system in the list above or
-wait %d seconds for default boot.
-
-");
- my $msg = translate($msg_en);
- #- use the english version if more than 20% of 8bits chars
- $msg = $msg_en if int(grep { $_ & 0x80 } unpack "c*", $msg) / length($msg) > 0.2;
- $msg = sprintf $msg, arch() =~ /sparc/ ? "SILO" : "LILO", $lilo->{timeout};
- local *F;
- open F, ">$prefix/boot/message" and print F $msg;
- }
- {
- local *F;
- local $\ = "\n";
- my $f = arch() =~ /ia64/ ? "$prefix/boot/efi/elilo.conf" : "$prefix/etc/lilo.conf";
-
- open F, ">$f" or die "cannot create lilo config file: $f";
- log::l("writing lilo config to $f");
-
- $lilo->{$_} and print F "$_=$lilo->{$_}" foreach qw(boot map install vga default append keytable);
- $lilo->{$_} and print F $_ foreach qw(linear lba32 compact prompt restricted);
- #- print F "password=", $lilo->{password} if $lilo->{restricted} && $lilo->{password}; #- done by msec
- print F "timeout=", round(10 * $lilo->{timeout}) if $lilo->{timeout};
-
- my $dev = $hds->[0]{device};
- my %dev2bios = map_index { $_ => $::i } dev2bios($hds, $lilo->{boot});
- if ($dev2bios{$dev}) {
- my %bios2dev = reverse %dev2bios;
- print F "disk=/dev/$bios2dev{0} bios=0x80";
- printf F "disk=/dev/$dev bios=0x%x", 0x80 + $dev2bios{$dev};
- } elsif ($dev =~ /hd[bde]/) {
- 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/);
-
- 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";
-
- if ($_->{type} eq "image") {
- print F "\troot=$_->{root}";
- print F "\tinitrd=", $file2fullname->($_->{initrd}) if $_->{initrd};
- print F "\tappend=\"$_->{append}\"" if $_->{append};
- print F "\tvga=$_->{vga}" if $_->{vga};
- print F "\tread-write" if $_->{'read-write'};
- print F "\tread-only" if !$_->{'read-write'};
- } else {
- print F "\ttable=$_->{table}" if $_->{table};
- print F "\tunsafe" if $_->{unsafe} && !$_->{table};
-
- if (my ($dev) = $_->{table} =~ m|/dev/(.*)|) {
- if ($dev2bios{$dev}) {
- #- boot off the nth drive, so reverse the BIOS maps
- my $nb = sprintf("0x%x", 0x80 + $dev2bios{$dev});
- $_->{mapdrive} ||= { '0x80' => $nb, $nb => '0x80' };
- }
- }
- while (my ($from, $to) = each %{$_->{mapdrive} || {}}) {
- print F "\tmap-drive=$from";
- print F "\t to=$to";
- }
- }
- }
- }
-}
-
-sub install_lilo {
- my ($prefix, $lilo, $fstab, $hds) = @_;
-
- write_lilo_conf($prefix, $lilo, $fstab, $hds);
-
- log::l("Installing boot loader...");
- $::testing and return;
- run_program::rooted_or_die($prefix, "lilo", "2>", "/tmp/.error") if (arch() !~ /ia64/);
- unlink "$prefix/tmp/.error";
-}
-
-sub dev2bios {
- my ($hds, $where) = @_;
- my @dev = map { $_->{device} } @$hds;
- member($where, @dev) or ($where) = @dev; #- if not on mbr,
-
- s/h(d[e-g])/x$1/ foreach $where, @dev; #- emulates ultra66 as xd_
-
- my $start = substr($where, 0, 2);
-
- my $translate = sub {
- $_ eq $where ? "aaa" : #- if exact match, value it first
- /^$start(.*)/ ? "ad$1" : #- if same class (ide/scsi/ultra66), value it before other classes
- $_;
- };
- @dev = map { $_->[0] }
- sort { $a->[1] cmp $b->[1] }
- map { [ $_, &$translate ] } @dev;
-
- s/x(d.)/h$1/ foreach @dev; #- switch back;
-
- @dev;
-}
-
-sub dev2grub {
- my ($dev, $dev2bios) = @_;
- $dev =~ m|^(/dev/)?(...)(.*)$| or die "dev2grub (bad device $dev), caller is " . join(":", caller());
- my $grub = $dev2bios->{$2} or die "dev2grub ($2)";
- "($grub" . ($3 && "," . ($3 - 1)) . ")";
-}
-
-sub write_grub_config {
- my ($prefix, $lilo, $fstab, $hds) = @_;
- my %dev2bios = (
- (map_index { $_ => "fd$::i" } detect_devices::floppies()),
- (map_index { $_ => "hd$::i" } dev2bios($hds, $lilo->{boot})),
- );
-
- {
- my %bios2dev = reverse %dev2bios;
- output "$prefix/boot/grub/device.map",
- join '', map { "($_) /dev/$bios2dev{$_}\n" } sort keys %bios2dev;
- }
- my $bootIsReiser = isThisFs("reiserfs", fsedit::get_root($fstab, 'boot'));
- my $file2grub = sub {
- my ($part, $file) = fsedit::file2part($prefix, $fstab, $_[0]);
- dev2grub($part->{device}, \%dev2bios) . $file;
- };
- {
- local *F;
- local $\ = "\n";
- my $f = "$prefix/boot/grub/menu.lst";
- open F, ">$f" or die "cannot create grub config file: $f";
- log::l("writing grub config to $f");
-
- $lilo->{$_} and print F "$_ $lilo->{$_}" foreach qw(timeout);
-
- print F "color black/cyan yellow/cyan";
- print F "i18n ", $file2grub->("/boot/grub/messages");
- print F "keytable ", $file2grub->($lilo->{keytable}) if $lilo->{keytable};
- #- since we use notail in reiserfs, altconfigfile is broken :-(
- unless ($bootIsReiser) {
- print F "altconfigfile ", $file2grub->(my $once = "/boot/grub/menu.once");
- output "$prefix$once", " " x 100;
- }
-
- map_index {
- print F "default $::i" if $_->{label} eq $lilo->{default};
- } @{$lilo->{entries}};
-
- foreach (@{$lilo->{entries}}) {
- print F "\ntitle $_->{label}";
-
- if ($_->{type} eq "image") {
- my $vga = $_->{vga} || $lilo->{vga};
- printf F "kernel %s root=%s %s%s%s\n",
- $file2grub->($_->{kernel_or_dev}),
- $_->{root} =~ /loop7/ ? "707" : $_->{root}, #- special to workaround bug in kernel (see #ifdef CONFIG_BLK_DEV_LOOP)
- $_->{append},
- $_->{'read-write'} && " rw",
- $vga && $vga ne "normal" && " vga=$vga";
- print F "initrd ", $file2grub->($_->{initrd}) if $_->{initrd};
- } else {
- print F "root ", dev2grub($_->{kernel_or_dev}, \%dev2bios);
- if ($_->{kernel_or_dev} !~ /fd/) {
- #- boot off the second drive, so reverse the BIOS maps
- $_->{mapdrive} ||= { '0x80' => '0x81', '0x81' => '0x80' }
- if $_->{table} && $lilo->{boot} !~ /$_->{table}/;
-
- map_each { print F "map ($::b) ($::a)" } %{$_->{mapdrive} || {}};
-
- print F "makeactive";
- }
- print F "chainloader +1";
- }
- }
- }
- my $hd = fsedit::get_root($fstab, 'boot')->{rootDevice};
-
- my $dev = dev2grub($lilo->{boot}, \%dev2bios);
- my ($s1, $s2, $m) = map { $file2grub->("/boot/grub/$_") } qw(stage1 stage2 menu.lst);
- my $f = "/boot/grub/install.sh";
- output "$prefix$f",
-"grub --device-map=/boot/grub/device.map --batch <<EOF
-install $s1 d $dev $s2 p $m
-quit
-EOF
-";
-
- output "$prefix/boot/grub/messages", map { substr(translate($_) . "\n", 0, 78) } ( #- ensure the translated messages are not too big the hard way
-#-PO: these messages will be displayed at boot time in the BIOS, use only ASCII (7bit)
-#-PO: and keep them smaller than 79 chars long
-__("Welcome to GRUB the operating system chooser!"),
-#-PO: these messages will be displayed at boot time in the BIOS, use only ASCII (7bit)
-#-PO: and keep them smaller than 79 chars long
-__("Use the %c and %c keys for selecting which entry is highlighted."),
-#-PO: these messages will be displayed at boot time in the BIOS, use only ASCII (7bit)
-#-PO: and keep them smaller than 79 chars long
-__("Press enter to boot the selected OS, \'e\' to edit the"),
-#-PO: these messages will be displayed at boot time in the BIOS, use only ASCII (7bit)
-#-PO: and keep them smaller than 79 chars long
-__("commands before booting, or \'c\' for a command-line."),
-#-PO: these messages will be displayed at boot time in the BIOS, use only ASCII (7bit)
-#-PO: and keep them smaller than 79 chars long
-__("The highlighted entry will be booted automatically in %d seconds."),
-);
-
- my $e = "$prefix/boot/.enough_space";
- output $e, 1; -s $e or die _("not enough room in /boot");
- unlink $e;
- $f;
-}
-
-sub install_grub {
- my ($prefix, $lilo, $fstab, $hds) = @_;
-
- my $f = write_grub_config($prefix, $lilo, $fstab, $hds);
-
- log::l("Installing boot loader...");
- $::testing and return;
- symlink "$prefix/boot", "/boot";
- run_program::run("sh", $f) or die "grub installation failed";
- unlink "$prefix/tmp/.error.grub", "/boot";
-}
-
-sub lnx4win_file {
- my $lilo = shift;
- map { local $_ = $_; s,/,\\,g; "$lilo->{boot_drive}:\\lnx4win$_" } @_;
-}
-
-sub loadlin_cmd {
- my ($prefix, $lilo) = @_;
- my $e = get_label("linux", $lilo) || first(grep { $_->{type} eq "image" } @{$lilo->{entries}});
-
- commands::cp("$prefix$e->{kernel_or_dev}", "$prefix/boot/vmlinuz") unless -e "$prefix/boot/vmlinuz";
- commands::cp("$prefix$e->{initrd}", "$prefix/boot/initrd.img") unless -e "$prefix/boot/initrd.img";
-
- $e->{label}, sprintf"%s %s initrd=%s root=%s $e->{append}",
- lnx4win_file($lilo, "/loadlin.exe", "/boot/vmlinuz", "/boot/initrd.img"),
- $e->{root} =~ /loop7/ ? "0707" : $e->{root}; #- special to workaround bug in kernel (see #ifdef CONFIG_BLK_DEV_LOOP)
-}
-
-sub install_loadlin {
- my ($prefix, $lilo, $fstab) = @_;
-
- my $boot;
- ($boot) = grep { $lilo->{boot} eq "/dev/$_->{device}" } @$fstab;
- ($boot) = grep { loopback::carryRootLoopback($_) } @$fstab unless $boot && $boot->{device_windobe};
- ($boot) = grep { isFat($_) } @$fstab unless $boot && $boot->{device_windobe};
- log::l("loadlin device is $boot->{device} (windobe $boot->{device_windobe})");
- $lilo->{boot_drive} = $boot->{device_windobe};
-
- my ($winpart) = grep { $_->{device_windobe} eq 'C' } @$fstab;
- log::l("winpart is $winpart->{device}");
- my $winhandle = any::inspect($winpart, $prefix, 'rw');
- my $windrive = $winhandle->{dir};
- log::l("windrive is $windrive");
-
- my ($label, $cmd) = loadlin_cmd($prefix, $lilo);
-
- #install_loadlin_config_sys($lilo, $windrive, $label, $cmd);
- #install_loadlin_desktop($lilo, $windrive);
-
- output "/initrd/loopfs/lnx4win/linux.bat", unix2dos(
-'@echo off
-echo Mandrake Linux
-smartdrv /C
-' . "$cmd\n");
-
-}
-
-sub install_loadlin_config_sys {
- my ($lilo, $windrive, $label, $cmd) = @_;
-
- my $config_sys = "$windrive/config.sys";
- local $_ = cat_($config_sys);
- output "$windrive/config.mdk", $_ if $_;
-
- my $timeout = $lilo->{timeout} || 1;
-
- $_ = "
-[Menu]
-menuitem=Windows
-menudefault=Windows,$timeout
-
-[Windows]
-" . $_ if !/^\Q[Menu]/m;
-
- #- remove existing entry
- s/^menuitem=$label\s*//mi;
- s/\n\[$label\].*?(\n\[|$)/$1/si;
-
- #- add entry
- s/(.*\nmenuitem=[^\n]*)/$1\nmenuitem=$label/s;
-
- $_ .= "
-[$label]
-shell=$cmd
-";
- output $config_sys, unix2dos($_);
-}
-
-sub install_loadlin_desktop {
- my ($lilo, $windrive) = @_;
- my $windir = lc(cat_("$windrive/msdos.sys") =~ /^WinDir=.:\\(\S+)/m ? $1 : "windows");
-
-#-PO: "Desktop" and "Start Menu" are the name of the directories found in c:\windows
-#-PO: so you may need to put them in English or in a different language if MS-windows doesn't exist in your language
- foreach (__("Desktop"),
-#-PO: "Desktop" and "Start Menu" are the name of the directories found in c:\windows
- __("Start Menu")) {
- my $d = "$windrive/$windir/" . translate($_);
- -d $d or $d = "$windrive/$windir/$_";
- -d $d or log::l("can't find windows $d directory"), next;
- output "$d/Linux4Win.url", unix2dos(sprintf
-q([InternetShortcut]
-URL=file:\lnx4win\lnx4win.exe
-WorkingDirectory=%s
-IconFile=%s
-IconIndex=0
-), lnx4win_file($lilo, "/", "/lnx4win.ico"));
- }
-}
-
-
-sub install {
- my ($prefix, $lilo, $fstab, $hds) = @_;
-
- {
- my $f = "$prefix/etc/sysconfig/system";
- setVarsInSh($f, add2hash_({ CLEAN_TMP => $lilo->{CLEAN_TMP} }, { getVarsFromSh($f) }));
- }
- $lilo->{keytable} = keytable($prefix, $lilo->{keytable});
-
- if (arch() =~ /i.86/) {
- #- when lilo is selected, we don't try to install grub.
- #- just create the config file in case it may be useful
- write_grub_config($prefix, $lilo, $fstab, $hds);
- }
-
- my %l = grep_each { $::b } %{$lilo->{methods}};
- my @rcs = map {
- my $f = $bootloader::{"install_$_"} or die "unknown bootloader method $_";
- eval { $f->(@_) };
- $@;
- } reverse sort keys %l; #- reverse sort for having grub installed after lilo if both are there.
-
- return if grep { !$_ } @rcs; #- at least one worked?
- die first(map { $_ } @rcs);
-}
-
-#-######################################################################################
-#- Wonderful perl :(
-#-######################################################################################
-1; #