summaryrefslogtreecommitdiffstats
path: root/images/make_boot_img
diff options
context:
space:
mode:
Diffstat (limited to 'images/make_boot_img')
-rwxr-xr-ximages/make_boot_img430
1 files changed, 430 insertions, 0 deletions
diff --git a/images/make_boot_img b/images/make_boot_img
new file mode 100755
index 000000000..6953b02df
--- /dev/null
+++ b/images/make_boot_img
@@ -0,0 +1,430 @@
+#!/usr/bin/perl
+
+use Config;
+use FileHandle;
+use MDK::Common;
+use POSIX;
+use Carp;
+
+Config->import;
+my ($arch) = $Config{archname} =~ /(.*?)-/;
+
+my $default_append = 'audit=0';
+my $default_acpi = '';
+my $default_vga = "vga=791 splash quiet";
+my $default_iswmd = "noiswmd";
+my $timeout = $ENV{BOOT_AUTOMATIC_METHOD} ? 5 : 150;
+my $isolinux_bin = '/usr/lib/syslinux/isolinux.bin';
+
+my $tmp_mnt = '/tmp/drakx_mnt';
+
+if ($>) {
+ $ENV{PATH} = "/sbin:/usr/sbin:$ENV{PATH}";
+}
+
+sub __ { print @_, "\n"; system(@_) }
+sub _ { __ @_; $? and croak "'" . join(' ', @_) . "failed ($?)\n" }
+
+sub mke2fs {
+ my ($f) = @_;
+ _ "/sbin/mke2fs -q -m 0 -F -s 1 $f";
+ _ "/sbin/tune2fs -c 0 -U clear -T 1970010101 $f";
+}
+
+_ "mkdir -p $tmp_mnt";
+mkdir "images";
+
+my @kernels = chomp_(cat_('all.kernels/.list'));
+
+my @all_images = (
+ if_($arch =~ /i.86|x86_64/, 'isolinux', 'boot.iso', 'all.img', 'hd_grub.img'),
+ );
+
+my @images = @ARGV ? @ARGV : map { "images/$_" } @all_images;
+
+foreach my $img (@images) {
+ my ($type, undef, $extension) = $img =~ m!([^/]*)(64)?\.([^.]*)$!;
+
+ if ($img =~ /hd_grub/) {
+ hd_grub($img);
+ } elsif ($img =~ /isolinux/) {
+ isolinux(\@kernels);
+
+ if (my ($tftpboot) = grep { -e $_ } qw(/tftpboot /var/lib/tftpboot)) {
+ system("/bin/cp -f isolinux/alt0/* $tftpboot");
+ }
+ } elsif ($img =~ /boot.iso/) {
+ boot_iso($img, \@kernels);
+ } elsif ($extension eq 'rdz') {
+ initrd("$img-$_", $_) foreach @kernels;
+ } elsif ($extension eq 'img') {
+ print STDERR "calling boot_img_$arch for $img\n";
+ $::{"boot_img_$arch"}->($type, "$img-$_", $_, "all.kernels/$_/vmlinuz") foreach @kernels;
+ rename("$img-$kernels[0]", $img);
+ } else {
+ die "unknown image $img";
+ }
+}
+
+# The ascii 15 / Shift In / ^O character before the 0 should not be removed
+sub syslinux_color {
+ chr(15) . "0" . {
+ default => '7',
+ blue => '9',
+ green => 'a',
+ red => 'c',
+ yellow => 'e',
+ white => 'f',
+ }->{$_[0]} || die "unknown color $_[0]\n";
+}
+
+sub syslinux_msg {
+ my ($msg_xml_file, @more_text) = @_;
+
+ require XML::Parser;
+
+ sub xml_tree2syslinux {
+ my ($current_color, $tree) = @_;
+ my (undef, @l) = @$tree;
+ join('', map {
+ my ($type, $val) = @$_;
+ if ($type eq '0') {
+ $val;
+ } else {
+ syslinux_color($type) . xml_tree2syslinux($type, $val) . syslinux_color($current_color);
+ }
+ } group_by2(@l));
+ }
+
+ print "parsing $msg_xml_file\n";
+ my $tree = XML::Parser->new(Style => 'Tree')->parsefile($msg_xml_file);
+ $tree->[0] eq 'document' or die "bad file $msg_xml_file\n";
+ my $text = xml_tree2syslinux('default', $tree->[1]);
+
+ " "
+ . $text . join('', @more_text)
+ . "\n" . syslinux_color('red') . "[F1-Help] [F2-Advanced Help]" . syslinux_color('default') . "\n";
+}
+
+sub syslinux_cfg {
+ my ($entries, $b_gfxboot) = @_;
+ my $default = 'linux';
+
+ my $header = <<EOF;
+default $default
+prompt 1
+timeout $timeout
+display help.msg
+implicit 1
+EOF
+ my $header_gfxboot = <<EOF;
+ui gfxboot.c32 bootlogo
+label harddisk
+ com32 chain.c32 hd0 exit
+EOF
+ my $header_non_gfxboot = <<EOF;
+F1 help.msg
+F2 advanced.msg
+F3 boot.msg
+EOF
+
+ my @l = map {
+ $_->{append} =~ s/\s+/ /g;
+ "label $_->{label}\n" .
+ " kernel $_->{kernel}\n" .
+ ($_->{initrd} ? " append initrd=$_->{initrd} $_->{append}\n" : '');
+ } @$entries;
+
+ $header . ($b_gfxboot ? $header_gfxboot : $header_non_gfxboot) . join('', @l);
+}
+
+sub trim {
+ return $_[0] =~ s/^\s+|\s+$//rg;
+}
+
+sub initrd {
+ my ($img, $kernel) = @_;
+ my $stage1_binary = $ENV{USE_LOCAL_STAGE1} ? trim(`realpath ../mdk-stage1/stage1`) : "";
+ my $init_binary = $ENV{USE_LOCAL_STAGE1} ? trim(`realpath ../mdk-stage1/init`) : "";
+ my $modules = " mgainstaller network-legacy nfs ";
+ my $drivers = `perl ../kernel/modules.pl list_needed_modules $kernel | xargs`;
+ my $fakedrivers = `perl ../kernel/modules.pl list_fake_modules $kernel | xargs`;
+
+ if ($ENV{DEBUGSTAGE1} || $ENV{BUILD_KA}) {
+ $modules="$modules busybox ";
+ }
+ $modules="$modules mgakadeploy " if $ENV{BUILD_KA};
+
+ my $extras = `perl ../kernel/modules.pl list_additional_firmware $kernel | xargs`;
+ chomp $extras;
+ my $install_extras = $extras ? "--install '$extras'" : "";
+
+ # TODO if --nofscks and --no-hostonly are switched, dracut gives an error - fix or report upstream
+ __ "DRAKX_STAGE1_BINARY=$stage1_binary DRAKX_INIT_BINARY=$init_binary DRAKX_FAKE_MODULES='$fakedrivers' dracut --confdir ./dracut.conf.d --add ' $modules ' --add-drivers ' $drivers ' $install_extras '$img' '$kernel'";
+ chmod(0644, $img);
+}
+
+
+sub entries_append {
+ my ($type) = @_;
+
+ my $automatic = $type =~ /cdrom/ ? 'automatic=method:cdrom ' : '';
+ $automatic .= 'changedisk ' if $type =~ /changedisk/;
+
+ my @simple_entries = (
+ linux => $default_vga,
+ vgalo => "vga=785",
+ vgahi => "vga=791",
+ text => "text",
+# patch => "patch $default_vga",
+ rescue => "audit=0 rescue",
+ );
+ my @entries = (
+ (map { $_->[0] => "$automatic$default_acpi $default_iswmd audit=0 $_->[1]" } group_by2(@simple_entries)),
+ noacpi => "$automatic$default_vga $default_iswmd audit=0 acpi=off",
+# restore => "$automatic$default_vga restore",
+ );
+
+ map { { label => $_->[0], append => join(' ', grep { $_ } $default_append, $_->[1]) } }
+ group_by2(@entries);
+}
+
+sub syslinux_cfg_all {
+ my ($type, $b_gfxboot) = @_;
+
+ syslinux_cfg([
+ (map {
+ { kernel => "$arch/vmlinuz", initrd => "$arch/all.rdz", %$_ };
+ } entries_append($type)),
+ (map_index {
+ { label => $arch, kernel => "$arch/vmlinuz", initrd => "$arch/all.rdz",
+ append => join(' ', grep { $_ } $default_append, $default_acpi, $default_vga, $default_iswmd) };
+ } @kernels),
+ ], $b_gfxboot);
+}
+sub remove_ending_zero {
+ my ($img) = @_;
+ _(q(perl -0777 -pi -e 's/\0+$//' ) . $img);
+}
+
+sub boot_img_i386 {
+ my ($type, $img, $kernel, $vmlinuz) = @_;
+
+ _ "rm -rf $tmp_mnt"; mkdir $tmp_mnt;
+ _ "cat $vmlinuz > $tmp_mnt/vmlinuz";
+
+ output("$tmp_mnt/help.msg", syslinux_msg('help.msg.xml'));
+ output("$tmp_mnt/advanced.msg", syslinux_msg('advanced.msg.xml'));
+
+ (my $rdz = $img) =~ s/\.img/.rdz/;
+ initrd($rdz, $kernel);
+ my $short_type = substr($type, 0, 8);
+
+ output("$tmp_mnt/syslinux.cfg",
+ syslinux_cfg([ map {
+ { kernel => 'vmlinuz', initrd => "$short_type.rdz", %$_ };
+ } entries_append($type) ]));
+
+ _ "cp -f $rdz $tmp_mnt/$short_type.rdz";
+ unlink $rdz;
+
+ # mtools wants the image to be a power of 32.
+ my $syslinux_overhead = 32 * 16;
+ my $size = max(ceil(chomp_(`du -s -k $tmp_mnt`) / 32) * 32 + $syslinux_overhead, 1440);
+
+ _ "/sbin/mkdosfs -C $img $size";
+ _ "mcopy -i $img $tmp_mnt/* ::";
+ _ "syslinux $img";
+ _ "rm -rf $tmp_mnt";
+}
+
+# alias to x86 variant, slightly bigger with images though
+sub boot_img_x86_64 { &boot_img_i386 }
+
+sub VERSION {
+ my ($kernels) = @_;
+
+ map { "$_\n" }
+ $ENV{DISTRIB_DESCR},
+ scalar gmtime(),
+ '', @$kernels;
+}
+
+sub syslinux_all_files {
+ my ($dir, $kernels) = @_;
+
+ eval { rm_rf($dir) }; mkdir_p($dir);
+
+ @$kernels or die "syslinux_all_files: no kernel\n";
+
+ each_index {
+ mkdir "$dir/$arch", 0777;
+ _ "cp all.kernels/$_/vmlinuz $dir/$arch";
+ initrd("images/all.rdz-$_", $_);
+ rename("images/all.rdz-$_", "$dir/$arch/all.rdz");
+ } @$kernels;
+
+ output("$dir/help.msg", syslinux_msg('help.msg.xml'));
+ output("$dir/advanced.msg", syslinux_msg('advanced.msg.xml',
+ "\nYou can choose the following kernels :\n",
+ map_index { " o " . syslinux_color('white') . "alt$::i" . syslinux_color('default') . " is kernel $_\n" } @$kernels));
+}
+
+sub isolinux {
+ my ($kernels) = @_;
+
+ syslinux_all_files('isolinux', $kernels);
+
+ _ "cp $isolinux_bin isolinux/isolinux.bin";
+ _ "cp /usr/lib/syslinux/ifcpu.c32 isolinux/ifcpu.c32";
+ _ "cp /usr/lib/syslinux/ldlinux.c32 isolinux/ldlinux.c32";
+ _ "cp /usr/lib/syslinux/libcom32.c32 isolinux/libcom32.c32";
+ _ "cp /usr/lib/syslinux/libgpl.c32 isolinux/libgpl.c32";
+ _ "cp /usr/lib/syslinux/libmenu.c32 isolinux/libmenu.c32";
+ _ "cp /usr/lib/syslinux/libutil.c32 isolinux/libutil.c32";
+ _ "cp /usr/lib/syslinux/gfxboot.c32 isolinux/gfxboot.c32";
+ _ "cp /usr/lib/syslinux/chain.c32 isolinux/chain.c32";
+ output("isolinux/isolinux.cfg", syslinux_cfg_all('cdrom', 1));
+
+ xbox_stage1() if arch() =~ /i.86/;
+}
+
+sub xbox_stage1() {
+ my $xbox_kernel = find { /xbox/ } all('all.kernels') or return;
+
+ my $dir = 'isolinux/xbox';
+ eval { rm_rf($dir) }; mkdir_p($dir);
+
+ _ "cp all.kernels/$xbox_kernel/vmlinuz $dir";
+ initrd("images/all.rdz-$xbox_kernel", $xbox_kernel);
+ rename("images/all.rdz-$xbox_kernel", "$dir/initrd");
+
+ _ "cp /usr/share/cromwell/xromwell-installer.xbe $dir/default.xbe";
+ output("$dir/linuxboot.cfg", <<EOF);
+kernel $dir/vmlinuz
+initrd $dir/initrd
+append root=/dev/ram3 ramdisk_size=36000 automatic=method:cdrom
+EOF
+}
+
+sub boot_iso {
+ my ($iso, $kernels) = @_;
+
+ syslinux_all_files('.boot_iso/isolinux', $kernels);
+
+ output('.boot_iso/VERSION', VERSION($kernels));
+
+ # for the boot iso, use standard isolinux
+ _ "cp $isolinux_bin .boot_iso/isolinux/isolinux.bin";
+ _ "cp /usr/lib/syslinux/ifcpu.c32 .boot_iso/isolinux/ifcpu.c32";
+ _ "cp /usr/lib/syslinux/ldlinux.c32 .boot_iso/isolinux/ldlinux.c32";
+ _ "cp /usr/lib/syslinux/libcom32.c32 .boot_iso/isolinux/libcom32.c32";
+ _ "cp /usr/lib/syslinux/libgpl.c32 .boot_iso/isolinux/libgpl.c32";
+ _ "cp /usr/lib/syslinux/libmenu.c32 .boot_iso/isolinux/libmenu.c32";
+ _ "cp /usr/lib/syslinux/libutil.c32 .boot_iso/isolinux/libutil.c32";
+ _ "cp /usr/lib/syslinux/chain.c32 .boot_iso/isolinux/chain.c32";
+
+ my $with_gfxboot = 0;
+ _ "cp /usr/share/gfxboot/themes/Mageia/install/* .boot_iso/isolinux" if $with_gfxboot;
+# _ "cp /home/pixel/cooker/soft/theme/mandriva-gfxboot-theme/inst/* .boot_iso/isolinux" if $with_gfxboot;
+ #_ "cp /home/teuf/mdv/src/mandriva-gfxboot-theme/inst/* .boot_iso/isolinux" if $with_gfxboot;
+ _ "cp /usr/lib/syslinux/gfxboot.c32 .boot_iso/isolinux/gfxboot.c32" if $with_gfxboot;
+
+ output('.boot_iso/isolinux/isolinux.cfg', syslinux_cfg_all('', $with_gfxboot));
+
+ if ($ENV{BOOT_AUTOMATIC_METHOD}) {
+ _ "sed -i 's#\\(append .*\\)\\(splash quiet\\|rescue\\)\$#\\1\\2 automatic=$ENV{BOOT_AUTOMATIC_METHOD}#' .boot_iso/isolinux/isolinux.cfg";
+ }
+
+ my $arch = arch();
+ my $options = "-J -joliet-long -r -v -T -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table";
+ my $cmd = "xorriso -as mkisofs -U -A 'Mageia-$ENV{DISTRIB_VERSION}-$arch-netinstall' -V 'Mageia-$ENV{DISTRIB_VERSION}-$arch-netinstall' -volset 'Mageia-$ENV{DISTRIB_VERSION}-$arch' $options";
+ # create efi stuff on the fly
+ if ($arch =~ /x86_64/) {
+ _ "mkdir -p .boot_iso/EFI/BOOT/";
+ # create efi loader
+ my $efi_core = "configfile normal boot linux loadenv ls reboot search search_label";
+ my $efi_part_fs = "part_msdos part_gpt part_apple fat iso9660 udf";
+ my $efi_gfx = "gfxmenu gfxterm efi_gop efi_uga video video_bochs video_cirrus video_fb font png";
+ _ "/usr/bin/grub2-mkimage --prefix='/EFI/BOOT' -O x86_64-efi -o .boot_iso/EFI/BOOT/bootx64.efi $efi_core $efi_part_fs $efi_gfx";
+ _ "cp -f grub2.config .boot_iso/EFI/BOOT/grub.cfg";
+ if ($ENV{BOOT_AUTOMATIC_METHOD}) {
+ _ "sed -i 's#\\(linux .*\\)#\\1 automatic=$ENV{BOOT_AUTOMATIC_METHOD}#' .boot_iso/EFI/BOOT/grub.cfg";
+ _ "sed -i 's#timeout=[0-9]*#timeout=1#' .boot_iso/EFI/BOOT/grub.cfg";
+ }
+ # add theme
+ _ "cp -r -L /boot/grub2/themes .boot_iso/EFI/BOOT/";
+ _ "cp -f grub2.theme .boot_iso/EFI/BOOT/themes/maggy/theme.txt";
+ _ "mkdir -p .boot_iso/EFI/BOOT/fonts";
+ _ "cp -f /usr/share/grub/unicode.pf2 .boot_iso/EFI/BOOT/fonts/";
+ # create efiboot.img, mtools wants the image to be a power of 32.
+ my $efisize = ceil(ceil(chomp_(`du -s -k .boot_iso/EFI`) / 1024) * 1024 / 32) * 32;
+ my $efi_img = ".boot_iso/isolinux/efiboot.img";
+ _ "/sbin/mkdosfs -F12 -C $efi_img $efisize";
+ _ "mcopy -s -i $efi_img .boot_iso/EFI ::";
+ # create iso
+ _ "$cmd -eltorito-alt-boot -e isolinux/efiboot.img -no-emul-boot -o $iso .boot_iso";
+ _ "isohybrid -u $iso";
+ } else {
+ _ "$cmd -o $iso .boot_iso";
+ _ "isohybrid -o 1 $iso";
+ }
+ rm_rf('.boot_iso');
+}
+
+sub hd_grub {
+ my ($img) = @_;
+ my $mapfile = '/tmp/device.map.tmp';
+
+ my ($grub_dir) = glob("/lib/grub/*-mageia");
+ my @grub_files = map { "$grub_dir/$_" } qw(stage1 stage2);
+
+ # mtools wants the image to be a power of 32.
+ my $size = ceil((40_000 + sum(map { -s $_ } @grub_files)) / 32 / 1024) * 32;
+
+ _ "rm -rf $tmp_mnt"; mkdir $tmp_mnt;
+ _ "cp @grub_files $tmp_mnt";
+
+ output("$tmp_mnt/menu.lst", <<EOF);
+timeout 10
+default 0
+fallback 1
+
+title Mageia Install
+
+root (hd0,0)
+kernel /cauldron/isolinux/alt0/vmlinuz $default_append $default_acpi $default_vga $default_iswmd automatic=method:disk
+initrd /cauldron/isolinux/alt0/all.rdz
+
+title Help
+
+pause To display the help, press <space> until you reach "HELP END"
+pause .
+pause Please see https://doc.mageia.org/ for a friendlier solution
+pause .
+pause To specify the location where Mageia is copied,
+pause choose "Mageia Install", and press "e".
+pause Then change "root (hd0,0)". FYI:
+pause - (hd0,0) is the first partition on first bios hard drive (usually hda1)
+pause - (hd0,4) is the first extended partition (usually hda5)
+pause - (hd1,0) is the first partition on second bios hard drive
+pause Replace /cauldron to suit the directory containing Mageia
+pause .
+pause HELP END
+EOF
+
+ _ "/sbin/mkdosfs -C $img $size";
+ _ "mcopy -i $img $tmp_mnt/* ::";
+ _ "rm -rf $tmp_mnt";
+
+ output($mapfile, "(fd0) $img\n");
+
+ open(my $G, "| grub --device-map=$mapfile --batch");
+ print $G <<EOF;
+root (fd0)
+install /stage1 d (fd0) /stage2 p /menu.lst
+quit
+EOF
+ close $G;
+ unlink $mapfile;
+}