Expand PMF_FN_* macros.
[netbsd-mini2440.git] / distrib / common / buildfloppies.sh
blob4f118263a7c68c7ad159b16c7accccc36abb247b
1 #!/bin/sh
3 # $NetBSD: buildfloppies.sh,v 1.16 2008/11/11 19:55:21 dbj Exp $
5 # Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
6 # All rights reserved.
8 # This code is derived from software contributed to The NetBSD Foundation
9 # by Luke Mewburn of Wasabi Systems.
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.
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.
33 # set defaults
35 : ${PAX=pax}
36 prog=${0##*/}
37 etcdir=/etc
40 usage()
42 cat 1>&2 << _USAGE_
43 Usage: ${prog} [options] base size file [...]
44 -i instboot eval instboot as a shell command to install a
45 bootstrap. @IMAGE@ is replaced with with the
46 file name of the floppy image.
47 -m max maximum number of floppies to build
48 -N etcdir directory in which to find passwd and group files.
49 -p pad last floppy to floppy size
50 -s suffix suffix for floppies
51 base basename of generated floppies
52 size size of a floppy in 512 byte blocks
53 file [...] file(s) to store in the floppies
54 _USAGE_
55 exit 1
58 plural()
60 [ $1 -ne 1 ] && echo "s"
63 roundup()
65 echo $(( ( $1 + $2 - 1 ) / ( $2 ) ))
69 # parse and check arguments
72 while getopts i:m:N:ps: opt; do
73 case ${opt} in
75 instboot=${OPTARG} ;;
77 maxdisks=${OPTARG} ;;
79 etcdir=${OPTARG} ;;
81 pad=1 ;;
83 suffix=${OPTARG} ;;
84 \?|*)
85 usage
87 esac
88 done
90 shift $(( ${OPTIND} - 1 ))
91 [ $# -lt 3 ] && usage
92 floppybase=$1
93 floppysize=$2
94 shift 2
95 files=$*
97 # setup temp file, remove existing images
99 floppy=floppy.$$.tar
100 trap "rm -f ${floppy}" 0 1 2 3 # EXIT HUP INT QUIT
101 rm -f ${floppybase}?${suffix} # XXX breaks if maxdisks > 9
103 # create tar file
105 dd if=/dev/zero of=${floppy} bs=8k count=1 2>/dev/null
107 echo ". type=dir optional"
108 for f in ${files}; do
109 echo "./$f type=file uname=root gname=wheel mode=0444"
110 done
111 ) | \
112 ${PAX} -O -w -b8k -M -N "${etcdir}" -s,^./,, >> ${floppy} || exit 1
114 # install bootstrap before the image is split into multiple disks
116 if [ -n "$instboot" ]; then
117 instboot=$( echo $instboot | sed -e s/@IMAGE@/${floppy}/ )
118 echo "Running instboot: ${instboot}"
119 eval ${instboot} || exit 1
122 # check size against available number of disks
124 set -- $(ls -ln $floppy)
125 bytes=$5
126 blocks=$(roundup ${bytes} 512)
127 # when calculating numdisks, take into account:
128 # a) the image already has an 8K tar header prepended
129 # b) each floppy needs an 8K tar volume header
130 numdisks=$(roundup ${blocks}-16 ${floppysize}-16)
131 if [ -z "${maxdisks}" ]; then
132 maxdisks=${numdisks}
135 # Try to accurately summarise free space
137 msg=
138 # First floppy has 8k boot code, the rest an 8k 'multivolume header'.
139 # Each file has a 512 byte header and is rounded to a multiple of 512.
140 # The archive ends with two 512 byte blocks of zeros.
141 # The output file is then rounded up to a multiple of 8k.
142 # floppysize is in units of 512-byte blocks; free_space is in bytes.
143 free_space=$(($maxdisks * ($floppysize - 16) * 512 - 512 * 2))
144 for file in $files; do
145 set -- $(ls -ln $file)
146 file_bytes=$5
147 pad_bytes=$(($(roundup $file_bytes 512) * 512 - $file_bytes))
148 [ "$file_bytes" != 0 -o "$file" = "${file#USTAR.volsize.}" ] &&
149 msg="$msg $file $pad_bytes,"
150 free_space=$(($free_space - 512 - $file_bytes - $pad_bytes))
151 done
152 echo "Free space in last tar block:$msg"
154 if [ ${numdisks} -gt ${maxdisks} ]; then
155 # Add in the size of the last item (we really want the kernel) ...
156 excess=$(( 0 - $free_space + $pad_bytes))
157 echo 1>&2 \
158 "$prog: Image is ${excess} bytes ($(( ${excess} / 1024 )) KB)"\
159 "too big to fit on ${maxdisks} disk"$(plural ${maxdisks})
160 exit 1
163 padto=$(( ${floppysize} * ${maxdisks} ))
164 if [ -n "${pad}" ]; then
165 echo \
166 "Writing $(( ${padto} * 512 )) bytes ($(( ${padto} / 2 )) KB)" \
167 "on ${numdisks} disk"$(plural ${numdisks})"," \
168 "padded by ${free_space} bytes" \
169 "($(( ${free_space} / 1024 )) KB)"
170 else
171 echo "Writing ${bytes} bytes ($(( ${blocks} / 2 )) KB)"\
172 "on ${numdisks} disk"$(plural ${numdisks})"," \
173 "free space ${free_space} bytes" \
174 "($(( ${free_space} / 1024 )) KB)"
177 # write disks
179 curdisk=1
180 image=
181 seek=0
182 skip=0
183 floppysize8k=$(( ${floppysize} / 16 ))
184 while [ ${curdisk} -le ${numdisks} ]; do
185 image="${floppybase}${curdisk}${suffix}"
186 echo "Creating disk ${curdisk} to ${image}"
187 if [ ${curdisk} -eq 1 ]; then
188 : > ${image}
189 else
190 echo USTARFS ${curdisk} > ${image}
192 count=$(( ${floppysize8k} - ${seek} ))
193 dd bs=8k conv=sync seek=${seek} skip=${skip} count=${count} \
194 if=${floppy} of=${image} 2>/dev/null
196 curdisk=$(( ${curdisk} + 1 ))
197 skip=$(( $skip + $count ))
198 seek=1
199 done
201 # pad last disk if necessary
203 if [ -n "${pad}" ]; then
204 dd if=$image of=$image conv=notrunc conv=sync bs=${floppysize}b count=1
208 # final status
210 echo "Final result:"
211 ls -l ${floppybase}?${suffix} # XXX breaks if maxdisks > 9
213 exit 0