oskit/oskit-20020317/boot/multiboot/mkmb2.in

188 lines
5.5 KiB
Plaintext
Executable File

#!@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 32-bit MultiBoot boot image
# from a MultiBoot kernel and a set of boot modules.
#
# Usage: mkmb2 [options] [files ...]
#
# Options:
# -x filename
# Use <filename> as the MultiBoot adaptor file instead of the default.
# -o filename
# Specify the output <filename> of the resulting multiboot image. The
# default is "Image" in the current directory.
# -c 'string'
# Specify a command line <string> to pass to the kernel when it is
# invoked.
# -save-temps
# Debugging option to save temporary files instead of deleting them
# after the image is built.
# -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.
# [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/mbboot.o";
@modules = ();
$outfile="Image";
$savetemps=0;
$fromstdin = 0;
$ldopts="-Ttext 100000 -n";
$cmdlinefile="bootadapter_cmdline";
if ($#ARGV == -1) {
print "Usage: mkmb2 [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; }
elsif ($ARGV[0] eq "-K") { $NOBIN{$ARGV[1]} = 1; }
else { push(@modules, $ARGV[0]); }
shift @ARGV;
}
# Add in anything from stdin if they've asked for it.
if ($fromstdin) {
while (<STDIN>) {
@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";
print OUT ".data; .globl boot_modules,_boot_modules; boot_modules:; _boot_modules:\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.
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<<EOL;
.long _binary_${sym_name}_start
.long _binary_${sym_name}_end
.long 1f
.data 2
1: .ascii "${string}\\0"
.data
EOL
}
print OUT ".long 0; .data; .align 4\n";
close(OUT);
# Turn the assembly discription module into a .o
$res = system("${cc} -c -o ${outfile}.mods.o ${outfile}.mods.S");
if ($res) {
&cleanup();
die "FATAL: C compiler ($cc) failed\n";
}
# Parse the file list, doing any necessary magic to the files.
# I'm leaving this in for now for experimentation with different
# linker args to try to get library files to load properly.
$filelist = "";
foreach $file (@files) {
## Escape any '$' that occur in file names (happens a lot with Java classes)
$file =~ s/\$/\\\$/g;
if ($NOBIN{$file}) {
$filelist .= "$file ";
} else {
$filelist .= "$file ";
}
}
# Link the MultiBoot boot adaptor file and the module vector file
# with the boot module files.
# Use the binary bfd backend for the input bmod files.
$res = system("$ld $ldopts -o $outfile $bb $outfile.mods.o -b binary $filelist -b elf32-i386");
if ($res) {
&cleanup();
die "FATAL: linker ($ld) failed: $res\n";
}
# Nuke our temp files, unless asked not to.
if (!$savetemps) {
system("rm -f $outfile.mods.S $outfile.mods.o ${outfile}.cmdline");
}
exit(0);
# A stub if we need to do any cleanup on failure.
sub cleanup {
;
}