xref: /netbsd-src/distrib/common/buildfloppies.sh (revision cd22f25e6f6d1cc1f197fe8c5468a80f51d1c4e1)
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