xref: /freebsd/tools/tools/nanobsd/legacy.sh (revision 9768746b)
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# $FreeBSD$
29#
30
31# Media geometry, only relevant if bios doesn't understand LBA.
32[ -n "$NANO_SECTS" ] || NANO_SECTS=63
33[ -n "$NANO_HEADS" ] || NANO_HEADS=16
34
35# Functions and variable definitions used by the legacy nanobsd
36# image building system.
37
38calculate_partitioning ( ) (
39	echo $NANO_MEDIASIZE $NANO_IMAGES \
40		$NANO_SECTS $NANO_HEADS \
41		$NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE |
42	awk '
43	{
44		# size of cylinder in sectors
45		cs = $3 * $4
46
47		# number of full cylinders on media
48		cyl = int ($1 / cs)
49
50		if ($7 > 0) {
51			# size of data partition in full cylinders
52			dsl = int (($7 + cs - 1) / cs)
53		} else {
54			dsl = 0;
55		}
56
57		# size of config partition in full cylinders
58		csl = int (($6 + cs - 1) / cs)
59
60		# size of image partition(s) in full cylinders
61		if ($5 == 0) {
62			isl = int ((cyl - dsl - csl) / $2)
63		} else {
64			isl = int (($5 + cs - 1) / cs)
65		}
66
67		# First image partition start at second track
68		print $3, isl * cs - $3
69		c = isl * cs;
70
71		# Second image partition (if any) also starts offset one
72		# track to keep them identical.
73		if ($2 > 1) {
74			print $3 + c, isl * cs - $3
75			c += isl * cs;
76		}
77
78		# Config partition starts at cylinder boundary.
79		print c, csl * cs
80		c += csl * cs
81
82		# Data partition (if any) starts at cylinder boundary.
83		if ($7 > 0) {
84			print c, dsl * cs
85		} else if ($7 < 0 && $1 > c) {
86			print c, $1 - c
87		} else if ($1 < c) {
88			print "Disk space overcommitted by", \
89			    c - $1, "sectors" > "/dev/stderr"
90			exit 2
91		}
92
93	}
94	' > ${NANO_LOG}/_.partitioning
95)
96
97create_code_slice ( ) (
98	pprint 2 "build code slice"
99	pprint 3 "log: ${NANO_OBJ}/_.cs"
100
101	(
102	IMG=${NANO_DISKIMGDIR}/_.disk.image
103	MNT=${NANO_OBJ}/_.mnt
104	mkdir -p ${MNT}
105	CODE_SIZE=`head -n 1 ${NANO_LOG}/_.partitioning | awk '{ print $2 }'`
106
107	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
108		MD=`mdconfig -a -t swap -s ${CODE_SIZE} -x ${NANO_SECTS} \
109			-y ${NANO_HEADS}`
110	else
111		echo "Creating md backing file..."
112		rm -f ${IMG}
113		dd if=/dev/zero of=${IMG} seek=${CODE_SIZE} count=0
114		MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \
115			-y ${NANO_HEADS}`
116	fi
117
118	trap "echo 'Running exit trap code' ; df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT
119
120	bsdlabel -w ${MD}
121	if [ -f ${NANO_WORLDDIR}/boot/boot ]; then
122	    echo "Making bootable partition"
123	    gpart bootcode -b ${NANO_WORLDDIR}/boot/boot ${MD}
124	else
125	    echo "Partition will not be bootable"
126	fi
127	bsdlabel ${MD}
128
129	# Create first image
130	populate_slice /dev/${MD}${NANO_PARTITION_ROOT} ${NANO_WORLDDIR} ${MNT} "${NANO_ROOT}"
131	mount /dev/${MD}a ${MNT}
132	echo "Generating mtree..."
133	( cd ${MNT} && mtree -c ) > ${NANO_OBJ}/_.mtree
134	( cd ${MNT} && du -k ) > ${NANO_OBJ}/_.du
135	nano_umount ${MNT}
136
137	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
138		echo "Writing out _.disk.image..."
139		dd conv=sparse if=/dev/${MD} of=${NANO_DISKIMGDIR}/_.disk.image bs=64k
140	fi
141	mdconfig -d -u $MD
142
143	trap - 1 2 15 EXIT
144
145	) > ${NANO_OBJ}/_.cs 2>&1
146)
147
148
149create_diskimage ( ) (
150	pprint 2 "build diskimage"
151	pprint 3 "log: ${NANO_OBJ}/_.di"
152
153	(
154
155	IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
156	MNT=${NANO_OBJ}/_.mnt
157	mkdir -p ${MNT}
158
159	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
160		MD=`mdconfig -a -t swap -s ${NANO_MEDIASIZE} -x ${NANO_SECTS} \
161			-y ${NANO_HEADS}`
162	else
163		echo "Creating md backing file..."
164		rm -f ${IMG}
165		dd if=/dev/zero of=${IMG} seek=${NANO_MEDIASIZE} count=0
166		MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \
167			-y ${NANO_HEADS}`
168	fi
169
170	awk '
171	BEGIN {
172		# Create MBR partition table
173		print "gpart create -s mbr $1"
174	}
175	{
176		# Make partition
177		print "gpart add -t freebsd -b ", $1, " -s ", $2, " $1"
178	}
179	END {
180		# Force slice 1 to be marked active. This is necessary
181		# for booting the image from a USB device to work.
182		print "gpart set -a active -i 1 $1"
183	}
184	' ${NANO_LOG}/_.partitioning > ${NANO_OBJ}/_.gpart
185
186	trap "echo 'Running exit trap code' ; df -i ${MNT} ; nano_umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT
187
188	sh ${NANO_OBJ}/_.gpart ${MD}
189	gpart show ${MD}
190	# XXX: params
191	# XXX: pick up cached boot* files, they may not be in image anymore.
192	if [ -f ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ]; then
193		gpart bootcode -b ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ${NANO_BOOTFLAGS} ${MD}
194	fi
195
196	echo "Writing code image..."
197	dd conv=sparse if=${NANO_DISKIMGDIR}/_.disk.image of=/dev/${MD}${NANO_SLICE_ROOT} bs=64k
198
199	if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then
200		# Duplicate to second image (if present)
201		echo "Duplicating to second image..."
202		dd conv=sparse if=/dev/${MD}${NANO_SLICE_ROOT} of=/dev/${MD}${NANO_SLICE_ALTROOT} bs=64k
203		mount /dev/${MD}${NANO_ALTROOT} ${MNT}
204		for f in ${MNT}/etc/fstab ${MNT}/conf/base/etc/fstab
205		do
206			sed -i "" "s=${NANO_DRIVE}${NANO_SLICE_ROOT}=${NANO_DRIVE}${NANO_SLICE_ALTROOT}=g" $f
207		done
208		nano_umount ${MNT}
209		# Override the label from the first partition so we
210		# don't confuse glabel with duplicates.
211		if [ -n "${NANO_LABEL}" ]; then
212			tunefs -L ${NANO_LABEL}"${NANO_ALTROOT}" /dev/${MD}${NANO_ALTROOT}
213		fi
214	fi
215
216	# Create Config slice
217	populate_cfg_slice /dev/${MD}${NANO_SLICE_CFG} "${NANO_CFGDIR}" ${MNT} "${NANO_SLICE_CFG}"
218
219	# Create Data slice, if any.
220	if [ -n "$NANO_SLICE_DATA" -a "$NANO_SLICE_CFG" = "$NANO_SLICE_DATA" -a \
221	   "$NANO_DATASIZE" -ne 0 ]; then
222		pprint 2 "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
223		exit 2
224	fi
225	if [ $NANO_DATASIZE -ne 0 -a -n "$NANO_SLICE_DATA" ] ; then
226		populate_data_slice /dev/${MD}${NANO_SLICE_DATA} "${NANO_DATADIR}" ${MNT} "${NANO_SLICE_DATA}"
227	fi
228
229	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
230		if [ ${NANO_IMAGE_MBRONLY} ]; then
231			echo "Writing out _.disk.mbr..."
232			dd if=/dev/${MD} of=${NANO_DISKIMGDIR}/_.disk.mbr bs=512 count=1
233		else
234			echo "Writing out ${NANO_IMGNAME}..."
235			dd if=/dev/${MD} of=${IMG} bs=64k
236		fi
237
238		echo "Writing out ${NANO_IMGNAME}..."
239		dd conv=sparse if=/dev/${MD} of=${IMG} bs=64k
240	fi
241
242	mdconfig -d -u $MD
243
244	trap - 1 2 15 EXIT
245
246	) > ${NANO_LOG}/_.di 2>&1
247)
248