nanobsd.sh revision 194431
1238106Sdes#!/bin/sh
2238106Sdes#
3238106Sdes# Copyright (c) 2005 Poul-Henning Kamp.
4238106Sdes# All rights reserved.
5238106Sdes#
6238106Sdes# Redistribution and use in source and binary forms, with or without
7238106Sdes# modification, are permitted provided that the following conditions
8238106Sdes# are met:
9238106Sdes# 1. Redistributions of source code must retain the above copyright
10238106Sdes#    notice, this list of conditions and the following disclaimer.
11238106Sdes# 2. Redistributions in binary form must reproduce the above copyright
12238106Sdes#    notice, this list of conditions and the following disclaimer in the
13238106Sdes#    documentation and/or other materials provided with the distribution.
14238106Sdes#
15238106Sdes# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16238106Sdes# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17238106Sdes# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18238106Sdes# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19238106Sdes# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20238106Sdes# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21238106Sdes# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22238106Sdes# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23238106Sdes# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24238106Sdes# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25238106Sdes# SUCH DAMAGE.
26238106Sdes#
27238106Sdes# $FreeBSD: head/tools/tools/nanobsd/nanobsd.sh 194431 2009-06-18 10:39:08Z n_hibma $
28238106Sdes#
29238106Sdes
30238106Sdesset -e
31238106Sdes
32238106Sdes#######################################################################
33238106Sdes#
34238106Sdes# Setup default values for all controlling variables.
35238106Sdes# These values can be overridden from the config file(s)
36238106Sdes#
37238106Sdes#######################################################################
38238106Sdes
39238106Sdes# Name of this NanoBSD build.  (Used to construct workdir names)
40238106SdesNANO_NAME=full
41238106Sdes
42238106Sdes# Source tree directory
43238106SdesNANO_SRC=/usr/src
44238106Sdes
45238106Sdes# Where nanobsd additional files live under the source tree
46238106SdesNANO_TOOLS=tools/tools/nanobsd
47238106Sdes
48238106Sdes# Where cust_pkg() finds packages to install
49238106SdesNANO_PACKAGE_DIR=${NANO_SRC}/${NANO_TOOLS}/Pkg
50238106SdesNANO_PACKAGE_LIST="*"
51238106Sdes
52238106Sdes# Object tree directory
53238106Sdes# default is subdir of /usr/obj
54238106Sdes#NANO_OBJ=""
55238106Sdes
56238106Sdes# The directory to put the final images
57238106Sdes# default is ${NANO_OBJ}
58238106Sdes#NANO_DISKIMGDIR=""
59238106Sdes
60238106Sdes# Parallel Make
61238106SdesNANO_PMAKE="make -j 3"
62238106Sdes
63238106Sdes# The default name for any image we create.
64238106SdesNANO_IMGNAME="_.disk.full"
65238106Sdes
66238106Sdes# Options to put in make.conf during buildworld only
67238106SdesCONF_BUILD=' '
68238106Sdes
69238106Sdes# Options to put in make.conf during installworld only
70238106SdesCONF_INSTALL=' '
71238106Sdes
72238106Sdes# Options to put in make.conf during both build- & installworld.
73238106SdesCONF_WORLD=' '
74238106Sdes
75238106Sdes# Kernel config file to use
76238106SdesNANO_KERNEL=GENERIC
77238106Sdes
78238106Sdes# Customize commands.
79238106SdesNANO_CUSTOMIZE=""
80238106Sdes
81238106Sdes# Late customize commands.
82238106SdesNANO_LATE_CUSTOMIZE=""
83238106Sdes
84238106Sdes# Newfs paramters to use
85238106SdesNANO_NEWFS="-b 4096 -f 512 -i 8192 -O1 -U"
86238106Sdes
87238106Sdes# The drive name of the media at runtime
88238106SdesNANO_DRIVE=ad0
89238106Sdes
90238106Sdes# Target media size in 512 bytes sectors
91238106SdesNANO_MEDIASIZE=1200000
92238106Sdes
93238106Sdes# Number of code images on media (1 or 2)
94238106SdesNANO_IMAGES=2
95238106Sdes
96238106Sdes# 0 -> Leave second image all zeroes so it compresses better.
97238106Sdes# 1 -> Initialize second image with a copy of the first
98238106SdesNANO_INIT_IMG2=1
99238106Sdes
100238106Sdes# Size of code file system in 512 bytes sectors
101238106Sdes# If zero, size will be as large as possible.
102238106SdesNANO_CODESIZE=0
103238106Sdes
104238106Sdes# Size of configuration file system in 512 bytes sectors
105238106Sdes# Cannot be zero.
106238106SdesNANO_CONFSIZE=2048
107238106Sdes
108238106Sdes# Size of data file system in 512 bytes sectors
109238106Sdes# If zero: no partition configured.
110238106Sdes# If negative: max size possible
111238106SdesNANO_DATASIZE=0
112238106Sdes
113238106Sdes# Size of the /etc ramdisk in 512 bytes sectors
114238106SdesNANO_RAM_ETCSIZE=10240
115238106Sdes
116238106Sdes# Size of the /tmp+/var ramdisk in 512 bytes sectors
117238106SdesNANO_RAM_TMPVARSIZE=10240
118238106Sdes
119238106Sdes# Media geometry, only relevant if bios doesn't understand LBA.
120238106SdesNANO_SECTS=63
121238106SdesNANO_HEADS=16
122238106Sdes
123238106Sdes# boot0 flags/options and configuration
124238106SdesNANO_BOOT0CFG="-o packet -s 1 -m 3"
125238106SdesNANO_BOOTLOADER="boot/boot0sio"
126238106Sdes
127238106Sdes# Backing type of md(4) device
128238106Sdes# Can be "file" or "swap"
129238106SdesNANO_MD_BACKING="file"
130238106Sdes
131238106Sdes# Progress Print level
132238106SdesPPLEVEL=3
133238106Sdes
134238106Sdes#######################################################################
135238106Sdes# Not a variable at this time
136238106Sdes
137238106SdesNANO_ARCH=i386
138238106Sdes
139238106Sdes#######################################################################
140238106Sdes#
141238106Sdes# The functions which do the real work.
142238106Sdes# Can be overridden from the config file(s)
143238106Sdes#
144238106Sdes#######################################################################
145238106Sdes
146238106Sdesclean_build ( ) (
147238106Sdes	pprint 2 "Clean and create object directory (${MAKEOBJDIRPREFIX})"
148238106Sdes
149238106Sdes	if ! rm -rf ${MAKEOBJDIRPREFIX} > /dev/null 2>&1 ; then
150238106Sdes		chflags -R noschg ${MAKEOBJDIRPREFIX}
151238106Sdes		rm -r ${MAKEOBJDIRPREFIX}
152238106Sdes	fi
153238106Sdes	mkdir -p ${MAKEOBJDIRPREFIX}
154238106Sdes	printenv > ${MAKEOBJDIRPREFIX}/_.env
155238106Sdes)
156238106Sdes
157238106Sdesmake_conf_build ( ) (
158238106Sdes	pprint 2 "Construct build make.conf ($NANO_MAKE_CONF_BUILD)"
159238106Sdes
160238106Sdes	echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_BUILD}
161238106Sdes	echo "${CONF_BUILD}" >> ${NANO_MAKE_CONF_BUILD}
162238106Sdes)
163238106Sdes
164238106Sdesbuild_world ( ) (
165238106Sdes	pprint 2 "run buildworld"
166238106Sdes	pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bw"
167238106Sdes
168238106Sdes	cd ${NANO_SRC}
169238106Sdes	env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} \
170238106Sdes		__MAKE_CONF=${NANO_MAKE_CONF_BUILD} buildworld \
171238106Sdes		> ${MAKEOBJDIRPREFIX}/_.bw 2>&1
172238106Sdes)
173238106Sdes
174238106Sdesbuild_kernel ( ) (
175238106Sdes	pprint 2 "build kernel ($NANO_KERNEL)"
176238106Sdes	pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bk"
177238106Sdes
178238106Sdes	if [ -f ${NANO_KERNEL} ] ; then
179238106Sdes		cp ${NANO_KERNEL} ${NANO_SRC}/sys/${NANO_ARCH}/conf
180238106Sdes	fi
181238106Sdes
182238106Sdes	(cd ${NANO_SRC};
183238106Sdes	# unset these just in case to avoid compiler complaints
184238106Sdes	# when cross-building
185238106Sdes	unset TARGET_CPUTYPE
186238106Sdes	unset TARGET_BIG_ENDIAN
187238106Sdes	env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} buildkernel \
188238106Sdes		__MAKE_CONF=${NANO_MAKE_CONF_BUILD} KERNCONF=`basename ${NANO_KERNEL}` \
189238106Sdes		> ${NANO_OBJ}/_.bk 2>&1
190238106Sdes	)
191238106Sdes)
192238106Sdes
193238106Sdesclean_world ( ) (
194238106Sdes	if [ "${NANO_OBJ}" != "${MAKEOBJDIRPREFIX}" ]; then
195238106Sdes		pprint 2 "Clean and create object directory (${NANO_OBJ})"
196238106Sdes		if ! rm -rf ${NANO_OBJ} > /dev/null 2>&1 ; then
197238106Sdes			chflags -R noschg ${NANO_OBJ}
198238106Sdes			rm -r ${NANO_OBJ}
199238106Sdes		fi
200238106Sdes		mkdir -p ${NANO_OBJ} ${NANO_WORLDDIR}
201238106Sdes		printenv > ${NANO_OBJ}/_.env
202238106Sdes	else
203238106Sdes		pprint 2 "Clean and create world directory (${NANO_WORLDDIR})"
204238106Sdes		if ! rm -rf ${NANO_WORLDDIR}/ > /dev/null 2>&1 ; then
205238106Sdes			chflags -R noschg ${NANO_WORLDDIR}
206238106Sdes			rm -rf ${NANO_WORLDDIR}
207238106Sdes		fi
208238106Sdes		mkdir -p ${NANO_WORLDDIR}
209238106Sdes	fi
210238106Sdes)
211238106Sdes
212238106Sdesmake_conf_install ( ) (
213238106Sdes	pprint 2 "Construct install make.conf ($NANO_MAKE_CONF_INSTALL)"
214238106Sdes
215238106Sdes	echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_INSTALL}
216238106Sdes	echo "${CONF_INSTALL}" >> ${NANO_MAKE_CONF_INSTALL}
217238106Sdes)
218238106Sdes
219238106Sdesinstall_world ( ) (
220238106Sdes	pprint 2 "installworld"
221238106Sdes	pprint 3 "log: ${NANO_OBJ}/_.iw"
222238106Sdes
223238106Sdes	cd ${NANO_SRC}
224238106Sdes	env TARGET_ARCH=${NANO_ARCH} \
225238106Sdes	${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} installworld \
226238106Sdes		DESTDIR=${NANO_WORLDDIR} \
227238106Sdes		> ${NANO_OBJ}/_.iw 2>&1
228238106Sdes	chflags -R noschg ${NANO_WORLDDIR}
229238106Sdes)
230238106Sdes
231238106Sdesinstall_etc ( ) (
232238106Sdes
233238106Sdes	pprint 2 "install /etc"
234238106Sdes	pprint 3 "log: ${NANO_OBJ}/_.etc"
235238106Sdes
236238106Sdes	cd ${NANO_SRC}
237238106Sdes	env TARGET_ARCH=${NANO_ARCH} \
238238106Sdes	${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} distribution \
239238106Sdes		DESTDIR=${NANO_WORLDDIR} \
240238106Sdes		> ${NANO_OBJ}/_.etc 2>&1
241238106Sdes)
242238106Sdes
243238106Sdesinstall_kernel ( ) (
244238106Sdes	pprint 2 "install kernel"
245238106Sdes	pprint 3 "log: ${NANO_OBJ}/_.ik"
246238106Sdes
247238106Sdes	cd ${NANO_SRC}
248238106Sdes	env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} installkernel \
249238106Sdes		DESTDIR=${NANO_WORLDDIR} \
250238106Sdes		__MAKE_CONF=${NANO_MAKE_CONF_INSTALL} KERNCONF=`basename ${NANO_KERNEL}` \
251238106Sdes		> ${NANO_OBJ}/_.ik 2>&1
252238106Sdes)
253238106Sdes
254238106Sdesrun_customize() (
255238106Sdes
256238106Sdes	pprint 2 "run customize scripts"
257238106Sdes	for c in $NANO_CUSTOMIZE
258238106Sdes	do
259238106Sdes		pprint 2 "customize \"$c\""
260238106Sdes		pprint 3 "log: ${NANO_OBJ}/_.cust.$c"
261238106Sdes		pprint 4 "`type $c`"
262238106Sdes		( $c ) > ${NANO_OBJ}/_.cust.$c 2>&1
263238106Sdes	done
264238106Sdes)
265238106Sdes
266238106Sdesrun_late_customize() (
267238106Sdes
268238106Sdes	pprint 2 "run late customize scripts"
269238106Sdes	for c in $NANO_LATE_CUSTOMIZE
270238106Sdes	do
271238106Sdes		pprint 2 "late customize \"$c\""
272238106Sdes		pprint 3 "log: ${NANO_OBJ}/_.late_cust.$c"
273238106Sdes		pprint 4 "`type $c`"
274238106Sdes		( $c ) > ${NANO_OBJ}/_.late_cust.$c 2>&1
275238106Sdes	done
276238106Sdes)
277238106Sdes
278238106Sdessetup_nanobsd ( ) (
279238106Sdes	pprint 2 "configure nanobsd setup"
280238106Sdes	pprint 3 "log: ${NANO_OBJ}/_.dl"
281238106Sdes
282238106Sdes	(
283238106Sdes	cd ${NANO_WORLDDIR}
284238106Sdes
285238106Sdes	# Move /usr/local/etc to /etc/local so that the /cfg stuff
286238106Sdes	# can stomp on it.  Otherwise packages like ipsec-tools which
287238106Sdes	# have hardcoded paths under ${prefix}/etc are not tweakable.
288238106Sdes	if [ -d usr/local/etc ] ; then
289238106Sdes		(
290238106Sdes		mkdir -p etc/local
291238106Sdes		cd usr/local/etc
292238106Sdes		find . -print | cpio -dumpl ../../../etc/local
293238106Sdes		cd ..
294238106Sdes		rm -rf etc
295238106Sdes		ln -s ../../etc/local etc
296238106Sdes		)
297238106Sdes	fi
298238106Sdes
299238106Sdes	for d in var etc
300238106Sdes	do
301238106Sdes		# link /$d under /conf
302238106Sdes		# we use hard links so we have them both places.
303238106Sdes		# the files in /$d will be hidden by the mount.
304238106Sdes		# XXX: configure /$d ramdisk size
305238106Sdes		mkdir -p conf/base/$d conf/default/$d
306238106Sdes		find $d -print | cpio -dumpl conf/base/
307238106Sdes	done
308238106Sdes
309238106Sdes	echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size
310238106Sdes	echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size
311238106Sdes
312238106Sdes	# pick up config files from the special partition
313238106Sdes	echo "mount -o ro /dev/${NANO_DRIVE}s3" > conf/default/etc/remount
314238106Sdes
315238106Sdes	# Put /tmp on the /var ramdisk (could be symlink already)
316238106Sdes	rmdir tmp || true
317238106Sdes	rm tmp || true
318238106Sdes	ln -s var/tmp tmp
319238106Sdes
320238106Sdes	) > ${NANO_OBJ}/_.dl 2>&1
321238106Sdes)
322238106Sdes
323238106Sdessetup_nanobsd_etc ( ) (
324238106Sdes	pprint 2 "configure nanobsd /etc"
325238106Sdes
326238106Sdes	(
327238106Sdes	cd ${NANO_WORLDDIR}
328238106Sdes
329238106Sdes	# create diskless marker file
330238106Sdes	touch etc/diskless
331238106Sdes
332238106Sdes	# Make root filesystem R/O by default
333238106Sdes	echo "root_rw_mount=NO" >> etc/defaults/rc.conf
334238106Sdes
335238106Sdes	# save config file for scripts
336238106Sdes	echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
337238106Sdes
338238106Sdes	echo "/dev/${NANO_DRIVE}s1a / ufs ro 1 1" > etc/fstab
339238106Sdes	echo "/dev/${NANO_DRIVE}s3 /cfg ufs rw,noauto 2 2" >> etc/fstab
340238106Sdes	mkdir -p cfg
341238106Sdes	)
342238106Sdes)
343238106Sdes
344238106Sdesprune_usr() (
345238106Sdes
346	# Remove all empty directories in /usr 
347	find ${NANO_WORLDDIR}/usr -type d -depth -print |
348		while read d
349		do
350			rmdir $d > /dev/null 2>&1 || true 
351		done
352)
353
354create_i386_diskimage ( ) (
355	pprint 2 "build diskimage"
356	pprint 3 "log: ${NANO_OBJ}/_.di"
357
358	(
359	echo $NANO_MEDIASIZE $NANO_IMAGES \
360		$NANO_SECTS $NANO_HEADS \
361		$NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE |
362	awk '
363	{
364		printf "# %s\n", $0
365
366		# size of cylinder in sectors
367		cs = $3 * $4
368
369		# number of full cylinders on media
370		cyl = int ($1 / cs)
371
372		# output fdisk geometry spec, truncate cyls to 1023
373		if (cyl <= 1023)
374			print "g c" cyl " h" $4 " s" $3
375		else
376			print "g c" 1023 " h" $4 " s" $3
377
378		if ($7 > 0) { 
379			# size of data partition in full cylinders
380			dsl = int (($7 + cs - 1) / cs)
381		} else {
382			dsl = 0;
383		}
384
385		# size of config partition in full cylinders
386		csl = int (($6 + cs - 1) / cs)
387
388		if ($5 == 0) {
389			# size of image partition(s) in full cylinders
390			isl = int ((cyl - dsl - csl) / $2)
391		} else {
392			isl = int (($5 + cs - 1) / cs)
393		}
394
395		# First image partition start at second track
396		print "p 1 165 " $3, isl * cs - $3
397		c = isl * cs;
398
399		# Second image partition (if any) also starts offset one 
400		# track to keep them identical.
401		if ($2 > 1) {
402			print "p 2 165 " $3 + c, isl * cs - $3
403			c += isl * cs;
404		}
405
406		# Config partition starts at cylinder boundary.
407		print "p 3 165 " c, csl * cs
408		c += csl * cs
409
410		# Data partition (if any) starts at cylinder boundary.
411		if ($7 > 0) {
412			print "p 4 165 " c, dsl * cs
413		} else if ($7 < 0 && $1 > c) {
414			print "p 4 165 " c, $1 - c
415		} else if ($1 < c) {
416			print "Disk space overcommitted by", \
417			    c - $1, "sectors" > "/dev/stderr"
418			exit 2
419		}
420
421		# Force slice 1 to be marked active. This is necessary
422		# for booting the image from a USB device to work.
423		print "a 1"
424	}
425	' > ${NANO_OBJ}/_.fdisk
426
427	IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
428	MNT=${NANO_OBJ}/_.mnt
429	mkdir -p ${MNT}
430
431	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
432		MD=`mdconfig -a -t swap -s ${NANO_MEDIASIZE} -x ${NANO_SECTS} \
433			-y ${NANO_HEADS}`
434	else
435		echo "Creating md backing file..."
436		dd if=/dev/zero of=${IMG} bs=${NANO_SECTS}b \
437			seek=`expr ${NANO_MEDIASIZE} / ${NANO_SECTS}` count=0
438		MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \
439			-y ${NANO_HEADS}`
440	fi
441
442	trap "df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT
443
444	fdisk -i -f ${NANO_OBJ}/_.fdisk ${MD}
445	fdisk ${MD}
446	# XXX: params
447	# XXX: pick up cached boot* files, they may not be in image anymore.
448	boot0cfg -B -b ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ${NANO_BOOT0CFG} ${MD}
449	bsdlabel -w -B -b ${NANO_WORLDDIR}/boot/boot ${MD}s1
450	bsdlabel ${MD}s1
451
452	# Create first image
453	newfs ${NANO_NEWFS} /dev/${MD}s1a
454	mount -o async /dev/${MD}s1a ${MNT}
455	df -i ${MNT}
456	echo "Copying worlddir..."
457	( cd ${NANO_WORLDDIR} && find . -print | cpio -dump ${MNT} )
458	df -i ${MNT}
459	echo "Generating mtree..."
460	( cd ${MNT} && mtree -c ) > ${NANO_OBJ}/_.mtree
461	( cd ${MNT} && du -k ) > ${NANO_OBJ}/_.du
462	umount ${MNT}
463
464	if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then
465		# Duplicate to second image (if present)
466		echo "Duplicating to second image..."
467		dd conv=sparse if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k
468		mount /dev/${MD}s2a ${MNT}
469		for f in ${MNT}/etc/fstab ${MNT}/conf/base/etc/fstab
470		do
471			sed -i "" "s/${NANO_DRIVE}s1/${NANO_DRIVE}s2/g" $f
472		done
473		umount ${MNT}
474	fi
475	
476	# Create Config slice
477	newfs ${NANO_NEWFS} /dev/${MD}s3
478	# XXX: fill from where ?
479
480	# Create Data slice, if any.
481	if [ $NANO_DATASIZE -gt 0 ] ; then
482		newfs ${NANO_NEWFS} /dev/${MD}s4
483		# XXX: fill from where ?
484	fi
485
486	if [ "${NANO_MD_BACKING}" = "swap" ] ; then
487		echo "Writing out _.disk.full..."
488		dd if=/dev/${MD} of=${IMG} bs=64k
489	fi
490
491	echo "Writing out _.disk.image..."
492	dd conv=sparse if=/dev/${MD}s1 of=${NANO_DISKIMGDIR}/_.disk.image bs=64k
493	mdconfig -d -u $MD
494	) > ${NANO_OBJ}/_.di 2>&1
495)
496
497last_orders () (
498	# Redefine this function with any last orders you may have
499	# after the build completed, for instance to copy the finished
500	# image to a more convenient place:
501	# cp ${NANO_DISKIMGDIR}/_.disk.image /home/ftp/pub/nanobsd.disk
502)
503
504#######################################################################
505#
506# Optional convenience functions.
507#
508#######################################################################
509
510#######################################################################
511# Common Flash device geometries
512#
513
514FlashDevice () {
515	if [ -d ${NANO_TOOLS} ] ; then
516		. ${NANO_TOOLS}/FlashDevice.sub
517	else
518		. ${NANO_SRC}/${NANO_TOOLS}/FlashDevice.sub
519	fi
520	sub_FlashDevice $1 $2
521}
522
523#######################################################################
524# USB device geometries
525#
526# Usage:
527#	UsbDevice Generic 1000	# a generic flash key sold as having 1GB
528#
529# This function will set NANO_MEDIASIZE, NANO_HEADS and NANO_SECTS for you.
530#
531# Note that the capacity of a flash key is usually advertised in MB or
532# GB, *not* MiB/GiB. As such, the precise number of cylinders available
533# for C/H/S geometry may vary depending on the actual flash geometry.
534#
535# The following generic device layouts are understood:
536#  generic           An alias for generic-hdd.
537#  generic-hdd       255H 63S/T xxxxC with no MBR restrictions.
538#  generic-fdd       64H 32S/T xxxxC with no MBR restrictions.
539#
540# The generic-hdd device is preferred for flash devices larger than 1GB.
541#
542
543UsbDevice () {
544	a1=`echo $1 | tr '[:upper:]' '[:lower:]'`
545	case $a1 in
546	generic-fdd)
547		NANO_HEADS=64
548		NANO_SECTS=32
549		NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 ))
550		;;
551	generic|generic-hdd)
552		NANO_HEADS=255
553		NANO_SECTS=63
554		NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 ))
555		;;
556	*)
557		echo "Unknown USB flash device"
558		exit 2
559		;;
560	esac
561}
562
563#######################################################################
564# Setup serial console
565
566cust_comconsole () (
567	# Enable getty on console
568	sed -i "" -e /tty[du]0/s/off/on/ ${NANO_WORLDDIR}/etc/ttys
569
570	# Disable getty on syscons devices
571	sed -i "" -e '/^ttyv[0-8]/s/	on/	off/' ${NANO_WORLDDIR}/etc/ttys
572
573	# Tell loader to use serial console early.
574	echo " -h" > ${NANO_WORLDDIR}/boot.config
575)
576
577#######################################################################
578# Allow root login via ssh
579
580cust_allow_ssh_root () (
581	sed -i "" -e '/PermitRootLogin/s/.*/PermitRootLogin yes/' \
582	    ${NANO_WORLDDIR}/etc/ssh/sshd_config
583)
584
585#######################################################################
586# Install the stuff under ./Files
587
588cust_install_files () (
589	cd ${NANO_TOOLS}/Files
590	find . -print | grep -Ev '/(CVS|\.svn)' | cpio -dumpv ${NANO_WORLDDIR}
591)
592
593#######################################################################
594# Install packages from ${NANO_PACKAGE_DIR}
595
596cust_pkg () (
597
598	# Copy packages into chroot
599	mkdir -p ${NANO_WORLDDIR}/Pkg
600	(
601		cd ${NANO_PACKAGE_DIR}
602		find ${NANO_PACKAGE_LIST} -print |
603		    cpio -dumpv ${NANO_WORLDDIR}/Pkg
604	)
605
606	# Count & report how many we have to install
607	todo=`ls ${NANO_WORLDDIR}/Pkg | wc -l`
608	echo "=== TODO: $todo"
609	ls ${NANO_WORLDDIR}/Pkg
610	echo "==="
611	while true
612	do
613		# Record how many we have now
614		have=`ls ${NANO_WORLDDIR}/var/db/pkg | wc -l`
615
616		# Attempt to install more packages
617		# ...but no more than 200 at a time due to pkg_add's internal
618		# limitations.
619		chroot ${NANO_WORLDDIR} sh -c \
620			'ls Pkg/*tbz | xargs -n 200 pkg_add -F' || true
621
622		# See what that got us
623		now=`ls ${NANO_WORLDDIR}/var/db/pkg | wc -l`
624		echo "=== NOW $now"
625		ls ${NANO_WORLDDIR}/var/db/pkg
626		echo "==="
627
628
629		if [ $now -eq $todo ] ; then
630			echo "DONE $now packages"
631			break
632		elif [ $now -eq $have ] ; then
633			echo "FAILED: Nothing happened on this pass"
634			exit 2
635		fi
636	done
637	rm -rf ${NANO_WORLDDIR}/Pkg
638)
639
640#######################################################################
641# Convenience function:
642# 	Register $1 as customize function.
643
644customize_cmd () {
645	NANO_CUSTOMIZE="$NANO_CUSTOMIZE $1"
646}
647
648#######################################################################
649# Convenience function:
650# 	Register $1 as late customize function to run just before
651#	image creation.
652
653late_customize_cmd () {
654	NANO_LATE_CUSTOMIZE="$NANO_LATE_CUSTOMIZE $1"
655}
656
657#######################################################################
658#
659# All set up to go...
660#
661#######################################################################
662
663# Progress Print
664#	Print $2 at level $1.
665pprint() {
666    if [ "$1" -le $PPLEVEL ]; then
667	printf "%.${1}s %s\n" "#####" "$2"
668    fi
669}
670
671usage () {
672	(
673	echo "Usage: $0 [-bikqvw] [-c config_file]"
674	echo "	-b	suppress builds (both kernel and world)"
675	echo "	-i	suppress disk image build"
676	echo "	-k	suppress buildkernel"
677	echo "	-n	add -DNO_CLEAN to buildworld, buildkernel, etc"
678	echo "	-q	make output more quite"
679	echo "	-v	make output more verbose"
680	echo "	-w	suppress buildworld"
681	echo "	-c	specify config file"
682	) 1>&2
683	exit 2
684}
685
686#######################################################################
687# Parse arguments
688
689do_clean=true
690do_kernel=true
691do_world=true
692do_image=true
693
694set +e
695args=`getopt bc:hiknqvw $*`
696if [ $? -ne 0 ] ; then
697	usage
698	exit 2
699fi
700set -e
701
702set -- $args
703for i
704do
705	case "$i" 
706	in
707	-b)
708		do_world=false
709		do_kernel=false
710		shift
711		;;
712	-k)
713		do_kernel=false
714		shift
715		;;
716	-c)
717		. "$2"
718		shift
719		shift
720		;;
721	-h)
722		usage
723		;;
724	-i)
725		do_image=false
726		shift
727		;;
728	-n)
729		do_clean=false
730		shift
731		;;
732	-q)
733		PPLEVEL=$(($PPLEVEL - 1))
734		shift
735		;;
736	-v)
737		PPLEVEL=$(($PPLEVEL + 1))
738		shift
739		;;
740	-w)
741		do_world=false
742		shift
743		;;
744	--)
745		shift
746		break
747	esac
748done
749
750if [ $# -gt 0 ] ; then
751	echo "$0: Extraneous arguments supplied"
752	usage
753fi
754
755#######################################################################
756# Setup and Export Internal variables
757#
758test -n "${NANO_OBJ}" || NANO_OBJ=/usr/obj/nanobsd.${NANO_NAME}/
759test -n "${MAKEOBJDIRPREFIX}" || MAKEOBJDIRPREFIX=${NANO_OBJ}
760test -n "${NANO_DISKIMGDIR}" || NANO_DISKIMGDIR=${NANO_OBJ}
761
762NANO_WORLDDIR=${NANO_OBJ}/_.w
763NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build
764NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install
765
766if [ -d ${NANO_TOOLS} ] ; then
767	true
768elif [ -d ${NANO_SRC}/${NANO_TOOLS} ] ; then
769	NANO_TOOLS=${NANO_SRC}/${NANO_TOOLS}
770else
771	echo "NANO_TOOLS directory does not exist" 1>&2
772	exit 1
773fi
774
775if $do_clean ; then
776	true
777else
778	NANO_PMAKE="${NANO_PMAKE} -DNO_CLEAN"
779fi
780
781export MAKEOBJDIRPREFIX
782
783export NANO_ARCH
784export NANO_CODESIZE
785export NANO_CONFSIZE
786export NANO_CUSTOMIZE
787export NANO_DATASIZE
788export NANO_DRIVE
789export NANO_HEADS
790export NANO_IMAGES
791export NANO_IMGNAME
792export NANO_MAKE_CONF_BUILD
793export NANO_MAKE_CONF_INSTALL
794export NANO_MEDIASIZE
795export NANO_NAME
796export NANO_NEWFS
797export NANO_OBJ
798export NANO_PMAKE
799export NANO_SECTS
800export NANO_SRC
801export NANO_TOOLS
802export NANO_WORLDDIR
803export NANO_BOOT0CFG
804export NANO_BOOTLOADER
805
806#######################################################################
807# And then it is as simple as that...
808
809pprint 1 "NanoBSD image ${NANO_NAME} build starting"
810
811if $do_world ; then
812	if $do_clean ; then
813		clean_build
814	else
815		pprint 2 "Using existing build tree (as instructed)"
816	fi
817	make_conf_build
818	build_world
819else
820	pprint 2 "Skipping buildworld (as instructed)"
821fi
822
823if $do_kernel ; then
824	build_kernel
825else
826	pprint 2 "Skipping buildkernel (as instructed)"
827fi
828
829clean_world
830make_conf_install
831install_world
832install_etc
833setup_nanobsd_etc
834install_kernel
835
836run_customize
837setup_nanobsd
838prune_usr
839run_late_customize
840if $do_image ; then
841	create_${NANO_ARCH}_diskimage
842	echo "# Created NanoBSD disk image: ${NANO_DISKIMGDIR}/${NANO_IMGNAME}"
843else
844	pprint 2 "Skipping image build (as instructed)"
845fi
846last_orders
847
848pprint 1 "NanoBSD image ${NANO_NAME} completed"
849