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