buildfloppies.sh revision 1.12.22.1 1 1.1 lukem #!/bin/sh
2 1.1 lukem #
3 1.12.22.1 yamt # $NetBSD: buildfloppies.sh,v 1.12.22.1 2008/05/18 12:29:34 yamt 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.1 lukem
38 1.1 lukem
39 1.1 lukem usage()
40 1.1 lukem {
41 1.1 lukem cat 1>&2 << _USAGE_
42 1.3 lukem Usage: ${prog} [-i instboot] [-m max] [-p] [-s suffix] base size file [...]
43 1.1 lukem -i instboot run instboot to install a bootstrap on @IMAGE@
44 1.1 lukem -m max maximum number of floppies to build
45 1.1 lukem -p pad last floppy to floppy size
46 1.3 lukem -s suffix suffix for floppies
47 1.1 lukem base basename of generated floppies
48 1.1 lukem size size of a floppy in 512 byte blocks
49 1.1 lukem file [...] file(s) to build
50 1.1 lukem _USAGE_
51 1.1 lukem exit 1
52 1.1 lukem }
53 1.1 lukem
54 1.1 lukem plural()
55 1.1 lukem {
56 1.1 lukem [ $1 -ne 1 ] && echo "s"
57 1.1 lukem }
58 1.1 lukem
59 1.7 lukem roundup()
60 1.7 lukem {
61 1.7 lukem echo $(( ( $1 + $2 - 1 ) / ( $2 ) ))
62 1.7 lukem }
63 1.7 lukem
64 1.1 lukem
65 1.1 lukem # parse and check arguments
66 1.1 lukem #
67 1.1 lukem
68 1.3 lukem while getopts i:m:ps: opt; do
69 1.1 lukem case ${opt} in
70 1.1 lukem i)
71 1.1 lukem instboot=${OPTARG} ;;
72 1.1 lukem m)
73 1.1 lukem maxdisks=${OPTARG} ;;
74 1.1 lukem p)
75 1.1 lukem pad=1 ;;
76 1.3 lukem s)
77 1.3 lukem suffix=${OPTARG} ;;
78 1.1 lukem \?|*)
79 1.1 lukem usage
80 1.1 lukem ;;
81 1.1 lukem esac
82 1.1 lukem done
83 1.1 lukem
84 1.1 lukem shift $(( ${OPTIND} - 1 ))
85 1.1 lukem [ $# -lt 3 ] && usage
86 1.1 lukem floppybase=$1
87 1.1 lukem floppysize=$2
88 1.1 lukem shift 2
89 1.1 lukem files=$*
90 1.1 lukem
91 1.1 lukem # setup temp file, remove existing images
92 1.1 lukem #
93 1.1 lukem floppy=floppy.$$.tar
94 1.1 lukem trap "rm -f ${floppy}" 0 1 2 3 # EXIT HUP INT QUIT
95 1.3 lukem rm -f ${floppybase}?${suffix}
96 1.1 lukem
97 1.1 lukem # create tar file
98 1.1 lukem #
99 1.1 lukem dd if=/dev/zero of=${floppy} bs=8k count=1 2>/dev/null
100 1.10 dsl ${PAX} -O -w -b8k ${files} >> ${floppy} || exit 1
101 1.1 lukem # XXX: use pax metafile and set perms?
102 1.1 lukem if [ -n "$instboot" ]; then
103 1.1 lukem instboot=$( echo $instboot | sed -e s/@IMAGE@/${floppy}/ )
104 1.1 lukem echo "Running instboot: ${instboot}"
105 1.2 tv eval ${instboot} || exit 1
106 1.1 lukem fi
107 1.1 lukem
108 1.1 lukem # check size against available number of disks
109 1.1 lukem #
110 1.12 dsl set -- $(ls -ln $floppy)
111 1.12 dsl bytes=$5
112 1.7 lukem blocks=$(roundup ${bytes} 512)
113 1.7 lukem # when calculating numdisks, take into account:
114 1.7 lukem # a) the image already has an 8K tar header prepended
115 1.7 lukem # b) each floppy needs an 8K tar volume header
116 1.7 lukem numdisks=$(roundup ${blocks}-16 ${floppysize}-16)
117 1.1 lukem if [ -z "${maxdisks}" ]; then
118 1.1 lukem maxdisks=${numdisks}
119 1.1 lukem fi
120 1.1 lukem
121 1.12 dsl # Try to accurately summarise free space
122 1.12 dsl #
123 1.12 dsl msg=
124 1.12 dsl # First floppy has 8k boot code, the rest an 8k 'multivolume header'
125 1.12 dsl # Each file has a 512 byte header and is rounded to a multiple of 512
126 1.12 dsl # The archive ends with two 512 byte blocks of zeros
127 1.12 dsl # The output file is then rounded up to a multiple of 8k
128 1.12 dsl free_space=$(($maxdisks * ($floppysize - 16) * 512 - 512 * 2))
129 1.12 dsl for file in $files; do
130 1.12 dsl set -- $(ls -ln $file)
131 1.12 dsl file_bytes=$5
132 1.12 dsl pad_bytes=$(($(roundup $file_bytes 512) * 512 - $file_bytes))
133 1.12 dsl [ "$file_bytes" != 0 -o "$file" = "${file#USTAR.volsize.}" ] &&
134 1.12 dsl msg="$msg $file $pad_bytes,"
135 1.12 dsl free_space=$(($free_space - 512 - $file_bytes - $pad_bytes))
136 1.12 dsl done
137 1.12 dsl echo "Free space in last tar block:$msg"
138 1.12 dsl
139 1.1 lukem if [ ${numdisks} -gt ${maxdisks} ]; then
140 1.12 dsl # Add in the size of the last item (we really want the kernel) ...
141 1.12 dsl excess=$(( 0 - $free_space + $pad_bytes))
142 1.1 lukem echo 1>&2 \
143 1.1 lukem "$prog: Image is ${excess} bytes ($(( ${excess} / 1024 )) KB)"\
144 1.1 lukem "too big to fit on ${maxdisks} disk"$(plural ${maxdisks})
145 1.1 lukem exit 1
146 1.1 lukem fi
147 1.1 lukem
148 1.12 dsl padto=$(( ${floppysize} * ${maxdisks} ))
149 1.1 lukem if [ -n "${pad}" ]; then
150 1.1 lukem echo \
151 1.12 dsl "Writing $(( ${padto} * 512 )) bytes ($(( ${padto} / 2 )) KB)" \
152 1.1 lukem "on ${numdisks} disk"$(plural ${numdisks})"," \
153 1.12 dsl "padded by ${free_space} bytes" \
154 1.12 dsl "($(( ${free_space} / 1024 )) KB)"
155 1.1 lukem else
156 1.1 lukem echo "Writing ${bytes} bytes ($(( ${blocks} / 2 )) KB)"\
157 1.5 dsl "on ${numdisks} disk"$(plural ${numdisks})"," \
158 1.12 dsl "free space ${free_space} bytes" \
159 1.12 dsl "($(( ${free_space} / 1024 )) KB)"
160 1.1 lukem fi
161 1.1 lukem
162 1.1 lukem # write disks
163 1.1 lukem #
164 1.1 lukem curdisk=1
165 1.1 lukem image=
166 1.8 dsl seek=0
167 1.8 dsl skip=0
168 1.1 lukem floppysize8k=$(( ${floppysize} / 16 ))
169 1.1 lukem while [ ${curdisk} -le ${numdisks} ]; do
170 1.3 lukem image="${floppybase}${curdisk}${suffix}"
171 1.1 lukem echo "Creating disk ${curdisk} to ${image}"
172 1.1 lukem if [ ${curdisk} -eq 1 ]; then
173 1.1 lukem : > ${image}
174 1.1 lukem else
175 1.1 lukem echo USTARFS ${curdisk} > ${image}
176 1.1 lukem fi
177 1.1 lukem count=$(( ${floppysize8k} - ${seek} ))
178 1.1 lukem dd bs=8k conv=sync seek=${seek} skip=${skip} count=${count} \
179 1.1 lukem if=${floppy} of=${image} 2>/dev/null
180 1.1 lukem
181 1.1 lukem curdisk=$(( ${curdisk} + 1 ))
182 1.8 dsl skip=$(( $skip + $count ))
183 1.8 dsl seek=1
184 1.1 lukem done
185 1.1 lukem
186 1.1 lukem # pad last disk if necessary
187 1.1 lukem #
188 1.1 lukem if [ -n "${pad}" ]; then
189 1.8 dsl dd if=$image of=$image conv=notrunc conv=sync bs=${floppysize}b count=1
190 1.1 lukem fi
191 1.1 lukem
192 1.1 lukem
193 1.1 lukem # final status
194 1.1 lukem #
195 1.1 lukem echo "Final result:"
196 1.3 lukem ls -l ${floppybase}?${suffix}
197 1.1 lukem
198 1.1 lukem exit 0
199