home *** CD-ROM | disk | FTP | other *** search
- package lilo;
-
-
-
-
-
-
-
-
- use common qw(:common :file);
- use partition_table qw(:types);
- use log;
- use fsedit;
- 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',
- );
-
-
-
-
-
-
- sub mkinitrd($$$) {
- my ($prefix, $kernelVersion, $initrdImage) = @_;
-
- $::testing and return;
-
- modules::load('loop');
- run_program::rooted($prefix, "mkinitrd", "-f", $initrdImage, "--ifneeded", $kernelVersion) or unlink("$prefix/$initrdImage");
- -e "$prefix/$initrdImage" or die "mkinitrd failed";
- }
-
- sub mkbootdisk($$$;$) {
- my ($prefix, $kernelVersion, $dev, $append) = @_;
-
- modules::load('loop');
- my @l = qw(mkbootdisk --noprompt); push @l, "--appendargs", $append if $append;
- run_program::rooted($prefix, @l, "--device", "/dev/$dev", $kernelVersion) or die "mkbootdisk failed";
- }
-
- 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)$/) {
- $b{entries}{$v} = $e = { type => $_ };
- $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};
- $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 empty)), !$type;
- }
-
- sub add_entry($$$) {
- my ($entries, $image, $v) = @_;
- my (%usedold, $freeold);
-
- do { $usedold{$1 || 0} = 1 if $_->{label} =~ /^old ([^_]*)_/x } foreach (values %$entries);
- foreach (0..scalar keys %usedold) { exists $usedold{$_} or $freeold = $_ || '', last }
-
- do { $_->{label} = "old${freeold}_$_->{label}" if $_->{label} eq $v->{label} } foreach (values %$entries);
- $entries->{$image} = $v;
- }
-
- sub add_kernel($$$$$) {
- my ($prefix, $lilo, $kernelVersion, $specific, $v) = @_;
- my $ext = $specific && "-$specific";
- my ($vmlinuz, $image, $initrdImage) = ("vmlinuz-$kernelVersion$specific", "/boot/vmlinuz$ext", "/boot/initrd$ext.img");
- if (-e "$prefix/boot/$vmlinuz") {
- {
- my $f = "initrd-$kernelVersion$specific.img";
- eval { mkinitrd($prefix, "$kernelVersion$specific", "/boot/$f") };
- undef $initrdImage if $@;
- symlinkf $f, "$prefix$initrdImage" if $initrdImage;
- }
- add2hash($v,
- {
- type => 'image',
- label => 'linux',
- initrd => $initrdImage,
- append => $lilo->{perImageAppend},
- });
- symlinkf "$vmlinuz", "$prefix/$image" if $specific;
- add_entry($lilo->{entries}, $image, $v);
- 1;
- } else {
- log::l("unable to find kernel image $prefix/boot/$vmlinuz");
- 0;
- }
- }
-
- sub suggest($$$$$) {
- my ($prefix, $lilo, $hds, $fstab, $kernelVersion) = @_;
- my $root = fsedit::get_root($fstab)->{device};
- my ($onmbr, $unsafe) = $lilo->{crushMbr} ? (1, 0) : suggest_onmbr($hds);
- add2hash_($lilo,
- {
- boot => "/dev/" . ($onmbr ? $hds->[0]{device} : fsedit::get_root($fstab, 'boot')->{device}),
- bootUnsafe => $unsafe,
- map => "/boot/map",
- default => "linux",
- timeout => $onmbr && 5,
- install => "/boot/boot.b",
- });
- $lilo->{disk} ||= "/dev/$hds->[0]{device} bios=0x80" if $hds->[0]{device} =~ /^hd[be]$/;
-
- if (!$lilo->{message} || $lilo->{message} eq "1") {
- $lilo->{message} = join('', cat_("$prefix/boot/message"));
- if (!$lilo->{message}) {
- my $msg_en =
- __("Welcome to LILO the operating system chooser!
-
- To list the possible choices, press <TAB>.
-
- To load one of them, write its name and press <ENTER> or wait %d seconds for default boot.
-
- ");
- my $msg = translate($msg_en);
-
- $msg = $msg_en if int(grep { $_ & 0x80 } unpack "c*", $msg) / length($msg) > 0.2;
- $lilo->{message} = sprintf $msg, $lilo->{timeout};
- }
- }
-
- my $isSecure = -e "$prefix/boot/vmlinuz-${kernelVersion}secure";
-
- 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;
- }
- add_kernel($prefix, $lilo, $kernelVersion, $isSecure ? 'secure' : 'smp',
- {
- label => 'linux',
- root => "/dev/$root",
- }) if $isSecure || $isSMP;
- add_kernel($prefix, $lilo, $kernelVersion, '',
- {
- label => $isSecure || $isSMP ? 'linux-up' : 'linux',
- root => "/dev/$root",
- });
-
-
- my ($dos, $win) = 0, 0;
- foreach (@$hds) {
- foreach (@{$_->{primary}{normal}}) {
- add_entry($lilo->{entries}, "/dev/$_->{device}",
- {
- type => 'other',
- label => isDos($_) ? "dos" . ($dos++ ? $dos : '') :
- "windows" . ($win++ ? $win : '') ,
- table => "/dev/$_->{rootDevice}",
- }) if isFat($_) && isFat({ type => fsedit::typeOfPart($_->{device}) });
- }
- }
-
- add_entry($lilo->{entries}, '/dev/fd0',
- {
- type => 'other',
- 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 install($$) {
- my ($prefix, $lilo) = @_;
- $lilo->{prompt} = $lilo->{timeout};
-
- $lilo->{keytable} = keytable($prefix, $lilo->{keytable});
-
- 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/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 disk);
- $lilo->{$_} and print F $_ foreach qw(linear compact prompt restricted);
-
- print F "timeout=", round(10 * $lilo->{timeout}) if $lilo->{timeout};
- print F "message=/boot/message" if $lilo->{message};
-
- while (my ($v, $e) = each %{$lilo->{entries}}) {
- print F "$e->{type}=$v";
- print F "\tlabel=$e->{label}";
-
- if ($e->{type} eq "image") {
- print F "\troot=$e->{root}";
- print F "\tinitrd=$e->{initrd}" if $e->{initrd};
- print F "\tappend=\"$1\"" if $e->{append} =~ /^\s*"?(.*?)"?\s*$/;
- print F "\tvga=$e->{vga}" if $e->{vga};
- print F "\tread-write" if $e->{'read-write'};
- print F "\tread-only" if !$e->{'read-write'};
- } else {
- print F "\ttable=$e->{table}" if $e->{table};
- print F "\tunsafe" if $e->{unsafe} && !$e->{table};
-
-
- $e->{mapdrive} ||= { '0x80' => '0x81', '0x81' => '0x80' }
- if $e->{table} && $lilo->{boot} !~ /$e->{table}/;
-
- while (my ($from, $to) = each %{$e->{mapdrive} || {}}) {
- print F "\tmap-drive=$from";
- print F "\t to=$to";
- }
- }
- }
- }
- log::l("Installing boot loader...");
- $::testing and return;
- run_program::rooted($prefix, "lilo", "2>", "/tmp/.error") or die "lilo failed";
- unlink "$prefix/tmp/.error";
- }
-
-
-
-
- 1; #
-