1#!/bin/sh 2# 3# $NetBSD: buildfloppies.sh,v 1.13 2008/04/30 13:10:48 martin Exp $ 4# 5# Copyright (c) 2002-2003 The NetBSD Foundation, Inc. 6# All rights reserved. 7# 8# This code is derived from software contributed to The NetBSD Foundation 9# by Luke Mewburn of Wasabi Systems. 10# 11# Redistribution and use in source and binary forms, with or without 12# modification, are permitted provided that the following conditions 13# are met: 14# 1. Redistributions of source code must retain the above copyright 15# notice, this list of conditions and the following disclaimer. 16# 2. Redistributions in binary form must reproduce the above copyright 17# notice, this list of conditions and the following disclaimer in the 18# documentation and/or other materials provided with the distribution. 19# 20# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30# POSSIBILITY OF SUCH DAMAGE. 31# 32 33# set defaults 34# 35: ${PAX=pax} 36prog=${0##*/} 37 38 39usage() 40{ 41 cat 1>&2 << _USAGE_ 42Usage: ${prog} [-i instboot] [-m max] [-p] [-s suffix] base size file [...] 43 -i instboot run instboot to install a bootstrap on @IMAGE@ 44 -m max maximum number of floppies to build 45 -p pad last floppy to floppy size 46 -s suffix suffix for floppies 47 base basename of generated floppies 48 size size of a floppy in 512 byte blocks 49 file [...] file(s) to build 50_USAGE_ 51 exit 1 52} 53 54plural() 55{ 56 [ $1 -ne 1 ] && echo "s" 57} 58 59roundup() 60{ 61 echo $(( ( $1 + $2 - 1 ) / ( $2 ) )) 62} 63 64 65# parse and check arguments 66# 67 68while getopts i:m:ps: opt; do 69 case ${opt} in 70 i) 71 instboot=${OPTARG} ;; 72 m) 73 maxdisks=${OPTARG} ;; 74 p) 75 pad=1 ;; 76 s) 77 suffix=${OPTARG} ;; 78 \?|*) 79 usage 80 ;; 81 esac 82done 83 84shift $(( ${OPTIND} - 1 )) 85[ $# -lt 3 ] && usage 86floppybase=$1 87floppysize=$2 88shift 2 89files=$* 90 91# setup temp file, remove existing images 92# 93floppy=floppy.$$.tar 94trap "rm -f ${floppy}" 0 1 2 3 # EXIT HUP INT QUIT 95rm -f ${floppybase}?${suffix} 96 97# create tar file 98# 99dd if=/dev/zero of=${floppy} bs=8k count=1 2>/dev/null 100${PAX} -O -w -b8k ${files} >> ${floppy} || exit 1 101 # XXX: use pax metafile and set perms? 102if [ -n "$instboot" ]; then 103 instboot=$( echo $instboot | sed -e s/@IMAGE@/${floppy}/ ) 104 echo "Running instboot: ${instboot}" 105 eval ${instboot} || exit 1 106fi 107 108# check size against available number of disks 109# 110set -- $(ls -ln $floppy) 111bytes=$5 112blocks=$(roundup ${bytes} 512) 113 # when calculating numdisks, take into account: 114 # a) the image already has an 8K tar header prepended 115 # b) each floppy needs an 8K tar volume header 116numdisks=$(roundup ${blocks}-16 ${floppysize}-16) 117if [ -z "${maxdisks}" ]; then 118 maxdisks=${numdisks} 119fi 120 121# Try to accurately summarise free space 122# 123msg= 124# First floppy has 8k boot code, the rest an 8k 'multivolume header' 125# Each file has a 512 byte header and is rounded to a multiple of 512 126# The archive ends with two 512 byte blocks of zeros 127# The output file is then rounded up to a multiple of 8k 128free_space=$(($maxdisks * ($floppysize - 16) * 512 - 512 * 2)) 129for file in $files; do 130 set -- $(ls -ln $file) 131 file_bytes=$5 132 pad_bytes=$(($(roundup $file_bytes 512) * 512 - $file_bytes)) 133 [ "$file_bytes" != 0 -o "$file" = "${file#USTAR.volsize.}" ] && 134 msg="$msg $file $pad_bytes," 135 free_space=$(($free_space - 512 - $file_bytes - $pad_bytes)) 136done 137echo "Free space in last tar block:$msg" 138 139if [ ${numdisks} -gt ${maxdisks} ]; then 140 # Add in the size of the last item (we really want the kernel) ... 141 excess=$(( 0 - $free_space + $pad_bytes)) 142 echo 1>&2 \ 143 "$prog: Image is ${excess} bytes ($(( ${excess} / 1024 )) KB)"\ 144 "too big to fit on ${maxdisks} disk"$(plural ${maxdisks}) 145 exit 1 146fi 147 148padto=$(( ${floppysize} * ${maxdisks} )) 149if [ -n "${pad}" ]; then 150 echo \ 151 "Writing $(( ${padto} * 512 )) bytes ($(( ${padto} / 2 )) KB)" \ 152 "on ${numdisks} disk"$(plural ${numdisks})"," \ 153 "padded by ${free_space} bytes" \ 154 "($(( ${free_space} / 1024 )) KB)" 155else 156 echo "Writing ${bytes} bytes ($(( ${blocks} / 2 )) KB)"\ 157 "on ${numdisks} disk"$(plural ${numdisks})"," \ 158 "free space ${free_space} bytes" \ 159 "($(( ${free_space} / 1024 )) KB)" 160fi 161 162# write disks 163# 164curdisk=1 165image= 166seek=0 167skip=0 168floppysize8k=$(( ${floppysize} / 16 )) 169while [ ${curdisk} -le ${numdisks} ]; do 170 image="${floppybase}${curdisk}${suffix}" 171 echo "Creating disk ${curdisk} to ${image}" 172 if [ ${curdisk} -eq 1 ]; then 173 : > ${image} 174 else 175 echo USTARFS ${curdisk} > ${image} 176 fi 177 count=$(( ${floppysize8k} - ${seek} )) 178 dd bs=8k conv=sync seek=${seek} skip=${skip} count=${count} \ 179 if=${floppy} of=${image} 2>/dev/null 180 181 curdisk=$(( ${curdisk} + 1 )) 182 skip=$(( $skip + $count )) 183 seek=1 184done 185 186# pad last disk if necessary 187# 188if [ -n "${pad}" ]; then 189 dd if=$image of=$image conv=notrunc conv=sync bs=${floppysize}b count=1 190fi 191 192 193# final status 194# 195echo "Final result:" 196ls -l ${floppybase}?${suffix} 197 198exit 0 199