nanobsd.sh revision 209210
1148422Sphk#!/bin/sh
2150366Sphk#
3148422Sphk# Copyright (c) 2005 Poul-Henning Kamp.
4150366Sphk# All rights reserved.
5148422Sphk#
6150366Sphk# Redistribution and use in source and binary forms, with or without
7150366Sphk# modification, are permitted provided that the following conditions
8150366Sphk# are met:
9150366Sphk# 1. Redistributions of source code must retain the above copyright
10150366Sphk#    notice, this list of conditions and the following disclaimer.
11150366Sphk# 2. Redistributions in binary form must reproduce the above copyright
12150366Sphk#    notice, this list of conditions and the following disclaimer in the
13150366Sphk#    documentation and/or other materials provided with the distribution.
14148422Sphk#
15150366Sphk# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16150366Sphk# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17150366Sphk# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18150366Sphk# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19150366Sphk# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20150366Sphk# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21150366Sphk# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22150366Sphk# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23150366Sphk# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24150366Sphk# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25150366Sphk# SUCH DAMAGE.
26150366Sphk#
27148422Sphk# $FreeBSD: head/tools/tools/nanobsd/nanobsd.sh 209210 2010-06-15 18:18:31Z imp $
28148422Sphk#
29148422Sphk
30148422Sphkset -e
31148422Sphk
32150366Sphk#######################################################################
33150366Sphk#
34150366Sphk# Setup default values for all controlling variables.
35150366Sphk# These values can be overridden from the config file(s)
36150366Sphk#
37150366Sphk#######################################################################
38150366Sphk
39148422Sphk# Name of this NanoBSD build.  (Used to construct workdir names)
40148422SphkNANO_NAME=full
41148422Sphk
42148422Sphk# Source tree directory
43148422SphkNANO_SRC=/usr/src
44148422Sphk
45150366Sphk# Where nanobsd additional files live under the source tree
46150366SphkNANO_TOOLS=tools/tools/nanobsd
47150366Sphk
48170607Sphk# Where cust_pkg() finds packages to install
49170607SphkNANO_PACKAGE_DIR=${NANO_SRC}/${NANO_TOOLS}/Pkg
50186181SphkNANO_PACKAGE_LIST="*"
51170607Sphk
52148422Sphk# Object tree directory
53148422Sphk# default is subdir of /usr/obj
54148648Sphk#NANO_OBJ=""
55148422Sphk
56175258Ssimon# The directory to put the final images
57175258Ssimon# default is ${NANO_OBJ}
58175258Ssimon#NANO_DISKIMGDIR=""
59175258Ssimon
60148422Sphk# Parallel Make
61148422SphkNANO_PMAKE="make -j 3"
62148422Sphk
63183284Sbms# The default name for any image we create.
64183284SbmsNANO_IMGNAME="_.disk.full"
65183284Sbms
66148422Sphk# Options to put in make.conf during buildworld only
67148422SphkCONF_BUILD=' '
68148422Sphk
69148422Sphk# Options to put in make.conf during installworld only
70148422SphkCONF_INSTALL=' '
71148422Sphk
72148422Sphk# Options to put in make.conf during both build- & installworld.
73148422SphkCONF_WORLD=' '
74148422Sphk
75148422Sphk# Kernel config file to use
76148422SphkNANO_KERNEL=GENERIC
77148422Sphk
78149073Sphk# Customize commands.
79149073SphkNANO_CUSTOMIZE=""
80149073Sphk
81181461Sphk# Late customize commands.
82181461SphkNANO_LATE_CUSTOMIZE=""
83181461Sphk
84148648Sphk# Newfs paramters to use
85148648SphkNANO_NEWFS="-b 4096 -f 512 -i 8192 -O1 -U"
86148648Sphk
87149082Sphk# The drive name of the media at runtime
88149082SphkNANO_DRIVE=ad0
89149082Sphk
90148648Sphk# Target media size in 512 bytes sectors
91183284SbmsNANO_MEDIASIZE=1200000
92148648Sphk
93148648Sphk# Number of code images on media (1 or 2)
94148422SphkNANO_IMAGES=2
95148648Sphk
96171986Sphk# 0 -> Leave second image all zeroes so it compresses better.
97171986Sphk# 1 -> Initialize second image with a copy of the first
98171986SphkNANO_INIT_IMG2=1
99171986Sphk
100149535Ssimon# Size of code file system in 512 bytes sectors
101149120Sphk# If zero, size will be as large as possible.
102149120SphkNANO_CODESIZE=0
103149120Sphk
104149120Sphk# Size of configuration file system in 512 bytes sectors
105149120Sphk# Cannot be zero.
106148422SphkNANO_CONFSIZE=2048
107148648Sphk
108148648Sphk# Size of data file system in 512 bytes sectors
109149120Sphk# If zero: no partition configured.
110149120Sphk# If negative: max size possible
111149120SphkNANO_DATASIZE=0
112148422Sphk
113154466Sphk# Size of the /etc ramdisk in 512 bytes sectors
114154466SphkNANO_RAM_ETCSIZE=10240
115154466Sphk
116154466Sphk# Size of the /tmp+/var ramdisk in 512 bytes sectors
117154466SphkNANO_RAM_TMPVARSIZE=10240
118154466Sphk
119148422Sphk# Media geometry, only relevant if bios doesn't understand LBA.
120170607SphkNANO_SECTS=63
121148422SphkNANO_HEADS=16
122148422Sphk
123168894Sadrian# boot0 flags/options and configuration
124168894SadrianNANO_BOOT0CFG="-o packet -s 1 -m 3"
125168894SadrianNANO_BOOTLOADER="boot/boot0sio"
126168894Sadrian
127175258Ssimon# Backing type of md(4) device
128175258Ssimon# Can be "file" or "swap"
129175258SsimonNANO_MD_BACKING="file"
130175258Ssimon
131183314Ssimon# Progress Print level
132183314SsimonPPLEVEL=3
133183314Ssimon
134148422Sphk#######################################################################
135206276Simp# Architecture to build.  Corresponds to TARGET_ARCH in a buildworld.
136206276Simp# Unfortunately, there's no way to set TARGET at this time, and it 
137206276Simp# conflates the two, so architectures where TARGET != TARGET_ARCH do
138206276Simp# not work.  This defaults to the arch of the current machine.
139148648Sphk
140205980SimpNANO_ARCH=`uname -p`
141148648Sphk
142148648Sphk#######################################################################
143150366Sphk#
144150366Sphk# The functions which do the real work.
145150366Sphk# Can be overridden from the config file(s)
146150366Sphk#
147150366Sphk#######################################################################
148148422Sphk
149149120Sphkclean_build ( ) (
150183314Ssimon	pprint 2 "Clean and create object directory (${MAKEOBJDIRPREFIX})"
151148422Sphk
152194431Sn_hibma	if ! rm -rf ${MAKEOBJDIRPREFIX} > /dev/null 2>&1 ; then
153148422Sphk		chflags -R noschg ${MAKEOBJDIRPREFIX}
154194431Sn_hibma		rm -r ${MAKEOBJDIRPREFIX}
155148422Sphk	fi
156148422Sphk	mkdir -p ${MAKEOBJDIRPREFIX}
157150343Sphk	printenv > ${MAKEOBJDIRPREFIX}/_.env
158148422Sphk)
159148422Sphk
160148422Sphkmake_conf_build ( ) (
161194431Sn_hibma	pprint 2 "Construct build make.conf ($NANO_MAKE_CONF_BUILD)"
162148422Sphk
163194431Sn_hibma	echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_BUILD}
164194431Sn_hibma	echo "${CONF_BUILD}" >> ${NANO_MAKE_CONF_BUILD}
165148422Sphk)
166148422Sphk
167148422Sphkbuild_world ( ) (
168183314Ssimon	pprint 2 "run buildworld"
169183314Ssimon	pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bw"
170148422Sphk
171148422Sphk	cd ${NANO_SRC}
172183284Sbms	env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} \
173194431Sn_hibma		__MAKE_CONF=${NANO_MAKE_CONF_BUILD} buildworld \
174148422Sphk		> ${MAKEOBJDIRPREFIX}/_.bw 2>&1
175148422Sphk)
176148422Sphk
177148422Sphkbuild_kernel ( ) (
178183314Ssimon	pprint 2 "build kernel ($NANO_KERNEL)"
179183314Ssimon	pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bk"
180148422Sphk
181148422Sphk	if [ -f ${NANO_KERNEL} ] ; then
182148422Sphk		cp ${NANO_KERNEL} ${NANO_SRC}/sys/${NANO_ARCH}/conf
183148422Sphk	fi
184148422Sphk
185181083Ssam	(cd ${NANO_SRC};
186181083Ssam	# unset these just in case to avoid compiler complaints
187181083Ssam	# when cross-building
188181083Ssam	unset TARGET_CPUTYPE
189181083Ssam	unset TARGET_BIG_ENDIAN
190183284Sbms	env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} buildkernel \
191194431Sn_hibma		__MAKE_CONF=${NANO_MAKE_CONF_BUILD} KERNCONF=`basename ${NANO_KERNEL}` \
192194440Sn_hibma		> ${MAKEOBJDIRPREFIX}/_.bk 2>&1
193181083Ssam	)
194148422Sphk)
195148422Sphk
196148422Sphkclean_world ( ) (
197194431Sn_hibma	if [ "${NANO_OBJ}" != "${MAKEOBJDIRPREFIX}" ]; then
198194431Sn_hibma		pprint 2 "Clean and create object directory (${NANO_OBJ})"
199194431Sn_hibma		if ! rm -rf ${NANO_OBJ} > /dev/null 2>&1 ; then
200194431Sn_hibma			chflags -R noschg ${NANO_OBJ}
201194431Sn_hibma			rm -r ${NANO_OBJ}
202194431Sn_hibma		fi
203194431Sn_hibma		mkdir -p ${NANO_OBJ} ${NANO_WORLDDIR}
204194431Sn_hibma		printenv > ${NANO_OBJ}/_.env
205148422Sphk	else
206194431Sn_hibma		pprint 2 "Clean and create world directory (${NANO_WORLDDIR})"
207194431Sn_hibma		if ! rm -rf ${NANO_WORLDDIR}/ > /dev/null 2>&1 ; then
208194431Sn_hibma			chflags -R noschg ${NANO_WORLDDIR}
209194431Sn_hibma			rm -rf ${NANO_WORLDDIR}
210194431Sn_hibma		fi
211194431Sn_hibma		mkdir -p ${NANO_WORLDDIR}
212148422Sphk	fi
213148422Sphk)
214148422Sphk
215148422Sphkmake_conf_install ( ) (
216194431Sn_hibma	pprint 2 "Construct install make.conf ($NANO_MAKE_CONF_INSTALL)"
217148422Sphk
218194431Sn_hibma	echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_INSTALL}
219194431Sn_hibma	echo "${CONF_INSTALL}" >> ${NANO_MAKE_CONF_INSTALL}
220148422Sphk)
221148422Sphk
222148422Sphkinstall_world ( ) (
223183314Ssimon	pprint 2 "installworld"
224194431Sn_hibma	pprint 3 "log: ${NANO_OBJ}/_.iw"
225148422Sphk
226148422Sphk	cd ${NANO_SRC}
227183284Sbms	env TARGET_ARCH=${NANO_ARCH} \
228194431Sn_hibma	${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} installworld \
229148422Sphk		DESTDIR=${NANO_WORLDDIR} \
230194431Sn_hibma		> ${NANO_OBJ}/_.iw 2>&1
231148422Sphk	chflags -R noschg ${NANO_WORLDDIR}
232148422Sphk)
233148422Sphk
234148422Sphkinstall_etc ( ) (
235148422Sphk
236183314Ssimon	pprint 2 "install /etc"
237194431Sn_hibma	pprint 3 "log: ${NANO_OBJ}/_.etc"
238148422Sphk
239160783Sthomas	cd ${NANO_SRC}
240183284Sbms	env TARGET_ARCH=${NANO_ARCH} \
241194431Sn_hibma	${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} distribution \
242148422Sphk		DESTDIR=${NANO_WORLDDIR} \
243194431Sn_hibma		> ${NANO_OBJ}/_.etc 2>&1
244209209Simp	# make.conf doesn't get created by default, but some ports need it
245209209Simp	# so they can spam it.
246209209Simp	cp /dev/null ${NANO_WORLDDIR}/etc/make.conf
247148422Sphk)
248148422Sphk
249148422Sphkinstall_kernel ( ) (
250183314Ssimon	pprint 2 "install kernel"
251194431Sn_hibma	pprint 3 "log: ${NANO_OBJ}/_.ik"
252148422Sphk
253148422Sphk	cd ${NANO_SRC}
254183284Sbms	env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} installkernel \
255148422Sphk		DESTDIR=${NANO_WORLDDIR} \
256194431Sn_hibma		__MAKE_CONF=${NANO_MAKE_CONF_INSTALL} KERNCONF=`basename ${NANO_KERNEL}` \
257194431Sn_hibma		> ${NANO_OBJ}/_.ik 2>&1
258148422Sphk)
259148422Sphk
260150366Sphkrun_customize() (
261150366Sphk
262183314Ssimon	pprint 2 "run customize scripts"
263150366Sphk	for c in $NANO_CUSTOMIZE
264150366Sphk	do
265183314Ssimon		pprint 2 "customize \"$c\""
266194431Sn_hibma		pprint 3 "log: ${NANO_OBJ}/_.cust.$c"
267183314Ssimon		pprint 4 "`type $c`"
268194431Sn_hibma		( $c ) > ${NANO_OBJ}/_.cust.$c 2>&1
269150366Sphk	done
270150366Sphk)
271150366Sphk
272181461Sphkrun_late_customize() (
273181461Sphk
274183314Ssimon	pprint 2 "run late customize scripts"
275181461Sphk	for c in $NANO_LATE_CUSTOMIZE
276181461Sphk	do
277183314Ssimon		pprint 2 "late customize \"$c\""
278194431Sn_hibma		pprint 3 "log: ${NANO_OBJ}/_.late_cust.$c"
279183314Ssimon		pprint 4 "`type $c`"
280194431Sn_hibma		( $c ) > ${NANO_OBJ}/_.late_cust.$c 2>&1
281181461Sphk	done
282181461Sphk)
283181461Sphk
284150366Sphksetup_nanobsd ( ) (
285183314Ssimon	pprint 2 "configure nanobsd setup"
286194431Sn_hibma	pprint 3 "log: ${NANO_OBJ}/_.dl"
287148422Sphk
288149103Sphk	(
289148422Sphk	cd ${NANO_WORLDDIR}
290148422Sphk
291170607Sphk	# Move /usr/local/etc to /etc/local so that the /cfg stuff
292170607Sphk	# can stomp on it.  Otherwise packages like ipsec-tools which
293170607Sphk	# have hardcoded paths under ${prefix}/etc are not tweakable.
294170607Sphk	if [ -d usr/local/etc ] ; then
295170607Sphk		(
296183727Sn_hibma		mkdir -p etc/local
297170607Sphk		cd usr/local/etc
298170607Sphk		find . -print | cpio -dumpl ../../../etc/local
299170607Sphk		cd ..
300170607Sphk		rm -rf etc
301170607Sphk		ln -s ../../etc/local etc
302170607Sphk		)
303170607Sphk	fi
304170607Sphk
305149082Sphk	for d in var etc
306149082Sphk	do
307149082Sphk		# link /$d under /conf
308149082Sphk		# we use hard links so we have them both places.
309149082Sphk		# the files in /$d will be hidden by the mount.
310149082Sphk		# XXX: configure /$d ramdisk size
311149082Sphk		mkdir -p conf/base/$d conf/default/$d
312149082Sphk		find $d -print | cpio -dumpl conf/base/
313149082Sphk	done
314148422Sphk
315154466Sphk	echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size
316154466Sphk	echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size
317154466Sphk
318148422Sphk	# pick up config files from the special partition
319149082Sphk	echo "mount -o ro /dev/${NANO_DRIVE}s3" > conf/default/etc/remount
320148422Sphk
321149082Sphk	# Put /tmp on the /var ramdisk (could be symlink already)
322149082Sphk	rmdir tmp || true
323149082Sphk	rm tmp || true
324148422Sphk	ln -s var/tmp tmp
325149082Sphk
326194431Sn_hibma	) > ${NANO_OBJ}/_.dl 2>&1
327148422Sphk)
328148422Sphk
329161341Ssimonsetup_nanobsd_etc ( ) (
330183314Ssimon	pprint 2 "configure nanobsd /etc"
331161341Ssimon
332161341Ssimon	(
333161341Ssimon	cd ${NANO_WORLDDIR}
334161341Ssimon
335161341Ssimon	# create diskless marker file
336161341Ssimon	touch etc/diskless
337161341Ssimon
338170324Sphk	# Make root filesystem R/O by default
339170324Sphk	echo "root_rw_mount=NO" >> etc/defaults/rc.conf
340170324Sphk
341161341Ssimon	# save config file for scripts
342161341Ssimon	echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
343161341Ssimon
344161341Ssimon	echo "/dev/${NANO_DRIVE}s1a / ufs ro 1 1" > etc/fstab
345161341Ssimon	echo "/dev/${NANO_DRIVE}s3 /cfg ufs rw,noauto 2 2" >> etc/fstab
346161341Ssimon	mkdir -p cfg
347161341Ssimon	)
348161341Ssimon)
349161341Ssimon
350149014Sphkprune_usr() (
351149014Sphk
352149014Sphk	# Remove all empty directories in /usr 
353149014Sphk	find ${NANO_WORLDDIR}/usr -type d -depth -print |
354149014Sphk		while read d
355149014Sphk		do
356149014Sphk			rmdir $d > /dev/null 2>&1 || true 
357149014Sphk		done
358149014Sphk)
359149014Sphk
360209210Simppopulate_slice ( ) (
361209210Simp	local dev dir mnt
362209210Simp	dev=$1
363209210Simp	dir=$2
364209210Simp	mnt=$3
365209210Simp	test -z $2 && dir=/var/empty
366209210Simp	test -d $d || dir=/var/empty
367209210Simp	echo "Creating ${dev} with ${dir} (mounting on ${mnt})"
368209210Simp	newfs ${NANO_NEWFS} ${dev}
369209210Simp	mount ${dev} ${mnt}
370209210Simp	cd ${dir}
371209210Simp	find . -print | grep -Ev '/(CVS|\.svn)' | cpio -dumpv ${mnt}
372209210Simp	df -i ${mnt}
373209210Simp	umount ${mnt}
374209210Simp)
375209210Simp
376209210Simppopulate_cfg_slice ( ) (
377209210Simp	populate_slice "$1" "$2" "$3"
378209210Simp)
379209210Simp
380209210Simppopulate_data_slice ( ) (
381209210Simp	populate_slice "$1" "$2" "$3"
382209210Simp)
383209210Simp
384148422Sphkcreate_i386_diskimage ( ) (
385183314Ssimon	pprint 2 "build diskimage"
386194431Sn_hibma	pprint 3 "log: ${NANO_OBJ}/_.di"
387148422Sphk
388149103Sphk	(
389149120Sphk	echo $NANO_MEDIASIZE $NANO_IMAGES \
390149120Sphk		$NANO_SECTS $NANO_HEADS \
391149120Sphk		$NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE |
392148422Sphk	awk '
393150717Sphk	{
394149120Sphk		printf "# %s\n", $0
395149120Sphk
396148422Sphk		# size of cylinder in sectors
397149120Sphk		cs = $3 * $4
398148422Sphk
399148422Sphk		# number of full cylinders on media
400148422Sphk		cyl = int ($1 / cs)
401148422Sphk
402149120Sphk		# output fdisk geometry spec, truncate cyls to 1023
403148422Sphk		if (cyl <= 1023)
404149120Sphk			print "g c" cyl " h" $4 " s" $3
405148422Sphk		else
406149120Sphk			print "g c" 1023 " h" $4 " s" $3
407148422Sphk
408149120Sphk		if ($7 > 0) { 
409149120Sphk			# size of data partition in full cylinders
410149120Sphk			dsl = int (($7 + cs - 1) / cs)
411149120Sphk		} else {
412149120Sphk			dsl = 0;
413149120Sphk		}
414148422Sphk
415148422Sphk		# size of config partition in full cylinders
416149120Sphk		csl = int (($6 + cs - 1) / cs)
417148422Sphk
418150717Sphk		if ($5 == 0) {
419149120Sphk			# size of image partition(s) in full cylinders
420149120Sphk			isl = int ((cyl - dsl - csl) / $2)
421149120Sphk		} else {
422149120Sphk			isl = int (($5 + cs - 1) / cs)
423149120Sphk		}
424148422Sphk
425148422Sphk		# First image partition start at second track
426149120Sphk		print "p 1 165 " $3, isl * cs - $3
427148422Sphk		c = isl * cs;
428148422Sphk
429148422Sphk		# Second image partition (if any) also starts offset one 
430148422Sphk		# track to keep them identical.
431148422Sphk		if ($2 > 1) {
432149120Sphk			print "p 2 165 " $3 + c, isl * cs - $3
433148422Sphk			c += isl * cs;
434148422Sphk		}
435148422Sphk
436148422Sphk		# Config partition starts at cylinder boundary.
437148422Sphk		print "p 3 165 " c, csl * cs
438148422Sphk		c += csl * cs
439148422Sphk
440148422Sphk		# Data partition (if any) starts at cylinder boundary.
441149120Sphk		if ($7 > 0) {
442148422Sphk			print "p 4 165 " c, dsl * cs
443174936Ssimon		} else if ($7 < 0 && $1 > c) {
444174936Ssimon			print "p 4 165 " c, $1 - c
445150717Sphk		} else if ($1 < c) {
446150717Sphk			print "Disk space overcommitted by", \
447150717Sphk			    c - $1, "sectors" > "/dev/stderr"
448150717Sphk			exit 2
449148422Sphk		}
450183279Sbms
451183279Sbms		# Force slice 1 to be marked active. This is necessary
452183279Sbms		# for booting the image from a USB device to work.
453183279Sbms		print "a 1"
454150717Sphk	}
455194431Sn_hibma	' > ${NANO_OBJ}/_.fdisk
456148422Sphk
457183284Sbms	IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
458194431Sn_hibma	MNT=${NANO_OBJ}/_.mnt
459148422Sphk	mkdir -p ${MNT}
460148422Sphk
461175258Ssimon	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
462175258Ssimon		MD=`mdconfig -a -t swap -s ${NANO_MEDIASIZE} -x ${NANO_SECTS} \
463175258Ssimon			-y ${NANO_HEADS}`
464175258Ssimon	else
465175258Ssimon		echo "Creating md backing file..."
466175258Ssimon		dd if=/dev/zero of=${IMG} bs=${NANO_SECTS}b \
467194437Sn_hibma			count=`expr ${NANO_MEDIASIZE} / ${NANO_SECTS}`
468175258Ssimon		MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \
469175258Ssimon			-y ${NANO_HEADS}`
470175258Ssimon	fi
471148422Sphk
472197542Ssimon	trap "echo 'Running exit trap code' ; df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT
473148422Sphk
474194431Sn_hibma	fdisk -i -f ${NANO_OBJ}/_.fdisk ${MD}
475149120Sphk	fdisk ${MD}
476148422Sphk	# XXX: params
477148422Sphk	# XXX: pick up cached boot* files, they may not be in image anymore.
478168894Sadrian	boot0cfg -B -b ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ${NANO_BOOT0CFG} ${MD}
479160388Sthomas	bsdlabel -w -B -b ${NANO_WORLDDIR}/boot/boot ${MD}s1
480149120Sphk	bsdlabel ${MD}s1
481148422Sphk
482148422Sphk	# Create first image
483209210Simp	# XXX: should use populate_slice for easier override
484148648Sphk	newfs ${NANO_NEWFS} /dev/${MD}s1a
485194437Sn_hibma	mount /dev/${MD}s1a ${MNT}
486149014Sphk	df -i ${MNT}
487175258Ssimon	echo "Copying worlddir..."
488148422Sphk	( cd ${NANO_WORLDDIR} && find . -print | cpio -dump ${MNT} )
489148422Sphk	df -i ${MNT}
490175258Ssimon	echo "Generating mtree..."
491194431Sn_hibma	( cd ${MNT} && mtree -c ) > ${NANO_OBJ}/_.mtree
492194431Sn_hibma	( cd ${MNT} && du -k ) > ${NANO_OBJ}/_.du
493148422Sphk	umount ${MNT}
494148422Sphk
495171986Sphk	if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then
496148422Sphk		# Duplicate to second image (if present)
497175258Ssimon		echo "Duplicating to second image..."
498194437Sn_hibma		dd if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k
499170322Sphk		mount /dev/${MD}s2a ${MNT}
500170322Sphk		for f in ${MNT}/etc/fstab ${MNT}/conf/base/etc/fstab
501170322Sphk		do
502170322Sphk			sed -i "" "s/${NANO_DRIVE}s1/${NANO_DRIVE}s2/g" $f
503170322Sphk		done
504170322Sphk		umount ${MNT}
505148422Sphk	fi
506148422Sphk	
507148422Sphk	# Create Config slice
508209210Simp	populate_cfg_slice /dev/${MD}s3 "${NANO_CFGDIR}" ${MNT}
509148422Sphk
510148422Sphk	# Create Data slice, if any.
511194437Sn_hibma	if [ $NANO_DATASIZE -ne 0 ] ; then
512209210Simp		populate_data_slice /dev/${MD}s4 "${NANO_DATADIR}" ${MNT}
513148422Sphk	fi
514148422Sphk
515175258Ssimon	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
516194440Sn_hibma		echo "Writing out ${NANO_IMGNAME}..."
517175258Ssimon		dd if=/dev/${MD} of=${IMG} bs=64k
518175258Ssimon	fi
519175258Ssimon
520175258Ssimon	echo "Writing out _.disk.image..."
521194437Sn_hibma	dd if=/dev/${MD}s1 of=${NANO_DISKIMGDIR}/_.disk.image bs=64k
522148422Sphk	mdconfig -d -u $MD
523197542Ssimon
524197542Ssimon	trap - 1 2 15 EXIT
525197542Ssimon
526194431Sn_hibma	) > ${NANO_OBJ}/_.di 2>&1
527148422Sphk)
528148422Sphk
529205980Simp# i386 and amd64 are identical for disk images
530205980Simpcreate_amd64_diskimage ( ) (
531205980Simp	create_i386_diskimage
532205980Simp)
533205980Simp
534154466Sphklast_orders () (
535154466Sphk	# Redefine this function with any last orders you may have
536154466Sphk	# after the build completed, for instance to copy the finished
537154466Sphk	# image to a more convenient place:
538194431Sn_hibma	# cp ${NANO_DISKIMGDIR}/_.disk.image /home/ftp/pub/nanobsd.disk
539154466Sphk)
540154466Sphk
541148422Sphk#######################################################################
542148422Sphk#
543150366Sphk# Optional convenience functions.
544148422Sphk#
545148422Sphk#######################################################################
546148422Sphk
547149014Sphk#######################################################################
548150367Sphk# Common Flash device geometries
549150367Sphk#
550150367Sphk
551150367SphkFlashDevice () {
552150717Sphk	if [ -d ${NANO_TOOLS} ] ; then
553150717Sphk		. ${NANO_TOOLS}/FlashDevice.sub
554150717Sphk	else
555150717Sphk		. ${NANO_SRC}/${NANO_TOOLS}/FlashDevice.sub
556150717Sphk	fi
557150367Sphk	sub_FlashDevice $1 $2
558150367Sphk}
559150367Sphk
560183284Sbms#######################################################################
561183284Sbms# USB device geometries
562183284Sbms#
563183284Sbms# Usage:
564183284Sbms#	UsbDevice Generic 1000	# a generic flash key sold as having 1GB
565183284Sbms#
566183284Sbms# This function will set NANO_MEDIASIZE, NANO_HEADS and NANO_SECTS for you.
567183284Sbms#
568183284Sbms# Note that the capacity of a flash key is usually advertised in MB or
569183284Sbms# GB, *not* MiB/GiB. As such, the precise number of cylinders available
570183284Sbms# for C/H/S geometry may vary depending on the actual flash geometry.
571183284Sbms#
572183284Sbms# The following generic device layouts are understood:
573183284Sbms#  generic           An alias for generic-hdd.
574183284Sbms#  generic-hdd       255H 63S/T xxxxC with no MBR restrictions.
575183284Sbms#  generic-fdd       64H 32S/T xxxxC with no MBR restrictions.
576183284Sbms#
577183284Sbms# The generic-hdd device is preferred for flash devices larger than 1GB.
578183284Sbms#
579150367Sphk
580183284SbmsUsbDevice () {
581183284Sbms	a1=`echo $1 | tr '[:upper:]' '[:lower:]'`
582183284Sbms	case $a1 in
583183284Sbms	generic-fdd)
584183284Sbms		NANO_HEADS=64
585183284Sbms		NANO_SECTS=32
586183284Sbms		NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 ))
587183284Sbms		;;
588183284Sbms	generic|generic-hdd)
589183284Sbms		NANO_HEADS=255
590183284Sbms		NANO_SECTS=63
591183284Sbms		NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 ))
592183284Sbms		;;
593183284Sbms	*)
594183284Sbms		echo "Unknown USB flash device"
595183284Sbms		exit 2
596183284Sbms		;;
597183284Sbms	esac
598183284Sbms}
599183284Sbms
600150367Sphk#######################################################################
601150366Sphk# Setup serial console
602150343Sphk
603150366Sphkcust_comconsole () (
604150366Sphk	# Enable getty on console
605181751Sphk	sed -i "" -e /tty[du]0/s/off/on/ ${NANO_WORLDDIR}/etc/ttys
606150366Sphk
607150366Sphk	# Disable getty on syscons devices
608150366Sphk	sed -i "" -e '/^ttyv[0-8]/s/	on/	off/' ${NANO_WORLDDIR}/etc/ttys
609150366Sphk
610150366Sphk	# Tell loader to use serial console early.
611150366Sphk	echo " -h" > ${NANO_WORLDDIR}/boot.config
612150366Sphk)
613150366Sphk
614150366Sphk#######################################################################
615150366Sphk# Allow root login via ssh
616150366Sphk
617150366Sphkcust_allow_ssh_root () (
618150366Sphk	sed -i "" -e '/PermitRootLogin/s/.*/PermitRootLogin yes/' \
619150366Sphk	    ${NANO_WORLDDIR}/etc/ssh/sshd_config
620150366Sphk)
621150366Sphk
622150366Sphk#######################################################################
623150366Sphk# Install the stuff under ./Files
624150366Sphk
625150366Sphkcust_install_files () (
626150511Ssimon	cd ${NANO_TOOLS}/Files
627183315Ssimon	find . -print | grep -Ev '/(CVS|\.svn)' | cpio -dumpv ${NANO_WORLDDIR}
628150366Sphk)
629150366Sphk
630150366Sphk#######################################################################
631170607Sphk# Install packages from ${NANO_PACKAGE_DIR}
632170607Sphk
633170607Sphkcust_pkg () (
634170607Sphk
635170607Sphk	# Copy packages into chroot
636170607Sphk	mkdir -p ${NANO_WORLDDIR}/Pkg
637186181Sphk	(
638186181Sphk		cd ${NANO_PACKAGE_DIR}
639186181Sphk		find ${NANO_PACKAGE_LIST} -print |
640186181Sphk		    cpio -dumpv ${NANO_WORLDDIR}/Pkg
641186181Sphk	)
642170607Sphk
643170607Sphk	# Count & report how many we have to install
644170607Sphk	todo=`ls ${NANO_WORLDDIR}/Pkg | wc -l`
645170607Sphk	echo "=== TODO: $todo"
646170607Sphk	ls ${NANO_WORLDDIR}/Pkg
647170607Sphk	echo "==="
648170607Sphk	while true
649170607Sphk	do
650182690Sthomas		# Record how many we have now
651170607Sphk		have=`ls ${NANO_WORLDDIR}/var/db/pkg | wc -l`
652170607Sphk
653171986Sphk		# Attempt to install more packages
654171986Sphk		# ...but no more than 200 at a time due to pkg_add's internal
655171986Sphk		# limitations.
656171986Sphk		chroot ${NANO_WORLDDIR} sh -c \
657171986Sphk			'ls Pkg/*tbz | xargs -n 200 pkg_add -F' || true
658170607Sphk
659170607Sphk		# See what that got us
660170607Sphk		now=`ls ${NANO_WORLDDIR}/var/db/pkg | wc -l`
661170607Sphk		echo "=== NOW $now"
662170607Sphk		ls ${NANO_WORLDDIR}/var/db/pkg
663170607Sphk		echo "==="
664170607Sphk
665170607Sphk
666170607Sphk		if [ $now -eq $todo ] ; then
667170607Sphk			echo "DONE $now packages"
668170607Sphk			break
669170607Sphk		elif [ $now -eq $have ] ; then
670170607Sphk			echo "FAILED: Nothing happened on this pass"
671170607Sphk			exit 2
672170607Sphk		fi
673170607Sphk	done
674170607Sphk	rm -rf ${NANO_WORLDDIR}/Pkg
675170607Sphk)
676170607Sphk
677170607Sphk#######################################################################
678150366Sphk# Convenience function:
679209207Simp# 	Register all args as customize function.
680150366Sphk
681150343Sphkcustomize_cmd () {
682209207Simp	NANO_CUSTOMIZE="$NANO_CUSTOMIZE $*"
683150343Sphk}
684150343Sphk
685150343Sphk#######################################################################
686181461Sphk# Convenience function:
687209207Simp# 	Register all args as late customize function to run just before
688181461Sphk#	image creation.
689181461Sphk
690181461Sphklate_customize_cmd () {
691209207Simp	NANO_LATE_CUSTOMIZE="$NANO_LATE_CUSTOMIZE $*"
692181461Sphk}
693181461Sphk
694181461Sphk#######################################################################
695150366Sphk#
696150366Sphk# All set up to go...
697150366Sphk#
698150366Sphk#######################################################################
699150366Sphk
700183314Ssimon# Progress Print
701183314Ssimon#	Print $2 at level $1.
702183314Ssimonpprint() {
703183314Ssimon    if [ "$1" -le $PPLEVEL ]; then
704194958Sn_hibma	runtime=$(( `date +%s` - $NANO_STARTTIME ))
705194958Sn_hibma	printf "%s %.${1}s %s\n" "`date -u -r $runtime +%H:%M:%S`" "#####" "$2" 1>&3
706183314Ssimon    fi
707183314Ssimon}
708183314Ssimon
709156496Sphkusage () {
710156496Sphk	(
711207436Sphilip	echo "Usage: $0 [-biknqvw] [-c config_file]"
712156496Sphk	echo "	-b	suppress builds (both kernel and world)"
713183314Ssimon	echo "	-i	suppress disk image build"
714156496Sphk	echo "	-k	suppress buildkernel"
715184048Ssam	echo "	-n	add -DNO_CLEAN to buildworld, buildkernel, etc"
716207436Sphilip	echo "	-q	make output more quiet"
717183314Ssimon	echo "	-v	make output more verbose"
718156496Sphk	echo "	-w	suppress buildworld"
719156496Sphk	echo "	-c	specify config file"
720156496Sphk	) 1>&2
721156496Sphk	exit 2
722156496Sphk}
723156496Sphk
724150366Sphk#######################################################################
725149014Sphk# Parse arguments
726148422Sphk
727184048Ssamdo_clean=true
728156496Sphkdo_kernel=true
729156496Sphkdo_world=true
730181460Sphkdo_image=true
731150366Sphk
732156496Sphkset +e
733184048Ssamargs=`getopt bc:hiknqvw $*`
734149014Sphkif [ $? -ne 0 ] ; then
735156496Sphk	usage
736149014Sphk	exit 2
737149014Sphkfi
738156496Sphkset -e
739149014Sphk
740149014Sphkset -- $args
741149014Sphkfor i
742149014Sphkdo
743149014Sphk	case "$i" 
744149014Sphk	in
745150366Sphk	-b)
746156496Sphk		do_world=false
747156496Sphk		do_kernel=false
748183314Ssimon		shift
749150366Sphk		;;
750156496Sphk	-k)
751156496Sphk		do_kernel=false
752183314Ssimon		shift
753156496Sphk		;;
754149014Sphk	-c)
755149014Sphk		. "$2"
756183314Ssimon		shift
757183314Ssimon		shift
758149014Sphk		;;
759150366Sphk	-h)
760156496Sphk		usage
761150366Sphk		;;
762181460Sphk	-i)
763181460Sphk		do_image=false
764183314Ssimon		shift
765181481Ssam		;;
766184048Ssam	-n)
767184048Ssam		do_clean=false
768184048Ssam		shift
769184048Ssam		;;
770183314Ssimon	-q)
771183314Ssimon		PPLEVEL=$(($PPLEVEL - 1))
772183314Ssimon		shift
773183314Ssimon		;;
774183314Ssimon	-v)
775183314Ssimon		PPLEVEL=$(($PPLEVEL + 1))
776183314Ssimon		shift
777183314Ssimon		;;
778156496Sphk	-w)
779156496Sphk		do_world=false
780183314Ssimon		shift
781156496Sphk		;;
782149014Sphk	--)
783183314Ssimon		shift
784183314Ssimon		break
785149014Sphk	esac
786149014Sphkdone
787149014Sphk
788150366Sphkif [ $# -gt 0 ] ; then
789156496Sphk	echo "$0: Extraneous arguments supplied"
790156496Sphk	usage
791150366Sphkfi
792150366Sphk
793148422Sphk#######################################################################
794150366Sphk# Setup and Export Internal variables
795150366Sphk#
796194431Sn_hibmatest -n "${NANO_OBJ}" || NANO_OBJ=/usr/obj/nanobsd.${NANO_NAME}/
797194431Sn_hibmatest -n "${MAKEOBJDIRPREFIX}" || MAKEOBJDIRPREFIX=${NANO_OBJ}
798194431Sn_hibmatest -n "${NANO_DISKIMGDIR}" || NANO_DISKIMGDIR=${NANO_OBJ}
799148422Sphk
800194431Sn_hibmaNANO_WORLDDIR=${NANO_OBJ}/_.w
801194431Sn_hibmaNANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build
802194431Sn_hibmaNANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install
803175258Ssimon
804150511Ssimonif [ -d ${NANO_TOOLS} ] ; then
805150511Ssimon	true
806150511Ssimonelif [ -d ${NANO_SRC}/${NANO_TOOLS} ] ; then
807150511Ssimon	NANO_TOOLS=${NANO_SRC}/${NANO_TOOLS}
808150511Ssimonelse
809150511Ssimon	echo "NANO_TOOLS directory does not exist" 1>&2
810150511Ssimon	exit 1
811150511Ssimonfi
812150511Ssimon
813184048Ssamif $do_clean ; then
814184048Ssam	true
815184048Ssamelse
816184048Ssam	NANO_PMAKE="${NANO_PMAKE} -DNO_CLEAN"
817184048Ssamfi
818184048Ssam
819148422Sphkexport MAKEOBJDIRPREFIX
820148422Sphk
821148422Sphkexport NANO_ARCH
822149120Sphkexport NANO_CODESIZE
823148422Sphkexport NANO_CONFSIZE
824149073Sphkexport NANO_CUSTOMIZE
825148422Sphkexport NANO_DATASIZE
826149082Sphkexport NANO_DRIVE
827148422Sphkexport NANO_HEADS
828148648Sphkexport NANO_IMAGES
829183284Sbmsexport NANO_IMGNAME
830194431Sn_hibmaexport NANO_MAKE_CONF_BUILD
831194431Sn_hibmaexport NANO_MAKE_CONF_INSTALL
832149120Sphkexport NANO_MEDIASIZE
833148648Sphkexport NANO_NAME
834148648Sphkexport NANO_NEWFS
835148648Sphkexport NANO_OBJ
836148422Sphkexport NANO_PMAKE
837148648Sphkexport NANO_SECTS
838148422Sphkexport NANO_SRC
839150366Sphkexport NANO_TOOLS
840148648Sphkexport NANO_WORLDDIR
841168894Sadrianexport NANO_BOOT0CFG
842168894Sadrianexport NANO_BOOTLOADER
843148422Sphk
844148422Sphk#######################################################################
845150366Sphk# And then it is as simple as that...
846148422Sphk
847194958Sn_hibma# File descriptor 3 is used for logging output, see pprint
848194958Sn_hibmaexec 3>&1
849194958Sn_hibma
850194958Sn_hibmaNANO_STARTTIME=`date +%s`
851183314Ssimonpprint 1 "NanoBSD image ${NANO_NAME} build starting"
852183314Ssimon
853156496Sphkif $do_world ; then
854184048Ssam	if $do_clean ; then
855184048Ssam		clean_build
856184048Ssam	else
857184048Ssam		pprint 2 "Using existing build tree (as instructed)"
858184048Ssam	fi
859150366Sphk	make_conf_build
860150366Sphk	build_world
861156496Sphkelse
862183314Ssimon	pprint 2 "Skipping buildworld (as instructed)"
863156496Sphkfi
864156496Sphk
865156496Sphkif $do_kernel ; then
866150366Sphk	build_kernel
867150366Sphkelse
868183314Ssimon	pprint 2 "Skipping buildkernel (as instructed)"
869150366Sphkfi
870149120Sphk
871149120Sphkclean_world
872149082Sphkmake_conf_install
873148422Sphkinstall_world
874148422Sphkinstall_etc
875161341Ssimonsetup_nanobsd_etc
876148422Sphkinstall_kernel
877149120Sphk
878149082Sphkrun_customize
879150366Sphksetup_nanobsd
880149014Sphkprune_usr
881181461Sphkrun_late_customize
882181460Sphkif $do_image ; then
883181460Sphk	create_${NANO_ARCH}_diskimage
884181460Sphkelse
885183314Ssimon	pprint 2 "Skipping image build (as instructed)"
886181460Sphkfi
887154466Sphklast_orders
888149120Sphk
889183314Ssimonpprint 1 "NanoBSD image ${NANO_NAME} completed"
890