xref: /freebsd/tools/tools/nanobsd/legacy.sh (revision 61e21613)
1#!/bin/sh
2#
3# Copyright (c) 2005 Poul-Henning Kamp All rights reserved.
4# Copyright (c) 2016 M. Warner Losh <imp@FreeBSD.org>
5#
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28#
29
30# Media geometry, only relevant if bios doesn't understand LBA.
31[ -n "$NANO_SECTS" ] || NANO_SECTS=63
32[ -n "$NANO_HEADS" ] || NANO_HEADS=16
33
34# Functions and variable definitions used by the legacy nanobsd
35# image building system.
36
37calculate_partitioning ( ) (
38	echo $NANO_MEDIASIZE $NANO_IMAGES \
39		$NANO_SECTS $NANO_HEADS \
40		$NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE |
41	awk '
42	{
43		# size of cylinder in sectors
44		cs = $3 * $4
45
46		# number of full cylinders on media
47		cyl = int ($1 / cs)
48
49		if ($7 > 0) {
50			# size of data partition in full cylinders
51			dsl = int (($7 + cs - 1) / cs)
52		} else {
53			dsl = 0;
54		}
55
56		# size of config partition in full cylinders
57		csl = int (($6 + cs - 1) / cs)
58
59		# size of image partition(s) in full cylinders
60		if ($5 == 0) {
61			isl = int ((cyl - dsl - csl) / $2)
62		} else {
63			isl = int (($5 + cs - 1) / cs)
64		}
65
66		# First image partition start at second track
67		print $3, isl * cs - $3
68		c = isl * cs;
69
70		# Second image partition (if any) also starts offset one
71		# track to keep them identical.
72		if ($2 > 1) {
73			print $3 + c, isl * cs - $3
74			c += isl * cs;
75		}
76
77		# Config partition starts at cylinder boundary.
78		print c, csl * cs
79		c += csl * cs
80
81		# Data partition (if any) starts at cylinder boundary.
82		if ($7 > 0) {
83			print c, dsl * cs
84		} else if ($7 < 0 && $1 > c) {
85			print c, $1 - c
86		} else if ($1 < c) {
87			print "Disk space overcommitted by", \
88			    c - $1, "sectors" > "/dev/stderr"
89			exit 2
90		}
91
92	}
93	' > ${NANO_LOG}/_.partitioning
94)
95
96create_code_slice ( ) (
97	pprint 2 "build code slice"
98	pprint 3 "log: ${NANO_OBJ}/_.cs"
99
100	(
101	IMG=${NANO_DISKIMGDIR}/_.disk.image
102	MNT=${NANO_OBJ}/_.mnt
103	mkdir -p ${MNT}
104	CODE_SIZE=`head -n 1 ${NANO_LOG}/_.partitioning | awk '{ print $2 }'`
105
106	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
107		MD=`mdconfig -a -t swap -s ${CODE_SIZE} -x ${NANO_SECTS} \
108			-y ${NANO_HEADS}`
109	else
110		echo "Creating md backing file..."
111		rm -f ${IMG}
112		dd if=/dev/zero of=${IMG} seek=${CODE_SIZE} count=0
113		MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \
114			-y ${NANO_HEADS}`
115	fi
116
117	trap "echo 'Running exit trap code' ; df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT
118
119	bsdlabel -w ${MD}
120	if [ -f ${NANO_WORLDDIR}/boot/boot ]; then
121	    echo "Making bootable partition"
122	    gpart bootcode -b ${NANO_WORLDDIR}/boot/boot ${MD}
123	else
124	    echo "Partition will not be bootable"
125	fi
126	bsdlabel ${MD}
127
128	# Create first image
129	populate_slice /dev/${MD}${NANO_PARTITION_ROOT} ${NANO_WORLDDIR} ${MNT} "${NANO_ROOT}"
130	mount /dev/${MD}a ${MNT}
131	echo "Generating mtree..."
132	( cd ${MNT} && mtree -c ) > ${NANO_OBJ}/_.mtree
133	( cd ${MNT} && du -k ) > ${NANO_OBJ}/_.du
134	nano_umount ${MNT}
135
136	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
137		echo "Writing out _.disk.image..."
138		dd conv=sparse if=/dev/${MD} of=${NANO_DISKIMGDIR}/_.disk.image bs=64k
139	fi
140	mdconfig -d -u $MD
141
142	trap - 1 2 15 EXIT
143
144	) > ${NANO_OBJ}/_.cs 2>&1
145)
146
147
148create_diskimage ( ) (
149	pprint 2 "build diskimage"
150	pprint 3 "log: ${NANO_OBJ}/_.di"
151
152	(
153
154	IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
155	MNT=${NANO_OBJ}/_.mnt
156	mkdir -p ${MNT}
157
158	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
159		MD=`mdconfig -a -t swap -s ${NANO_MEDIASIZE} -x ${NANO_SECTS} \
160			-y ${NANO_HEADS}`
161	else
162		echo "Creating md backing file..."
163		rm -f ${IMG}
164		dd if=/dev/zero of=${IMG} seek=${NANO_MEDIASIZE} count=0
165		MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \
166			-y ${NANO_HEADS}`
167	fi
168
169	awk '
170	BEGIN {
171		# Create MBR partition table
172		print "gpart create -s mbr $1"
173	}
174	{
175		# Make partition
176		print "gpart add -t freebsd -b ", $1, " -s ", $2, " $1"
177	}
178	END {
179		# Force slice 1 to be marked active. This is necessary
180		# for booting the image from a USB device to work.
181		print "gpart set -a active -i 1 $1"
182	}
183	' ${NANO_LOG}/_.partitioning > ${NANO_OBJ}/_.gpart
184
185	trap "echo 'Running exit trap code' ; df -i ${MNT} ; nano_umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT
186
187	sh ${NANO_OBJ}/_.gpart ${MD}
188	gpart show ${MD}
189	# XXX: params
190	# XXX: pick up cached boot* files, they may not be in image anymore.
191	if [ -f ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ]; then
192		gpart bootcode -b ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ${NANO_BOOTFLAGS} ${MD}
193	fi
194
195	echo "Writing code image..."
196	dd conv=sparse if=${NANO_DISKIMGDIR}/_.disk.image of=/dev/${MD}${NANO_SLICE_ROOT} bs=64k
197
198	if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then
199		# Duplicate to second image (if present)
200		echo "Duplicating to second image..."
201		dd conv=sparse if=/dev/${MD}${NANO_SLICE_ROOT} of=/dev/${MD}${NANO_SLICE_ALTROOT} bs=64k
202		mount /dev/${MD}${NANO_ALTROOT} ${MNT}
203		for f in ${MNT}/etc/fstab ${MNT}/conf/base/etc/fstab
204		do
205			sed -i "" "s=${NANO_DRIVE}${NANO_SLICE_ROOT}=${NANO_DRIVE}${NANO_SLICE_ALTROOT}=g" $f
206		done
207		nano_umount ${MNT}
208		# Override the label from the first partition so we
209		# don't confuse glabel with duplicates.
210		if [ -n "${NANO_LABEL}" ]; then
211			tunefs -L ${NANO_LABEL}"${NANO_ALTROOT}" /dev/${MD}${NANO_ALTROOT}
212		fi
213	fi
214
215	# Create Config slice
216	populate_cfg_slice /dev/${MD}${NANO_SLICE_CFG} "${NANO_CFGDIR}" ${MNT} "${NANO_SLICE_CFG}"
217
218	# Create Data slice, if any.
219	if [ -n "$NANO_SLICE_DATA" -a "$NANO_SLICE_CFG" = "$NANO_SLICE_DATA" -a \
220	   "$NANO_DATASIZE" -ne 0 ]; then
221		pprint 2 "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
222		exit 2
223	fi
224	if [ $NANO_DATASIZE -ne 0 -a -n "$NANO_SLICE_DATA" ] ; then
225		populate_data_slice /dev/${MD}${NANO_SLICE_DATA} "${NANO_DATADIR}" ${MNT} "${NANO_SLICE_DATA}"
226	fi
227
228	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
229		if [ ${NANO_IMAGE_MBRONLY} ]; then
230			echo "Writing out _.disk.mbr..."
231			dd if=/dev/${MD} of=${NANO_DISKIMGDIR}/_.disk.mbr bs=512 count=1
232		else
233			echo "Writing out ${NANO_IMGNAME}..."
234			dd if=/dev/${MD} of=${IMG} bs=64k
235		fi
236
237		echo "Writing out ${NANO_IMGNAME}..."
238		dd conv=sparse if=/dev/${MD} of=${IMG} bs=64k
239	fi
240
241	mdconfig -d -u $MD
242
243	trap - 1 2 15 EXIT
244
245	) > ${NANO_LOG}/_.di 2>&1
246)
247