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