blob: 8c4ee983e99b7b8e8e87e6fb6a4e67c687d3850d [file] [log] [blame] [edit]
#!/bin/sh
#
# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Build a qemu-bootable harddisk image.
#
# Usage:
# An optional kernel command line argument is provided with -a.
# The kernel image is provided with -k.
# The output harddisk image is specified with -o.
# Userland images are provided after that (usually only one).
#
# Authors:
# Benjamin Kalman, 2009
# Michael von Tessin, 2010
# Support build system debugging directive passed from above.
if [ 0${V} -ge 3 ]; then
set -x
fi
# Find syslinux
SYSLINUX=`which syslinux`
if [ -z "${SYSLINUX}" ]; then
echo "syslinux not found." >&2
exit 1
fi
SYSLINUXDIR=`echo $SYSLINUX | sed 's:/bin/:/share/:'`
[ -d "$SYSLINUXDIR" ] || SYSLINUXDIR="`echo $SYSLINUXDIR | sed 's:/share/:/lib/:'`"
[ -d "$SYSLINUXDIR" ] || {
echo >&2 "Cannot find syslinux data directory!"
exit 1
}
if [ -f "$SYSLINUXDIR"/mbr.bin ]
then
SYSLINUX_MODULES="$SYSLINUXDIR"
MBR="$SYSLINUXDIR"/mbr.bin
elif [ -d "$SYSLINUXDIR"/modules ]
then
SYSLINUX_MODULES="$SYSLINUXDIR"/modules/bios/
MBR="$SYSLINUXDIR"/mbr/mbr.bin
fi
[ -f "$MBR" ] || {
echo >&2 "Can't find mbr.bin. Is syslinux installed?"
exit 1
}
trap "rm -f mtoolsrc syslinux.cfg mbr.bin" 0
# Parse options
while getopts "k:o:a:" flag ; do
case "$flag" in
k) KERNEL="$OPTARG" ;;
o) OUTIMG="$OPTARG" ;;
a) CMDLINE="$OPTARG" ;;
esac
done
shift $(($OPTIND-1))
UIMGS=$@
if [ ! -f "$KERNEL" -o -z "$OUTIMG" -o -z "$UIMGS" ] ; then
echo "Usage: $0 [-a kernel_cmdline] -k kernel_image -o output_image userland_images ..."
exit 1
fi
for UIMG in $UIMGS ; do
if [ ! -f "$UIMG" ] ; then
echo "Error: Userland image '$UIMG' not found!"
exit 1
fi
done
MODULES="$SYSLINUX_MODULES/mboot.c32"
[ -f $SYSLINUX_MODULES/libcom32.c32 ] && MODULES="$MODULES $SYSLINUX_MODULES/libcom32.c32"
# Calculate image size and number of cylinders
IMGSIZE=`stat -c '%s' $UIMGS $KERNEL $MODULES | awk ' { sum += $1 } END { print sum }'`
echo "final image size will be $IMGSIZE"
HEADS=16
SECTORS=63
BLKSPERCYL=`expr $HEADS \* $SECTORS`
CYLINDERS=`expr 2 + $IMGSIZE / 512 / $BLKSPERCYL`
# Create a blank image
dd if=/dev/zero of="$OUTIMG" count=1 seek=`expr $CYLINDERS \* $BLKSPERCYL - 1` bs=512 2>/dev/null
# Set up mtools
echo "drive c: file=\"$OUTIMG\" partition=1" > mtoolsrc
export MTOOLSRC=mtoolsrc
# Get mbr.bin and blow up/cut down to 512 bytes (required by mtools)
cat "$MBR" /dev/zero 2>/dev/null | head -c 512 > mbr.bin
# Create filesystem
which mpartition >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "mpartition not found. Is mtools installed?" >&2
exit 1
fi
mpartition -I -B mbr.bin c:
mpartition -c -t $CYLINDERS -h $HEADS -s $SECTORS c:
mpartition -a c:
mformat c:
syslinux --offset `expr $SECTORS \* 512` $OUTIMG
# Write syslinux config file
UIMGS_CFG=""
for UIMG in $UIMGS
do
UIMGS_CFG="$UIMGS_CFG --- `basename $UIMG`"
done
cat > syslinux.cfg <<EOF
serial 0 115200
default mylabel
label mylabel
kernel mboot.c32
append `basename $KERNEL` $CMDLINE $UIMGS_CFG
EOF
# Install kernel and apps to the image
for file in $KERNEL $UIMGS $MODULES syslinux.cfg
do
mcopy "$file" c: || {
echo "Error: mcopy $file failed!" >&2
exit 1
}
done
# And we're done
echo "Image '$OUTIMG' successfully created"