| #!/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" |