First cut of "wrapper" program
Paul Mackerras
paulus at samba.org
Thu Sep 21 09:38:26 EST 2006
Here is a prototype of a "wrapper" program which will take a kernel,
and optionally an initrd image and/or a device tree blob, and create a
bootable zImage. My idea is that the Makefile in arch/powerpc/boot
will construct the files that this needs, then run it one or more
times to create whatever images are needed.
The type of zImage that is created is selected with the -p flag. This
also specifies an extra object file to be linked in that will contain
the platform_init() function. So for the xyzzy platform, we would
arrange for an xyzzy.o to be made in arch/powerpc/boot, and for the
wrapper to be invoked with "-p xyzzy".
Currently the wrapper uses the strip, objcopy and ld programs, which
need to be the powerpc cross-utilities if you are cross-building. You
can use the -C flag to specify a prefix for these programs if
necessary.
It also uses several files which it gets from a data directory, which
is by default ./arch/powerpc/boot, but which can be changed with the
-D flag. The files it needs from there are:
a platform-specific object file (of.o for OF-based platforms)
crt0.o
empty.o
wrapper.a
zImage.lds
zImage.coff.lds
addnote
hack-coff
Although this will start out in arch/powerpc/boot, my idea is that it
is a stand-alone thing that could be pulled out and built and used
quite independently of the kernel source tree. For this reason I
really want to avoid using CONFIG_* symbols in the code.
Comments?
Paul.
#!/bin/sh
# Copyright (C) 2006 Paul Mackerras, IBM Corporation <paulus at samba.org>
# This program may be used under the terms of version 2 of the GNU
# General Public License.
# This script takes a kernel binary and optionally an initrd image
# and/or a device-tree blob, and creates a bootable zImage for a
# given platform.
# Options:
# -o zImage specify output file
# -p platform specify platform (links in $platform.o)
# -i initrd specify initrd file
# -d devtree specify device-tree blob
# -s tree.dts specify device-tree source file (needs dts installed)
# -c cache $kernel.strip.gz (use if present & newer, else make)
# -C prefix specify command prefix for cross-building tools
# (strip, objcopy, ld)
# -D dir specify directory containing data files used by script
# (default ./arch/powerpc/boot)
# -W dir specify working directory for temporary files (default .)
# defaults
kernel=
ofile=zImage
platform=of
initrd=
dtb=
dts=
cacheit=
# cross-compilation prefix
CROSS=
# directory for object and other files used by this script
object=arch/powerpc/boot
# directory for working files
tmpdir=.
usage() {
echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2
echo ' [-d devtree] [-s tree.dts] [-c] [-C cross-prefix]' >&2
echo ' [-D datadir] [-W workingdir] [vmlinux]' >&2
exit 1
}
while [ "$#" -gt 0 ]; do
case "$1" in
-o)
shift
[ "$#" -gt 0 ] || usage
ofile="$1"
;;
-p)
shift
[ "$#" -gt 0 ] || usage
platform="$1"
;;
-i)
shift
[ "$#" -gt 0 ] || usage
initrd="$1"
;;
-d)
shift
[ "$#" -gt 0 ] || usage
dtb="$1"
;;
-s)
shift
[ "$#" -gt 0 ] || usage
dts="$1"
;;
-c)
cacheit=y
;;
-C)
shift
[ "$#" -gt 0 ] || usage
CROSS="$1"
;;
-D)
shift
[ "$#" -gt 0 ] || usage
object="$1"
;;
-W)
shift
[ "$#" -gt 0 ] || usage
tmpdir="$1"
;;
-?)
usage
;;
*)
[ -z "$kernel" ] || usage
kernel="$1"
;;
esac
shift
done
if [ -n "$dts" ]; then
if [ -z "$dtb" ]; then
dtb="$platform.dtb"
fi
dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1
fi
if [ -z "$kernel" ]; then
kernel=vmlinux
fi
platformo=$object/"$platform".o
lds=$object/zImage.lds
case "$platform" in
pmac|pseries)
platformo=$object/of.o
;;
pmaccoff)
platformo=$object/of.o
lds=$object/zImage.coff.lds
;;
miboot)
# this is quite different...
tmpvm=$tmpdir/vmlinux.bin.$$
${CROSS}objcopy -O binary "$kernel" $tmpvm
gzip -f -9 $tmpvm
tmpir=
if [ -n "$initrd" ]; then
tmpir=--add-section=initrd="$initrd"
fi
${CROSS}objcopy -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment \
--add-section=image=$tmpvm.gz $tmpir \
$object/empty.o "$ofile"
rm $tmpvm.gz
exit 0
esac
tmp=$tmpdir/zImage.$$.o
cp $object/empty.o $tmp
addsec() {
${CROSS}objcopy $1 \
--add-section=.kernel:$3="$2" \
--set-section-flags=.kernel:$3=contents,alloc,load,readonly,data
}
if [ -n "$cacheit" ]; then
vmz="$tmpdir/`basename \"$kernel\"`.strip"
if [ ! -f "$vmz.gz" -o "$vmz.gz" -ot "$kernel" ]; then
cp "$kernel" "$vmz"
${CROSS}strip "$vmz"
gzip -f -9 "$vmz"
fi
addsec $tmp "$vmz.gz" vmlinux.strip
else
tmpvmz=$tmpdir/vmlinux.$$
cp "$kernel" $tmpvmz
${CROSS}strip $tmpvmz
gzip -f -9 $tmpvmz
addsec $tmp $tmpvmz.gz vmlinux.strip
rm $tmpvmz.gz
fi
if [ -n "$initrd" ]; then
addsec $tmp "$initrd" initrd
fi
if [ -n "$dtb" ]; then
addsec $tmp "$dtb" dtb
fi
${CROSS}ld -m elf32ppc -T $lds -o "$ofile" \
$object/crt0.o $platformo $tmp $object/wrapper.a
rm $tmp
# post-processing needed for some platforms
case "$platform" in
pseries)
$object/addnote "$ofile"
;;
pmaccoff)
${CROSS}objcopy -O aixcoff-rs6000 --set-start 0x500000 "$ofile"
$object/hack-coff "$ofile"
;;
esac
More information about the Linuxppc-dev
mailing list