#!@PERL@ # # Copyright (c) 1994-1996, 1998-2000 University of Utah and the Flux Group. # All rights reserved. # # This file is part of the Flux OSKit. The OSKit is free software, also known # as "open source;" you can redistribute it and/or modify it under the terms # of the GNU General Public License (GPL), version 2, as published by the Free # Software Foundation (FSF). To explore alternate licensing terms, contact # the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271. # # The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have # received a copy of the GPL along with the OSKit; see the file COPYING. If # not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA. # # This little script uses GNU ld to build a Linux 16-bit compressed boot image # from a set of boot modules. # # Usage: mklinux2 [options] [files ...] # # Options: # -x filename # Use as the MultiBoot adaptor file instead of the default. # -o filename # Specify the output of the resulting Linux image. The # default is "zImage" in the current directory. # -c 'string' # Specify a command line to pass to the kernel when it is # invoked. # -stdin # Take file specifications from stdin, in addition to those on the # command line. This is useful when using another script to build # a list of file specifications which can then be piped into this # script. # -save-temps # Debugging option to save temporary files instead of deleting them # after the image is built. # [files ...] # A list of file specifications in the format pathname1:pathname2, # where pathname1 is the name of a local module which is placed in the # boot image. If :pathname2 is provided, it specifies the name to give # the module in the image. If :pathname2 is omitted, it defaults to # pathname1. # # The first file specification is typically the name of the Oskit kernel. # $bootdir = $ENV{"BOOTDIR"}; $cc = $ENV{"CC"}; $ld = $ENV{"LD"}; if (!$cc) { $cc = "@CC@"; } if (!$ld) { $ld = "@LD@"; } if (!$bootdir) { $bootdir = "@prefix@/lib/boot"; } $bb="$bootdir/linuxboot.bin"; @modules = (); $outfile="zImage"; $savetemps=0; $fromstdin = 0; $ldopts="-Ttext 0 -defsym _start=0 -oformat binary"; $cmdlinefile="bootadapter_cmdline"; $def_syssize = 0x7f00; $def_setupssecs = 4; if ($#ARGV == -1) { print "Usage: mklinux2 [option | filename]\n"; exit; } # Parse the command-line options while ($#ARGV >= 0) { if ($ARGV[0] eq "-x") { $bb = $ARGV[1]; shift @ARGV; } elsif ($ARGV[0] eq "-o") { $outfile = $ARGV[1]; shift @ARGV; } elsif ($ARGV[0] eq "-c") { $cmdline = $ARGV[1]; shift @ARGV; } elsif ($ARGV[0] eq "-stdin") { $fromstdin = 1; } elsif ($ARGV[0] eq "-save-temps") { $savetemps = 1; } else { push(@modules, $ARGV[0]); } shift @ARGV; } # Add in anything from stdin if they've asked for it. if ($fromstdin) { while () { @words = split; push(@modules, @words); } } # Link in the command line if they specified one if ($cmdline) { open(CMD, ">$outfile.cmdline") || die "could not open cmdline file: $!\n"; print CMD "$cmdline\n"; push(@modules, "${outfile}.cmdline:${cmdlinefile}"); close(CMD); } open(OUT, ">${outfile}.mods.S") || die "Could not open outfile: $!\n"; @files = (); @linksmade = (); # Wrap each of the input files in a .o file. # At the same time, build an assembly language module # containing a table describing the boot modules. print OUT ".text; .long 0xf00baabb\n"; foreach $module (@modules) { $file = $module; $file =~ s/:.*$//; $string = $module; $string =~ s/^[^:]*://; if (!length($string)) { $string = $file; } if (!$FOUND{$file}) { # Must be unique or we get linker probs push(@files, $file); #This is where the shell script bogged down } $FOUND{$file} = 1; # Convert all non alphanumeric characters to underscores. # The BFD binary input format will do the same thing # to produce the symbol names that it wraps around the input files $sym_name = $file; $sym_name =~ s/[^a-zA-Z0-9]/_/g; print OUT<$outfile.tmp.gz"); if ($res) { &cleanup(); die "FATAL: gzip failed: $res\n"; } # Create the final boot image by tacking that onto the end of 'linuxboot.bin'. $res = system("cat $bootdir/linuxboot.bin $outfile.tmp.gz >$outfile"); if ($res) { &cleanup(); die "FATAL: final cat failed: $res\n"; } # Update the system size in the boot image, so we only load as much # as we need, not DEF_SYSSIZE open(OUT, "+< ${outfile}") || die "Couldn't open $outfile.\n"; $size = (stat OUT)[7]; $sys_size = ($size + 15) / 16; if ($sys_size > $def_syssize) { print "System size is too big!\n"; } seek(OUT, 500, 0) || die "Couldn't seek to SYS_SIZE offset.\n"; $buf = pack("v", $sys_size); (syswrite(OUT, $buf, 2) == 2) || die "Couldn't write system size!\n"; close OUT; # Nuke our temp files, unless asked not to. if (!$savetemps) { system("rm -f $outfile.mods.S $outfile.mods.o ${outfile}.cmdline $outfile.tmp*"); } exit(0); # A stub if we need to do any cleanup on failure. sub cleanup { ; }