1#!/bin/sh 2# 3# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4# 5# SPDX-License-Identifier: BSD-2-Clause 6# 7 8# Build a qemu-bootable harddisk image. 9# 10# Usage: 11# An optional kernel command line argument is provided with -a. 12# The kernel image is provided with -k. 13# The output harddisk image is specified with -o. 14# Userland images are provided after that (usually only one). 15# 16# Authors: 17# Benjamin Kalman, 2009 18# Michael von Tessin, 2010 19 20# Support build system debugging directive passed from above. 21if [ 0${V} -ge 3 ]; then 22 set -x 23fi 24 25# Find syslinux 26SYSLINUX=`which syslinux` 27if [ -z "${SYSLINUX}" ]; then 28 echo "syslinux not found." >&2 29 exit 1 30fi 31SYSLINUXDIR=`echo $SYSLINUX | sed 's:/bin/:/share/:'` 32[ -d "$SYSLINUXDIR" ] || SYSLINUXDIR="`echo $SYSLINUXDIR | sed 's:/share/:/lib/:'`" 33 34[ -d "$SYSLINUXDIR" ] || { 35 echo >&2 "Cannot find syslinux data directory!" 36 exit 1 37} 38 39if [ -f "$SYSLINUXDIR"/mbr.bin ] 40then 41 SYSLINUX_MODULES="$SYSLINUXDIR" 42 MBR="$SYSLINUXDIR"/mbr.bin 43elif [ -d "$SYSLINUXDIR"/modules ] 44then 45 SYSLINUX_MODULES="$SYSLINUXDIR"/modules/bios/ 46 MBR="$SYSLINUXDIR"/mbr/mbr.bin 47fi 48 49[ -f "$MBR" ] || { 50 echo >&2 "Can't find mbr.bin. Is syslinux installed?" 51 exit 1 52} 53 54trap "rm -f mtoolsrc syslinux.cfg mbr.bin" 0 55 56# Parse options 57while getopts "k:o:a:" flag ; do 58 case "$flag" in 59 k) KERNEL="$OPTARG" ;; 60 o) OUTIMG="$OPTARG" ;; 61 a) CMDLINE="$OPTARG" ;; 62 esac 63done 64shift $(($OPTIND-1)) 65UIMGS=$@ 66 67if [ ! -f "$KERNEL" -o -z "$OUTIMG" -o -z "$UIMGS" ] ; then 68 echo "Usage: $0 [-a kernel_cmdline] -k kernel_image -o output_image userland_images ..." 69 exit 1 70fi 71 72for UIMG in $UIMGS ; do 73 if [ ! -f "$UIMG" ] ; then 74 echo "Error: Userland image '$UIMG' not found!" 75 exit 1 76 fi 77done 78 79MODULES="$SYSLINUX_MODULES/mboot.c32" 80[ -f $SYSLINUX_MODULES/libcom32.c32 ] && MODULES="$MODULES $SYSLINUX_MODULES/libcom32.c32" 81# Calculate image size and number of cylinders 82 83IMGSIZE=`stat -c '%s' $UIMGS $KERNEL $MODULES | awk ' { sum += $1 } END { print sum }'` 84 85echo "final image size will be $IMGSIZE" 86 87HEADS=16 88SECTORS=63 89BLKSPERCYL=`expr $HEADS \* $SECTORS` 90CYLINDERS=`expr 2 + $IMGSIZE / 512 / $BLKSPERCYL` 91 92# Create a blank image 93dd if=/dev/zero of="$OUTIMG" count=1 seek=`expr $CYLINDERS \* $BLKSPERCYL - 1` bs=512 2>/dev/null 94 95# Set up mtools 96echo "drive c: file=\"$OUTIMG\" partition=1" > mtoolsrc 97export MTOOLSRC=mtoolsrc 98 99# Get mbr.bin and blow up/cut down to 512 bytes (required by mtools) 100cat "$MBR" /dev/zero 2>/dev/null | head -c 512 > mbr.bin 101 102# Create filesystem 103which mpartition >/dev/null 2>&1 104if [ $? -ne 0 ]; then 105 echo "mpartition not found. Is mtools installed?" >&2 106 exit 1 107fi 108mpartition -I -B mbr.bin c: 109mpartition -c -t $CYLINDERS -h $HEADS -s $SECTORS c: 110mpartition -a c: 111mformat c: 112syslinux --offset `expr $SECTORS \* 512` $OUTIMG 113 114# Write syslinux config file 115UIMGS_CFG="" 116for UIMG in $UIMGS 117do 118 UIMGS_CFG="$UIMGS_CFG --- `basename $UIMG`" 119done 120 121cat > syslinux.cfg <<EOF 122serial 0 115200 123default mylabel 124 125label mylabel 126 kernel mboot.c32 127 append `basename $KERNEL` $CMDLINE $UIMGS_CFG 128EOF 129 130# Install kernel and apps to the image 131for file in $KERNEL $UIMGS $MODULES syslinux.cfg 132do 133 mcopy "$file" c: || { 134 echo "Error: mcopy $file failed!" >&2 135 exit 1 136 } 137done 138 139# And we're done 140echo "Image '$OUTIMG' successfully created" 141