picobsd revision 244642
172770Sluigi#!/bin/sh -
272770Sluigi#
372770Sluigi# $FreeBSD: head/release/picobsd/build/picobsd 244642 2012-12-23 22:41:54Z luigi $
4155136Sluigi# This file requires sysutils/makefs to run
572770Sluigi#
6190378Sluigi# The PicoBSD build script. Invoked as
772770Sluigi#
8190378Sluigi#	picobsd [options] image_type [site_name]
972770Sluigi#
10239738Sluigi# CWARNFLAGS can be used to pass -Wall or similar options
11239738Sluigi#
12190378Sluigi# Where image_type is a directory with the picobsd config info,
13190378Sluigi# and ${image_type}/floppy.tree.${site_name} contains
1472770Sluigi# optional site-specific configuration.
1572770Sluigi#
1672770Sluigi# For Options, see the bottom of the file where the processing is
1778494Sluigi# done. The picobsd(8) manpage might be of some help, but code and docs
18190378Sluigi# tend to lose sync over time.
1972770Sluigi#
2072770Sluigi# This script depends on the following files:
2172770Sluigi#
2272770Sluigi# in ${PICO_TREE} :
2372770Sluigi#   Makefile.conf	Makefile used to build the kernel
2472770Sluigi#   config		shell variables, sourced here.
2572770Sluigi#   mfs.mtree		mtree config file
2672770Sluigi#   floppy.tree/	files which go on the floppy
2772770Sluigi#   mfs_tree/		files which go onto the mfs
2872770Sluigi#
2972770Sluigi# in ${MY_TREE} :
3072770Sluigi#   PICOBSD		kernel config file
3172770Sluigi#   config		shell variables, sourced here.
3272770Sluigi#   crunch.conf		crunchgen configuration
33188835Sluigi#   mfs.mtree		overrides ${PICO_TREE}/mfs.mtree
3472770Sluigi#   floppy.tree.exclude	files from floppy.tree/ which we do not need here.
35188835Sluigi#   floppy.tree/	local additions to ${PICO_TREE}/mfs_free
3672770Sluigi#   floppy.tree.${site}/ same as above, site specific.
37122229Ssimokawa#   mfs_tree/		local additions to the mfs_free
38190378Sluigi#   buildtree.mk	optional Makefile to build an extension for floppy tree
39188835Sluigi#			(generated in buildtree/ )
4072770Sluigi
4172770Sluigi#
4272770Sluigi#--- The main entry point is at the end.
4372770Sluigi#
4472770Sluigi
45190378Sluigi# There are two initialization functions:
4684377Sluigi#
47190378Sluigi# + set_defaults
48190378Sluigi#   is run on entry to the script, and is used to set default values
49190378Sluigi#   for all variables that do not depend on image type and source tree.
5084377Sluigi#
51190378Sluigi# + set_build_parameters
52190378Sluigi#   is run after command line parsing
53190378Sluigi#
54190378Sluigi# VARIABLE NAMES:
5584377Sluigi# + variables that control operation (e.g. verbosity) and are generally
5684377Sluigi#   set from the command line have o_ ("option") as a name prefix
5784377Sluigi#
58190378Sluigi# + variables that contain pathnames and values that should not change
5984377Sluigi#   have c_ ("constant") as a name prefix
6084377Sluigi#
6184377Sluigi# + variables exported to Makefiles and subshells are CAPITAL
6284377Sluigi#
6384377Sluigi# + variables local to the script are lowercase, possibly with
64190378Sluigi#   an l_ ("local") prefix.
65190378Sluigi#
66190378Sluigi# There are unfortunately exceptions:
67190378Sluigi# name, l_usrtree, l_objtree
6872770Sluigi
6984377Sluigi# SRC points to your FreeBSD source tree.
7084377Sluigi# l_usrtree points to the /usr subdir for the source tree.
7184377Sluigi#     Normally /usr or ${SRC}/../usr
72227878Sluigi# l_objtree points to the obj tree. Normally ${l_usrtree}/obj-pico-${o_arch}
73190378Sluigi# c_label is either bsdlabel or disklabel
7484377Sluigi# PICO_TREE is where standard picobsd stuff resides.
7584377Sluigi#     Normally ${SRC}/release/picobsd
7684377Sluigi# You can set SRC with --src <directory>
7784377Sluigi# It is not recommended to override the other variables.
7872770Sluigi
7984377Sluigi# MY_TREE (set later) is where this floppy type resides.
8084377Sluigi# BUILDDIR is the build directory
8172770Sluigi
8284377Sluigi# log something on stdout if verbose.
8384377Sluigio_verbose=0	# this needs to be here!
84190378Sluigilog() {	#	message
85173602Sluigi    local foo
86173602Sluigi    [ ${o_verbose} -gt 0 ] && printf "\n*** %s\n" "$*"
87173602Sluigi    [ ${o_verbose}  -gt 1 ] && read -p "=== Press enter to continue" foo
88173602Sluigi    return 0
8984377Sluigi}
9083723Sjoe
91190378Sluigi# unconditionally log and wait for input
92190378Sluigilogverbose() {	# message
93127266Sluigi    local foo
9491846Sluigi    printf "\n*** %s\n" "$*"
9591846Sluigi    read -p "=== Press enter to continue" foo
96173602Sluigi    return 0
9791846Sluigi}
9891846Sluigi
99190378Sluigi# set some default values for variables.
100190378Sluigi# needs to be done as the first thing in the script.
10172770Sluigi
102190378Sluigiset_defaults() {	# no arguments
10372770Sluigi    # EDITOR is the editor you use
10484377Sluigi    # fd_size  floppy size in KB (default to 1440). You can use 1480,
10572770Sluigi    #	1720, 2880, etc. but beware that only 1440 and 1480 will boot
10672770Sluigi    #	from 1.44M floppy drives (1480 will not work on vmware).
10772770Sluigi    EDITOR=${EDITOR:-vi}
10884377Sluigi    fd_size=${fd_size:-1440}
10972770Sluigi
110190378Sluigi    o_all_in_mfs="yes"		# put all files in mfs so you can boot
111190378Sluigi				# and run the image via diskless boot.
112190378Sluigi    o_clean=""			# set if you want to clean prev.builds.
11384377Sluigi    o_interactive=""		# default is interactive
11484377Sluigi    o_verbose=0			# verbose level, 0 is silent
11584377Sluigi    o_tarv=""			# tar verbose flag, "" or "v"
116190378Sluigi    o_init_src=""		# set to build libs and includes.
11784377Sluigi    o_makeopts=${MAKEOPTS:--s}	# make options, be silent by default
118190378Sluigi    o_no_devfs=			# default is use devfs.
119190378Sluigi	# You should only set it when building 4.x images
12085833Sluigi    o_do_modules=""		# do not build modules
121227878Sluigi    o_arch=`uname -m`		# default to amd64 or i386 ...
12272770Sluigi
12384377Sluigi    SRC="/usr/src"		# default location for sources
124155136Sluigi    c_startdir=`pwd`		# directory where we start
125155136Sluigi				# used to lookup config and create BUILDDIR
12684377Sluigi
127155136Sluigi    # XXX 6.x/7.x have a single /boot/boot block, which is the concatenation
128155136Sluigi    # of the old two. For the time being, we keep these, but this should
129155136Sluigi    # be fixed at some point.
130155136Sluigi
131155136Sluigi    # blocks
132127266Sluigi    c_boot1=/boot/boot1		# boot blocks (in case you want custom ones)
13384377Sluigi    c_boot2=/boot/boot2
13484377Sluigi
13584377Sluigi    c_reply=${c_reply:-`mktemp "/tmp/reply.XXXXXXXXXX"`}
136155136Sluigi    				# file where User replies will be put
13784377Sluigi    c_mnt=`mktemp -d "/tmp/picobsd.XXXXXXXXXX"`
138155136Sluigi    				# mountpoint used to build memory filesystems
139155136Sluigi    c_fs=fs.PICOBSD		# filename used for the memory filesystem
140155136Sluigi    c_img=picobsd.bin		# filename used for the picobsd image
141194635Sluigi    c_iso=picobsd.iso		# filename used for the ISO image
142188835Sluigi    generate_iso="NO"		# don't generate the iso image
14384377Sluigi
144190378Sluigi    # select the right disklabel program
14584377Sluigi    case `uname -r` in
146190378Sluigi	4.*)
147190378Sluigi	    c_label="disklabel"
14884377Sluigi	    ;;
14984377Sluigi	*)
150190378Sluigi	    c_label="bsdlabel"
151127266Sluigi	    ;;
15284377Sluigi    esac
15372770Sluigi
15472770Sluigi    set -e
15572770Sluigi
15684377Sluigi    trap fail 2
15784377Sluigi    #trap fail 3
15884377Sluigi    #trap fail 6
15984377Sluigi    trap fail 15
16072770Sluigi}
16172770Sluigi
162190411Sluigi# use the new build infrastructure to create libraries
163190411Sluigi# and also to build a specific target
164190411Sluigicreate_includes_and_libraries2() { # opt_dir opt_target
165155136Sluigi    local no
166229532Sluigi    log "create_includes_and_libraries2() for ${SRC} $1"
167155136Sluigi    if [ ${OSVERSION} -ge 600000 ] ; then
168201059Sluigi	no="-DNO_CLEAN -DNO_PROFILE -DNO_GAMES -DNO_LIBC_R" # WITHOUT_CDDL=1"
169239738Sluigi	no="$no -DWITHOUT_CLANG -DMALLOC_PRODUCTION"
170155136Sluigi    else
171155136Sluigi	no="-DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R"
172155136Sluigi    fi
17399946Sluigi    ( cd ${SRC};
174155136Sluigi    # make -DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R -DPICOBSD buildworld
175190411Sluigi    if [ -d "$1" ] ; then
176218359Sluigi	cd $1 ; ${BINMAKE} ${o_par} $2	# specific target, e.g. ld-elf.so
177190411Sluigi    else
178229532Sluigi	MAKEOBJDIRPREFIX=${l_objtree}
179229532Sluigi	export MAKEOBJDIRPREFIX
180229511Sluigi	# export WITH_RESCUE=yes	# build crunchide
181229511Sluigi	# ${BINMAKE} ${o_par} _+_= $no toolchain _includes _libraries
182229511Sluigi	(
183229511Sluigi	    # eval export `cd ${SRC}; ${BINMAKE} -f Makefile.inc1 -V BMAKEENV`
184229511Sluigi	    eval "export XMAKE=\"`cd ${SRC}; make -f Makefile -V XMAKE`\""
185229511Sluigi	    ${BINMAKE} ${o_par} _+_= $no toolchain
186229511Sluigi	)
187229511Sluigi        eval export `cd ${SRC}; ${BINMAKE} -f Makefile.inc1 -V WMAKEENV`
188229511Sluigi	${BINMAKE} ${o_par} _+_= $no _includes _libraries
189229511Sluigi	[ ${o_arch} != `uname -m` ] && \
190229511Sluigi	    (cd ${l_objtree}; ln -s . ${o_arch}.${o_arch} || true )
191190411Sluigi    fi
19299946Sluigi    )
19399946Sluigi}
19499946Sluigi
195173602Sluigi# entry for 4.x and earlier trees
19684377Sluigicreate_includes_and_libraries() {
197127266Sluigi    local e i
198127266Sluigi
19984377Sluigi    log "create_includes_and_libraries() for ${SRC}"
20084377Sluigi    # Optionally creates include directory and libraries.
201190378Sluigi    mkdir -p ${l_usrtree}/include	# the include directory...
20284377Sluigi    mkdir -p ${l_usrtree}/share/misc	# a few things go here
20384377Sluigi    mkdir -p ${l_usrtree}/lib		# libraries
20484377Sluigi    mkdir -p ${l_usrtree}/sbin		# some binaries
205127266Sluigi    # override variables for ownershiip and destinations
206127266Sluigi    # BINOWN:BINGRP are also used for include files
207127266Sluigi    (cd ${SRC}; \
208127266Sluigi	BINOWN=`id -un` BINGRP=`id -gn` \
209127266Sluigi	DESTDIR=${l_usrtree}/.. \
210127266Sluigi	make -m ${SRC}/share/mk includes ) || fail $? includes
21192964Sru    # Pick up the correct headers for libraries.
21292964Sru    CFLAGS="-nostdinc -I${l_usrtree}/include" ; export CFLAGS
21384377Sluigi
21484377Sluigi    (cd ${SRC}
21584377Sluigi	# $e is the invocation of make with correct environment
216155136Sluigi	# XXX check the NO* options below, maybe system dependent.
21784377Sluigi	e="MAKEOBJDIRPREFIX=${l_objtree}/picobsd/libraries \
218127266Sluigi	    BINOWN=`id -un` BINGRP=`id -gn` \
219127266Sluigi	    DESTDIR=${l_usrtree}/.. \
22086876Sluigi	    make -m ${SRC}/share/mk \
221155136Sluigi		-DNOHTML -DNOINFO -DNOMAN -DNOSHARE -DNOFSCHG "
22292063Sluigi	log "do a 'make obj' in a few places."
22392063Sluigi	# This is very version-specific... The following works for 5.0
224158687Sphk	for i in lib secure/lib gnu/lib \
22584377Sluigi		gnu/usr.bin/perl usr.bin/lex usr.sbin/config ; do
22684377Sluigi	    (cd ${i}; eval $e obj)
22784377Sluigi	done
22892063Sluigi	log "now make the static libraries"
229155136Sluigi	eval $e -DNOPROFILE -DNOPIC libraries
23084377Sluigi	(cd ${SRC}/usr.sbin/config
23184377Sluigi	eval $e		# build binary
23284377Sluigi	eval $e	install	# install it
23384377Sluigi	)
23484377Sluigi    ) || fail $? "libraries"
23584377Sluigi    log "Libraries done"
23672770Sluigi}
23772770Sluigi
238190378Sluigi# set_type <the_type> [the_site] looks in user or system directories
239190378Sluigi# for the directory named as the first argument, reads the configuration
240190378Sluigi# files and sets variables according to the config.
241190378Sluigi# Also sets MY_TREE and BUILDDIR and SITE
24272770Sluigi
243190378Sluigiset_type() {	# the_type the_site
244127266Sluigi    local a i
24584377Sluigi
246173602Sluigi    log "set_type() : Type '$1' site '$2'"
24784377Sluigi    THETYPE=$1
24884377Sluigi    SITE=$2
24972770Sluigi    a=$1
250173602Sluigi    name=""	# clear in case of errors
25184377Sluigi    for i in ${c_startdir}/${a} ${PICO_TREE}/${a} ; do
25278494Sluigi	log "set_type: checking $i"
253229511Sluigi	[ -d $i -a -f $i/crunch.conf ] || continue
254229511Sluigi	# look for a kernel config file, privilege arch-specific
255229511Sluigi	l_kernconf=$i/PICOBSD.${o_arch}
256229511Sluigi	[ -f $l_kernconf ] || l_kernconf=$i/PICOBSD
257229511Sluigi	[ -f $l_kernconf ] || continue
258229511Sluigi	set -- `cat $l_kernconf | \
25972770Sluigi	    awk '/^#PicoBSD/ {print $2, $3, $4, $5, $6}'`
260173602Sluigi	[ x"$1" != "x" ] || continue
261229511Sluigi	MFS_SIZE=$1
262173602Sluigi	name=`(cd $i ; pwd) `
263173602Sluigi	name=`basename $name`
264173602Sluigi	MY_TREE=$i
265229511Sluigi	BUILDDIR=${c_startdir}/build_dir-${name}-${o_arch}
266173602Sluigi	log "Matching file $name in $i"
267173602Sluigi	return ;
26872770Sluigi    done
269173602Sluigi    logverbose "Type $a NOT FOUND"
27072770Sluigi}
27172770Sluigi
27272770Sluigiclean_tree() {
27384377Sluigi    log "clean_tree()"
274190411Sluigi    if [ -z "${name}" ] ; then
27584377Sluigi	echo "---> Wrong floppy type"
27672770Sluigi	exit 3
27772770Sluigi    fi
27872770Sluigi    rm -rf ${BUILDDIR}
27972770Sluigi}
28072770Sluigi
28172770Sluigi# prepare a message to be printed in the dialog menus.
28272770Sluigiset_msgs() {		# OK
28384377Sluigi    log "set_msgs()"
28484377Sluigi
28572770Sluigi    MSG1="Type: ${THETYPE} name $name"
28672770Sluigi
28772770Sluigi    MSG="PicoBSD build -- Current parameters:\n\n\t1.  ${MSG1}\n\
28872770Sluigi\t2.  MFS size: ${MFS_SIZE} kB\n\
28972770Sluigi\t3.  Site-info: ${SITE}\n\t4.  Full-path: ${MY_TREE}\n"
29072770Sluigi}
29172770Sluigi
292194631Sluigi# Main build procedure. Builds both the disk image and the ISO
29372770Sluigibuild_image() {
29484377Sluigi    log "build_image() <${name}>"
295190411Sluigi    [ -n "${name}" ] || fail $? bad_type
29672770Sluigi    clear
29772770Sluigi    set_msgs
29884377Sluigi    printf "${MSG}---> We'll use the sources living in ${SRC}\n\n"
29972770Sluigi
30084377Sluigi    # read config variables from a global and then a type-specific file
30184377Sluigi    # basically STAND_LINKS and MY_DEVS, but can also override other
30284377Sluigi    # variables.
30384377Sluigi    # 
30484377Sluigi    . ${PICO_TREE}/build/config
305190411Sluigi    [ -f "${MY_TREE}/config" ]		&& . ${MY_TREE}/config
306190411Sluigi    [ -f "${o_additional_config}" ]	&& . ${o_additional_config}
30784377Sluigi
30884377Sluigi    # location of the object directory
30984377Sluigi    PICO_OBJ=${l_objtree}/picobsd/${THETYPE}
31084377Sluigi    log "PICO_OBJ is ${PICO_OBJ}"
31184377Sluigi
31284377Sluigi    # create build directory and subtree
31384377Sluigi    mkdir -p ${BUILDDIR}/crunch
31484377Sluigi    # remove any old stuff
31584377Sluigi    rm -f ${BUILDDIR}/kernel.gz ${BUILDDIR}/${c_fs}
31684377Sluigi    # invoke commands to build a kernel
31772770Sluigi    do_kernel
31884377Sluigi    # fill a subdirectory with things that go into the floppy
31984377Sluigi    # (mostly /etc and similar stuff)
32084377Sluigi    populate_floppy_fs
32184377Sluigi    # populate it and produce a file with the MFS image
32284377Sluigi    populate_mfs_tree		# things which go into mfs
32384377Sluigi    # create, mount and fill a filesystem with floppy image
32472770Sluigi    fill_floppy_image # copies everything into the floppy
32572770Sluigi}
32672770Sluigi
32772770Sluigi# Set build parameters interactively
32872770Sluigi
32972770Sluigimain_dialog() {
33084377Sluigi  local ans i l
33184377Sluigi
33284377Sluigi  log "main_dialog()"
333190411Sluigi  while true ; do
33472770Sluigi    set_msgs
33584377Sluigi    rm ${c_reply}
33684377Sluigi    dialog --menu "PicoBSD build menu -- (29 sep 2001)" 19 70 12 \
33772770Sluigi	N "--> READY, build it <---" \
33872770Sluigi	T "${MSG1}" \
33972770Sluigi	K "edit Kernel config file" \
34072770Sluigi	E "Edit crunch.conf file" \
34172770Sluigi	S "MFS Size: ${MFS_SIZE}kB" \
34284377Sluigi	F "Floppy size: ${fd_size}kB" \
34372770Sluigi	$ "Site-info: ${SITE}" \
34472770Sluigi	Q "Quit" \
34584377Sluigi	2> ${c_reply}
34684377Sluigi    ans=`cat ${c_reply}`
34784377Sluigi    rm ${c_reply}
34872770Sluigi    case ${ans} in
34972770Sluigi    T)
35072770Sluigi	l=""
35184377Sluigi	for i in ${c_startdir} ${c_startdir}/* ${PICO_TREE}/* ; do
35272770Sluigi	    if [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ]; then
35372770Sluigi		l="$l `basename $i` `basename $i`"
35472770Sluigi	    fi
35572770Sluigi	done
35672770Sluigi	log $l
35790659Sluigi	{ dialog --menu "Setup the type of configuration" 12 70 5 $l \
35890659Sluigi		2> ${c_reply} && set_type "`cat ${c_reply}`" ${SITE} ; } || true
35972770Sluigi	;;
36072770Sluigi
36172770Sluigi    K) ${EDITOR} ${MY_TREE}/PICOBSD ;;
36272770Sluigi
36372770Sluigi    E) ${EDITOR} ${MY_TREE}/crunch.conf ;;
36472770Sluigi
36572770Sluigi    S)
36690659Sluigi	{ dialog --title "MFS Size setup" --inputbox \
36772770Sluigi"MFS size depends on what you need to put on the MFS image. Typically \
36872770Sluigiranges between 820kB (for very small bridge/router images) to \
36972770Sluigias much as 2500kB kB for a densely packed image. \
37072770SluigiKeep in mind that this memory is \
37172770Sluigitotally lost to other programs. Usually you want to keep \
37284377Sluigithis as small as possible. " 10 70 2> ${c_reply} \
37390659Sluigi	&& MFS_SIZE=`cat ${c_reply}` ; } || true
37472770Sluigi	;;
37572770Sluigi
37672770Sluigi    \$)
37790659Sluigi	{ dialog --title "Site info setup" --inputbox \
37872770Sluigi	"Please enter the full path to the directory \
37972770Sluigi	containing site-specific setup. \
38072770Sluigi	This directory tree must contain files that replace \
38172770Sluigi	standard ones in floppy.tree/ and mfs.tree/ . " \
38290659Sluigi	10 70 2> ${c_reply} && SITE=`cat ${c_reply}` ; } || true
38372770Sluigi	;;
38472770Sluigi
38572770Sluigi    F)
38691846Sluigi	{ dialog --menu "Set floppy size" 15 70 4 \
38784377Sluigi	    1440 "1.44MB" 1720 "1.72MB" 2880 "2.88MB" 4096 "4MB" \
38891846Sluigi		 2> ${c_reply} && fd_size=`cat ${c_reply}` ; } || true
38972770Sluigi	;;
39072770Sluigi
39172770Sluigi    N) break 2
39272770Sluigi	;;
39372770Sluigi
39472770Sluigi    Q) exit 0 ;;
39572770Sluigi
39672770Sluigi    *) echo "Unknown option \"${ans}\". Try again."
39772770Sluigi	sleep 2
39872770Sluigi	clear
39972770Sluigi	;;
40072770Sluigi    esac
40172770Sluigi  done
40272770Sluigi}
40372770Sluigi
40472770Sluigi# Call the build procedure
40572770Sluigi# Install image
40672770Sluigido_install() {
40784377Sluigi    log "do_install()"
40884377Sluigi
40985833Sluigi    if [ "${o_interactive}" = "NO" ] ; then
41085833Sluigi	echo "+++ Build completed +++"
411155136Sluigi	cat .build.reply || true
41285833Sluigi	return
41385833Sluigi    fi
41482747Sluigi    dialog --title "Build ${THETYPE} completed" --inputbox \
41572770Sluigi"\nThe build process was completed successfuly.\n\
41672770Sluigi`cat .build.reply` \n\n\
41772770SluigiNow we are going to install the image on the floppy.\n\
41872770SluigiPlease insert a blank floppy in /dev/fd0.\\n
41972770SluigiWARNING: the contents of the floppy will be permanently erased!\n\
42072770Sluigi\n\
42172770SluigiYour options:\n\
42272770Sluigi	* ^C or [Cancel] to abort,\n\
42384377Sluigi	* Enter to install ${c_img},\n\
42484377Sluigi" 20 80 2> ${c_reply}
42572770Sluigi    if [ "$?" = "0" ]; then
42684377Sluigi	echo "Writing ${c_img}..."
42784377Sluigi	dd if=${BUILDDIR}/${c_img} of=/dev/fd0.${fd_size}
42872770Sluigi    else
42984377Sluigi	echo "Ok, the image is in ${c_img}"
43072770Sluigi    fi
43172770Sluigi    echo "Done."
43272770Sluigi}
43372770Sluigi
43472770Sluigi
43572770Sluigi#-------------------------------------------------------------------
43672770Sluigi
437173602Sluigi# invoke the picobsd Makefile to compile the kernel.
438173602Sluigi# if MODULES is set (value is irrelevant) the makefile will build modules.
43972770Sluigido_kernel() {		# OK
44084377Sluigi    log "do_kernel() Preparing kernel \"$name\" in $MY_TREE"
44199946Sluigi    (cd $MY_TREE; export name SRC BUILDDIR # used in this makefile ;
44299946Sluigi	# export CONFIG
443227878Sluigi	export WARNS CWARNFLAGS
444173602Sluigi	[ "${o_do_modules}" = "yes" ] && export MODULES=""
445229511Sluigi	${BINMAKE} ${o_par} KERNCONF=${l_kernconf}	\
446229511Sluigi		-v -f ${PICO_TREE}/build/Makefile.conf ) || \
447229511Sluigi	    fail $? missing_kernel
448244642Sluigi#		-DWITHOUT_CLANG_IS_CC			\
449244642Sluigi
45072770Sluigi}
45172770Sluigi
45284377Sluigi# Populate the variable part of the floppy filesystem. Must be done before
45384377Sluigi# the MFS because its content might need to be copied there as well.
45472770Sluigi#
45584377Sluigi# This involves fetching files from three subtrees, in this order:
45672770Sluigi#
45784377Sluigi#  1. a standard one, from which type-specific files are excluded;
45872770Sluigi#  2. a type-specific one;
45972770Sluigi#  3. a site-specific one.
46072770Sluigi#
46172770Sluigi# Files are first copied to a local tree and then compressed.
46272770Sluigi
46372770Sluigipopulate_floppy_fs() {		# OK
46483692Sluigi    local dst excl srcdir
46572770Sluigi
46684377Sluigi    log "populate_floppy_fs()"
46772770Sluigi    dst=${BUILDDIR}/floppy.tree
46884377Sluigi    log "pwd=`pwd` Populating floppy filesystem..."
46972770Sluigi
470188835Sluigi    rm -rf ${dst} || true	# clean relics from old compilations.
471188835Sluigi    mkdir ${dst}		# create a clean tree
47272770Sluigi
473188835Sluigi    # compute exclude list for generic tree
47472770Sluigi    excl=${MY_TREE}/floppy.tree.exclude
47572770Sluigi    if [ -f ${excl} ] ; then
476173597Sluigi	log "Files excluded from generic tree: `echo;cat ${excl}`"
47772770Sluigi	excl="--exclude-from ${excl}"
47872770Sluigi    else
47972770Sluigi	excl=""
48072770Sluigi    fi
481188835Sluigi    # copy from the floppy trees into the destination
482188835Sluigi    for FLOPPY_TREE in ${PICO_TREE}/floppy.tree ${MY_TREE}/floppy.tree \
483188835Sluigi		${MY_TREE}/floppy.tree.${SITE} ; do
484188835Sluigi	if [ -d ${FLOPPY_TREE} ] ; then
485188835Sluigi	    (cd ${FLOPPY_TREE} ; tar -cf - --exclude CVS \
486188835Sluigi		    --exclude .svn ${excl} . ) | \
48784377Sluigi		(cd ${dst} ; tar x${o_tarv}f - )
488188835Sluigi	    log "Copied from ${FLOPPY_TREE}"
489188835Sluigi	fi
490188835Sluigi	excl="" # reset the exclude list.
491188835Sluigi    done
49272770Sluigi
493188835Sluigi    # add local manipulation
494188835Sluigi    if [ -f ${MY_TREE}/buildtree.mk ] ; then
495188835Sluigi	log "building local floppy tree"
496188835Sluigi	${BINMAKE} -C ${dst} -f ${MY_TREE}/buildtree.mk floppy.tree
49772770Sluigi    fi
498188835Sluigi 
499188835Sluigi    # compress the files in etc/, just in case
500188835Sluigi    # XXX this should be done in the makefile.
50172770Sluigi    # gzip returns an error if it fails to compress some file
50284377Sluigi    (cd $dst ; gzip -9 etc/*
50384377Sluigi	    log "Compressed files in etc/ `echo; ls -l etc`"
50472770Sluigi    ) || true
50572770Sluigi}
50672770Sluigi
507189978Sluigi# Copy the specified files to the destination filesystem.
508189978Sluigi# Each file is specified as a pair "src dst", dst is assumed to be
509189978Sluigi# a directory (and created with mkdir -p) if it has a trailing /
510189978Sluigi# Be careful to escape metacharacters.
511189978Sluigi# You can use ${CROSS} to point to the root of the cross build
512189978Sluigi# (remember that it might be incomplete)
513189978Sluigi
514189978Sluigido_copyfiles() {	# rootdir varname
515189978Sluigi	log Copy files to $1
516189978Sluigi	local root=$1
517189978Sluigi	local srcs dst
518189978Sluigi	local CROSS=${_SHLIBDIRPREFIX}
519189978Sluigi	eval set "\${${2}}"
520189978Sluigi        srcs=""
521189978Sluigi	for dst in $* ; do
522190411Sluigi		[ -z "$srcs" ] && srcs=$dst && continue
523189978Sluigi		eval srcs="$srcs"	# expand wildcard and vars
524189978Sluigi		case x"$dst" in
525189978Sluigi		*/ )	mkdir -p ${root}/${dst} ;;
526189978Sluigi		# * )	mkdir -p `dirname ${root}/${dst}` ;;
527189978Sluigi		esac
528189978Sluigi		cp -p ${srcs} ${root}/${dst} || true
529189978Sluigi		srcs=""
530189978Sluigi        done
531189978Sluigi}
532189978Sluigi
533190411Sluigi# do_links is a helper function to create links between programs
534190411Sluigi# in stand/
535190411Sluigi# This is done reading the names and destination from variable
536190411Sluigi# links in a config file, in the format
537190411Sluigi#	: dst names
538190411Sluigi
539190411Sluigido_links() {	# rootdir varname
540190411Sluigi	local root=$1
541190411Sluigi	local l i dst
542190411Sluigi	eval l="\${${2}}"
543190411Sluigi        dst=""
544190411Sluigi	log "Create links for ${l}"
545190411Sluigi	(cd ${root}/stand
546190411Sluigi	for i in $l ; do
547190411Sluigi	    if [ "$dst" = ":" -o "$i" = ":" ] ; then
548190411Sluigi		dst=$i
549190411Sluigi	    elif [ -n "${dst}" ] ; then
550190411Sluigi		ln -s ${dst} ${i}
551190411Sluigi	    fi
552190411Sluigi	done
553190411Sluigi	)
554190411Sluigi}
555190411Sluigi
556190383Sluigi# find_progs is a helper function to locate the named programs
557190411Sluigi# or libraries in ${o_objdir} or ${_SHLIBDIRPREFIX},
558190411Sluigi# and return the full pathnames.
559229532Sluigi# Called as "find_progs [[-L libpath] [-P binpath]] prog1 prog2 ... "
560201072Sluigi# On return it sets ${u_progs} to the list of programs, and ${u_libs}
561190383Sluigi# to the list of shared libraries used.
562201072Sluigi# 
563201072Sluigi# '-L path' can be used to specify a search path for libraries
564201072Sluigi#    (which searches in $path/lib:$path/usr/lib:$path/usr/local/lib
565201072Sluigi# '-P binpath' can be used to specify a search path for programs
566201072Sluigi#    (which searches in a lot of places in the subtree)
567201072Sluigi# -L must be the first, followed by -P
568190383Sluigi#
569201072Sluigi# You can use it e.g. in a local confign file by writing
570190383Sluigi#
571190383Sluigi#  do_copyfiles_user() {
572190383Sluigi#	local dst=$1
573190383Sluigi#	find_progs nvi sed less grep
574190383Sluigi#	cp -p ${u_progs} ${dst}/bin
575190383Sluigi#	cp -p ${u_libs} ${dst}/lib
576190383Sluigi#	mkdir -p ${dst}/libexec
577190383Sluigi#	find_progs ld-elf.so.1
578201072Sluigi#	cp -p ${u_progs} ${dst}/libexec # ignore errors
579190383Sluigi#  }
580190383Sluigi
581190383Sluigifind_progs() {	# programs
582229532Sluigi	local pass i old_libs="" tmp o=""
583201072Sluigi	if [ x"$1" = "x-L" -a -d "$2" ] ; then # set lib search path
584229532Sluigi		o="-P $2"; shift; shift
585201072Sluigi	fi
586229532Sluigi	# Result returned in global variables
587229532Sluigi	u_libs="" ; u_progs="`find_progs_helper $*`"
588190383Sluigi	[ -z "${u_progs}" ] && return 1	# not found, error
589229532Sluigi	# use objdump to find libraries. Iterate to fetch recursive
590229532Sluigi	# dependencies.
591229532Sluigi	tmp="${u_progs}" ; pass=1
592229532Sluigi	while [ $pass -lt 10 ] ; do
593229532Sluigi		pass=$(($pass + 1))
594229532Sluigi		i="`objdump -x ${tmp} | \
595229532Sluigi			awk '$1 == "NEEDED" { print $2 }' | sort | uniq`"
596229532Sluigi		if [ "$old_libs" = "$i" ] ; then
597229532Sluigi			log "libraries for: $my_progs ($u_progs) are ($i) $u_libs"
598229532Sluigi			log "--- done find_progs ---"
599229532Sluigi			return 0
600229532Sluigi		else
601229532Sluigi			# logverbose "old--- $old_libs --- new +++ $i +++"
602229532Sluigi		fi
603229532Sluigi		u_libs="`find_progs_helper $o $i`"
604229532Sluigi		old_libs="$i"
605229532Sluigi		tmp="$tmp $u_libs"
606229532Sluigi	done
607229532Sluigi	log "WARNING: Too many passes, giving up"
608190383Sluigi}
609190383Sluigi
610190383Sluigifind_progs_helper() {	# programs
611201072Sluigi	local dir=${o_objdir:-${_SHLIBDIRPREFIX}/..}
612201072Sluigi	local ldir=""
613201072Sluigi	if [ x"$1" = "x-P" -a -d "$2" ] ; then # set path
614201072Sluigi		ldir=$2; shift; shift
615201072Sluigi	fi
616190383Sluigi	local progs="$*"
617201072Sluigi	local subdirs=". local/bin local/sbin local/lib local/libexec \
618201072Sluigi		bin sbin usr.bin usr.sbin libexec lib \
619190383Sluigi		gnu/usr.bin gnu/lib \
620190383Sluigi		secure/usr.bin secure/usr.sbin secure/libexec secure/lib"
621201072Sluigi	local names=""	# files to search
622201072Sluigi	local o=""
623201072Sluigi	local i
624190383Sluigi	for i in $progs ; do
625201072Sluigi		# full pathnames are just listed
626190411Sluigi		[ -f "$i" ] && echo $i && continue
627190383Sluigi		names="${names} ${o} -name $i"
628190383Sluigi		o="-o"
629190383Sluigi	done
630190411Sluigi	[ -z "${names}" ] && return 0
631201072Sluigi	local places=""				# places to search
632190383Sluigi	for i in $subdirs ; do
633201072Sluigi		[ -d "${dir}/${i}" ] && places="${places} ${dir}/${i}"
634190383Sluigi	done
635201072Sluigi	if [ -n "${ldir}" ] ; then
636201072Sluigi	    for i in $subdirs ; do
637201072Sluigi		[ -d "${ldir}/${i}" ] && places="${places} ${ldir}/${i}"
638201072Sluigi	    done
639201072Sluigi	fi
640229511Sluigi	for i in $progs ; do
641229511Sluigi		# full pathnames are just listed
642229511Sluigi		[ -f "$i" ] && echo $i && continue
643229511Sluigi		find ${places} -maxdepth 3 -type f -name ${i} | head -1
644229511Sluigi	done
645201072Sluigi	# use maxdepth 3 because some libs are way down
646190383Sluigi}
647190411Sluigi
64872770Sluigi# Populate the memory filesystem with binaries and non-variable
64972770Sluigi# configuration files.
65072770Sluigi# First do an mtree pass, then create directory links and device entries,
65172770Sluigi# then run crunchgen etc. to build the binary and create links.
65272770Sluigi# Then copy the specific/generic mfs_tree.
65372770Sluigi# Finally, if required, make a copy of the floppy.tree onto /fd
65472770Sluigi
65584377Sluigipopulate_mfs_tree() {
656189978Sluigi    local i j a dst MFS_TREE
65772770Sluigi
65884377Sluigi    log "populate_mfs_tree()"
659155136Sluigi    dst=${BUILDDIR}/mfs.tree
660188835Sluigi    rm -rf ${dst} || true	# clean relics from old compilations.
661188835Sluigi    mkdir ${dst}		# create a fresh tree
66272770Sluigi
66384377Sluigi    log "pwd=`pwd`, Populating MFS tree..."
66484377Sluigi
66584377Sluigi    # use type-specific mfs.mtree, default to generic one.
66684377Sluigi    a=${MY_TREE}/mfs.mtree
66784377Sluigi    [ -f ${a} ] || a=${PICO_TREE}/build/mfs.mtree
66884377Sluigi    log "Running mtree using $a..."
66984377Sluigi    mtree -deU -f $a -p ${dst} > /dev/null || fail $? mtree
67084377Sluigi
671189978Sluigi    # Create symlinks using relative pathnames, so it is possible
672189978Sluigi    # to follow them also when building the image.
673189978Sluigi    # Note that names in STAND_LINKS should not have a leading /
67472770Sluigi    for i in ${STAND_LINKS}; do
675189978Sluigi	j=`echo $i | sed -E 's:^[^/]+::;s:/[^/]+:../:g'`
676189978Sluigi	ln -s ${j}stand ${dst}/$i
67772770Sluigi    done
678189978Sluigi    ln -s ../../dev/null ${dst}/var/run/log
679189978Sluigi    ln -s ../../../etc/termcap ${dst}/usr/share/misc/termcap
68072770Sluigi
681188835Sluigi    ### now build the crunched binaries ###
68272770Sluigi    (
68372770Sluigi    cd ${BUILDDIR}/crunch
68484377Sluigi    log "Making and installing crunch1 from `pwd` src ${SRC}..."
68572770Sluigi    a=${BUILDDIR}/crunch1.conf
68678541Sluigi    ( export BUILDDIR SRC MY_TREE PICO_OBJ ;
687173597Sluigi	${BINMAKE} \
68886876Sluigi		-v -f ${PICO_TREE}/build/Makefile.conf ${BUILDDIR}/crunch.mk )
68984377Sluigi    log "Libs are ${LIBS} "
69099946Sluigi    export SRC # used by crunch.mk
69199946Sluigi    # export LIBS CFLAGS
69272770Sluigi    log "Now make -f crunch.mk"
693173597Sluigi    ${BINMAKE} ${o_makeopts} -f ${BUILDDIR}/crunch.mk
69472770Sluigi    strip --remove-section=.note --remove-section=.comment crunch1
69584377Sluigi    mv crunch1 ${dst}/stand/crunch
69684377Sluigi    chmod 555 ${dst}/stand/crunch
69784377Sluigi    log "Making links for binaries..."
69872770Sluigi    for i in `crunchgen -l $a` ; do
69984377Sluigi	ln ${dst}/stand/crunch ${dst}/stand/${i};
70072770Sluigi    done
70178541Sluigi    # rm $a # do not remove!
70272770Sluigi    ) || fail $? crunch
70372770Sluigi
70484377Sluigi    if [ -f ${dst}/stand/sshd ] ; then
70592063Sluigi	log "Setting up host key for sshd:"
70692063Sluigi	if [ -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key.gz ] ; then
70784627Sluigi	    log "Using existing host key"
70884627Sluigi	else
70992063Sluigi	    log "Generating new host key" 
710127266Sluigi	    ssh-keygen -t rsa1 -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key \
71192063Sluigi		 -N "" -C "root@picobsd"
71292063Sluigi	    gzip -9 ${BUILDDIR}/floppy.tree/etc/ssh_host_key* || true
71384627Sluigi	fi
71472770Sluigi    fi
71572770Sluigi
71691846Sluigi    log "Copy generic and site-specific MFS tree..."
71791846Sluigi    for MFS_TREE in ${PICO_TREE}/mfs_tree ${MY_TREE}/mfs_tree ; do
71891846Sluigi	if [ -d ${MFS_TREE} ] ; then
71991846Sluigi	    log "Copy ${MFS_TREE} ..."
720180012Sru	    (cd ${MFS_TREE} ; tar -cf - --exclude CVS --exclude .svn . ) | \
72192063Sluigi		    (cd ${dst} ; tar x${o_tarv}f - )
72291846Sluigi	fi
72391846Sluigi    done
72472770Sluigi
725188835Sluigi    if [ -f ${MY_TREE}/buildtree.mk ] ; then
726188835Sluigi	log "building local floppy tree"
727188835Sluigi	${BINMAKE} -C ${dst} -f ${MY_TREE}/buildtree.mk mfs.tree
728188835Sluigi    fi
729188835Sluigi
73084377Sluigi    if [ "${o_all_in_mfs}" = "yes" ]; then
73184377Sluigi	log "Copy generic floppy_tree into MFS..."
732188835Sluigi	# ignore failure in case the floppy is empty
733155136Sluigi	cp -Rp ${BUILDDIR}/floppy.tree/* ${dst}/fd || true
73472770Sluigi    fi
73584377Sluigi
736188835Sluigi    # 4.x compatibility - create device nodes
737190411Sluigi    if [ -n "${o_no_devfs}" ] ; then
73884377Sluigi	# create device entries using MAKEDEV
73984377Sluigi	(cd ${dst}/dev
740155136Sluigi	ln -s ${SRC}/etc/MAKEDEV ; chmod 555 MAKEDEV
741155136Sluigi	# log `pwd`
742155136Sluigi	sh ./MAKEDEV ${MY_DEVS}
74384377Sluigi	rm MAKEDEV
74484377Sluigi	)
74584377Sluigi    fi
746155136Sluigi    if [ "`id -u`" = "0" ] ; then
747155136Sluigi	log "Fixing permissions"
748155136Sluigi	(cd ${dst}; chown -R root . )
749155136Sluigi    fi
75084377Sluigi
751200301Sluigi    log "for a shared 'crunch' take libraries and dynamic loader as well"
752190411Sluigi    find_progs ${dst}/stand/crunch
753190411Sluigi    if [ -n "${u_libs}" ] ; then
754190411Sluigi	mkdir -p ${dst}/lib && cp -p ${u_libs} ${dst}/lib
755190411Sluigi	mkdir -p ${dst}/libexec
756190411Sluigi        create_includes_and_libraries2 libexec/rtld-elf
757190411Sluigi        find_progs ld-elf.so.1 && cp -p ${u_progs} ${dst}/libexec
758189978Sluigi    fi
759190411Sluigi
760190411Sluigi    [ -n "${copy_files}" ] && do_copyfiles ${dst} copy_files
761190378Sluigi    do_copyfiles_user ${dst} || true
762190411Sluigi    [ -n "${links}" ] && do_links ${dst} links
763190411Sluigi    strip ${dst}/libexec/* ${dst}/lib/* ${dst}/stand/* 2> /dev/null || true
764189978Sluigi
765189978Sluigi    # The 'import_files' mechanism is deprecated, as it requires
766189978Sluigi    # root permissions to follow the symlinks, and also does
767189978Sluigi    # not let you rename the entries.
76892853Sluigi    if [ -n "${import_files}" ] ; then
76992853Sluigi	log "importing ${import_files} into mfs"
77092853Sluigi	# We do it in a chroot environment on the target so
77192853Sluigi	# symlinks are followed correctly.
772188835Sluigi	# Make sure we have a statically linked tar there.
773188835Sluigi	mkdir -p ${dst}/rescue
774188835Sluigi	cp /rescue/tar ${dst}/rescue
77592853Sluigi	(cd ${l_usrtree}/.. ; tar cf - ${import_files} ) | \
776188835Sluigi	    (chroot ${dst} /rescue/tar xPf - )
777188835Sluigi	rm -rf ${dst}/rescue
77892853Sluigi    fi
77992853Sluigi
780189978Sluigi    # final step -- build the mfs image
781155136Sluigi    (cd ${BUILDDIR}
782155136Sluigi	# override the owner
783155136Sluigi	echo "/set uid=0 gid=0" > mtree.out
784188835Sluigi	mtree -ic -p ${dst} -k "" >> mtree.out
785155136Sluigi	log "mtre.out at ${BUILDDIR}/mtree.out"
786155136Sluigi	makefs -t ffs -o bsize=4096 -o fsize=512 \
787188835Sluigi		-s ${MFS_SIZE}k -f 1000 -F mtree.out ${c_fs} ${dst}
788155136Sluigi	ls -l ${c_fs} )
789155136Sluigi    log "done mfs image"
79072770Sluigi}
79172770Sluigi
79272770Sluigifinal_cleanup() {
79384377Sluigi    log "final_cleanup()"
79484377Sluigi    rm -rf ${c_mnt} ${c_reply} 2> /dev/null || true
79572770Sluigi}
79672770Sluigi
79772770Sluigi# fail errno errcode
79872770Sluigi# This function is used to trap errors and print msgs
79972770Sluigi#
80072770Sluigifail() {
80184377Sluigi    local errno errocode where
80284377Sluigi
80372770Sluigi    errno=$1
80472770Sluigi    errcode=$2
80584377Sluigi    where=$3
80684377Sluigi    echo "---> fail: Error <${errno}> error code <${errcode}> in <${where}>"
80784377Sluigi    case ${errcode} in
80872770Sluigi    mtree)
80984377Sluigi	echo "Error while making hierarchy in ${c_mnt}"
81072770Sluigi	;;
81172770Sluigi    crunch)
81272770Sluigi	echo "Error while building ${name}."
81372770Sluigi	;;
81472770Sluigi    missing_kernel)
81575880Sjoe	echo "Error: you must build PICOBSD${suffix} kernel first"
81672770Sluigi	;;
81782917Sluigi    includes)
81882917Sluigi	echo "Error: failed while making includes"
81982917Sluigi	;;
82082917Sluigi    libraries)
82182917Sluigi	echo "Error: failed while making libraries"
82282917Sluigi	;;
82384377Sluigi    bad_type)
82484377Sluigi	echo "Error: unknown floppy type ${name}"
82584377Sluigi	;;
82684377Sluigi    no_space)
82784377Sluigi	echo "Error: no space left on device (${where})"
82884377Sluigi	;;
82992853Sluigi    no_mfs)
83092853Sluigi	echo "Error: while writing MFS into the kernel."
83192853Sluigi	;;
83272770Sluigi    "")
83372770Sluigi	echo "User break"
83484377Sluigi	errcode="userbreak"
83572770Sluigi	;;
83672770Sluigi    *)
83772770Sluigi	echo "unknown error, maybe user break: $errno $errcode"
83872770Sluigi	;;
83972770Sluigi    esac
84072770Sluigi    echo "---> Aborting $0"
84172770Sluigi    # try to cleanup the vnode.
84272770Sluigi    final_cleanup
84372770Sluigi    exit 2
84472770Sluigi}
84572770Sluigi
84672770Sluigifill_floppy_image() {
847155136Sluigi    local blocks dst mfs_start mfs_end mfs_size img_size
84872770Sluigi
84984377Sluigi    log "fill_floppy_image()"
85084377Sluigi    dst=${c_mnt}	# where to create the image
85184377Sluigi
85284377Sluigi    log "Preparing ${fd_size}kB floppy filesystem..."
85384377Sluigi
854155136Sluigi    # correct blocks according to size.
855155136Sluigi    blocks=${fd_size};
85672770Sluigi    if [ "${blocks}" = "1720" ]; then
857155136Sluigi	blocks=1722
85872770Sluigi    elif [ "${blocks}" = "1480" ]; then
859155136Sluigi	blocks=1476
86072770Sluigi    fi
86172770Sluigi
86284377Sluigi    log "Labeling floppy image"
863155136Sluigi
864155136Sluigi    dst=${BUILDDIR}/image.tree
865155136Sluigi    rm -rf ${dst}
866155136Sluigi    mkdir -p ${dst}
86772770Sluigi    (
86872770Sluigi    cd ${BUILDDIR}
869155136Sluigi    set 0 0 # reset variables
87099946Sluigi    # $1 takes the offset of the MFS filesystem
87199946Sluigi    set `strings -at d kernel | grep "MFS Filesystem goes here"`
872155136Sluigi    mfs_start=$1
873155136Sluigi    set 0 0 # reset variables
874155136Sluigi    set `strings -at d kernel | grep "MFS Filesystem had better"`
875155136Sluigi    mfs_end=$1
876155136Sluigi    mfs_size="$((${mfs_end} - ${mfs_start}))"
877155136Sluigi    set -- `ls -l ${c_fs}`; imgsize="$5"
878155136Sluigi    if [ ${mfs_start} -gt 0 -a ${mfs_size} -ge ${imgsize} ] ; then
879155136Sluigi	mfs_ofs=$((${mfs_start} + 8192))
880155136Sluigi	log "Preload kernel with file ${c_fs} at ${mfs_ofs}"
881203877Sluigi	log "`ls -l ${c_fs}` to fit in ${mfs_size}"
882155136Sluigi	dd if=${c_fs} ibs=8192 iseek=1 of=kernel obs=${mfs_ofs} \
883188835Sluigi	    oseek=1 conv=notrunc # 2> /dev/null
884155136Sluigi    else
885155136Sluigi    	log "not loading mfs, size ${mfs_size} img ${imgsize}"
886155136Sluigi    fi
88784377Sluigi    log "Compress with kgzip and copy to floppy image"
88872770Sluigi
889229511Sluigi    mkdir -p  ${dst}/boot/kernel
890234983Sluigi    # XXX loader.conf does not work unless we also load the .4th files
891229511Sluigi    echo "hint.acpi.0.disabled=\"1\"" > ${dst}/boot/loader.conf
892229511Sluigi    echo "console=\"comconsole\"" >> ${dst}/boot/loader.conf
893229511Sluigi    cp -p /boot/loader ${dst}/boot/loader || fail $? no_space "copying bootloader"
894229511Sluigi    gzip -c kernel > ${dst}/boot/kernel/kernel.gz || fail $? no_space "copying kernel"
895229511Sluigi
89672770Sluigi    # now transfer the floppy tree. If it is already in mfs, dont bother.
89784377Sluigi    if [ "${o_all_in_mfs}" != "yes" ] ; then
898188835Sluigi	log "Now transfer floppy tree if not already in MFS image"
89984377Sluigi	cp -Rp floppy.tree/* ${dst} || \
90084377Sluigi		fail $? no_space "copying floppy tree"
90172770Sluigi    fi
90272770Sluigi    )
903188835Sluigi
904188835Sluigi    # add local manipulation to the image
905188835Sluigi    if [ -f ${MY_TREE}/buildtree.mk ] ; then
906188835Sluigi	${BINMAKE} -C ${dst} -f ${MY_TREE}/buildtree.mk image.tree
907188835Sluigi    fi
908188835Sluigi
909188835Sluigi    log "image used `du -s ${dst}` of ${blocks}k"
910194631Sluigi    if [ "${generate_iso}" = "YES" ]; then
911194631Sluigi	logverbose "generate_iso ${generate_iso}"
912194631Sluigi	# build_iso_image	# XXX not implemented yet
913194631Sluigi	(cd ${BUILDDIR}
914194631Sluigi	cp -p /boot/cdboot ${dst}/boot || fail $? no_space "copying cdboot"
915194631Sluigi	mkisofs -b boot/cdboot -no-emul-boot -J -r -ldots -l -L \
916194631Sluigi		-o ${c_iso} ${dst}
917194631Sluigi	)
918194631Sluigi    fi
919194631Sluigi
920155136Sluigi    (cd ${BUILDDIR}
921155136Sluigi    makefs -t ffs -o bsize=4096 -o fsize=512 \
922155136Sluigi	-s ${blocks}k -f 50 ${c_img} ${dst}
923190378Sluigi
924190378Sluigi    ${c_label} -w -f `pwd`/${c_img} auto # write in a label
925155136Sluigi    # copy partition c: into a: with some sed magic
926190378Sluigi    ${c_label} -f `pwd`/${c_img} | sed -e '/  c:/{p;s/c:/a:/;}' | \
927190378Sluigi	${c_label} -R -f `pwd`/${c_img} /dev/stdin
928190378Sluigi    ${c_label} -f `pwd`/${c_img}
929188835Sluigi
930155136Sluigi    ls -l ${c_img}
931190378Sluigi    ${c_label} -f `pwd`/${c_img}
932203877Sluigi    log "after disklabel"
933188835Sluigi    )
934188835Sluigi
935188835Sluigi    echo "BUILDDIR ${BUILDDIR}"
936188835Sluigi
937155136Sluigi    # dump the primary and secondary boot
938155136Sluigi    # XXX primary is 512 bytes
939155136Sluigi    dd if=${c_boot1} of=${BUILDDIR}/${c_img} conv=notrunc 2>/dev/null
940155136Sluigi    # XXX secondary starts after the 0x114 = dec 276 bytes of the label
941155136Sluigi    # so we skip 276 from the source, and 276+512=788 from dst
942155136Sluigi    # the old style blocks used 512 and 1024 respectively
94372770Sluigi
944229511Sluigi    dd if=${c_boot2} iseek=1 ibs=276 2> /dev/null | \
945155136Sluigi	dd of=${BUILDDIR}/${c_img} oseek=1 obs=788 conv=notrunc 2>/dev/null
946203877Sluigi    log "done disk image"
947155136Sluigi    # XXX (log "Fixing permissions"; cd ${dst}; chown -R root *)
948229511Sluigi    # leave build stuff if verbose
949229511Sluigi    [ ${o_verbose} -gt 0 ] && return
950229511Sluigi
951155136Sluigi    rm -rf ${BUILDDIR}/floppy.tree || true # cleanup
952155136Sluigi    # df -ik ${dst} | colrm 70 > .build.reply
95384377Sluigi    rm -rf ${dst}
954188835Sluigi    rm ${BUILDDIR}/${c_fs}
955188835Sluigi    # rm ${BUILDDIR}/kernel.gz
95672770Sluigi}
95772770Sluigi
95884377Sluigi# This function creates variables which depend on the source tree in use:
95999946Sluigi# SRC, l_usrtree, l_objtree
96084377Sluigi# Optionally creates libraries, includes and the like (for cross compiles,
96184377Sluigi# needs to be done once).
96284377Sluigi
96384377Sluigiset_build_parameters() {
96484377Sluigi    if [ "${SRC}" = "/usr/src" ] ; then
96584377Sluigi	l_usrtree=${USR:-/usr}
96684377Sluigi    else
96784377Sluigi	l_usrtree=${USR:-${SRC}/../usr}
96884093Sluigi    fi
969227878Sluigi    l_objtree=${l_usrtree}/obj-pico-${o_arch}
970215177Sluigi
97184377Sluigi    PICO_TREE=${PICO_TREE:-${SRC}/release/picobsd}
97299946Sluigi    set `grep "#define[\t ]__FreeBSD_version" ${SRC}/sys/sys/param.h`
97399946Sluigi    OSVERSION=$3
97499951Sluigi    log "OSVERSION is ${OSVERSION}"
975215177Sluigi    if [ ${OSVERSION} -ge 500035 ] ; then
976215177Sluigi	export MAKEOBJDIRPREFIX=${l_objtree}
977227878Sluigi	export TARGET_ARCH=${o_arch} TARGET=${o_arch}
978244642Sluigi	export WITHOUT_CLANG_IS_CC=1
979229511Sluigi	# XXX why change machine_arch ?
980229511Sluigi	#-- export MACHINE_ARCH=`uname -m` MACHINE=`uname -m`
981227878Sluigi	# export CWARNFLAGS="-Wextra -Wno-sign-compare -Wno-missing-field-initializers"
982215177Sluigi	eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V BINMAKE`\""
983215177Sluigi    fi
984215177Sluigi
98584377Sluigi    if [ "${o_init_src}" != "" ] ; then
98699946Sluigi	if [ ${OSVERSION} -lt 500035 ] ; then
98799946Sluigi	    create_includes_and_libraries
98899946Sluigi	else
98999946Sluigi	    create_includes_and_libraries2
99099946Sluigi	fi
991229511Sluigi    else
992229511Sluigi	eval export `cd ${SRC}; ${BINMAKE} -f Makefile.inc1 -V WMAKEENV`
99384093Sluigi    fi
99499946Sluigi    if [ ${OSVERSION} -lt 500035 ] ; then
99599946Sluigi	# Create the right LIBS and CFLAGS for further builds.
99699946Sluigi	# and build the config program
99799946Sluigi	LIBS="-L${l_usrtree}/lib"
99899946Sluigi	CFLAGS="-nostdinc -I${l_usrtree}/include"
99999946Sluigi	export LIBS CFLAGS
100099946Sluigi	CONFIG=${l_usrtree}/sbin/config
100199946Sluigi	export CONFIG
100299946Sluigi    fi
1003190383Sluigi
1004190383Sluigi    # if we have o_objdir, find where bin/ is
1005190383Sluigi    if [ ! -z "${o_objdir}" ] ; then
1006190383Sluigi	if [ -d ${o_objdir}/bin ] ; then
1007190383Sluigi	    # fine
1008190383Sluigi	elif [ -d "${o_objdir}${SRC}/bin" ] ; then
1009190383Sluigi	    o_objdir="${o_objdir}${SRC}"
1010190383Sluigi	    log "Changing objdir to ${o_objdir}"
1011190383Sluigi	else
1012190383Sluigi	    log "Cannot find objdir in ${o_objdir}, sorry"
1013190383Sluigi	    o_objdir=""
1014190383Sluigi	fi
1015190383Sluigi    fi
101684093Sluigi}
101784093Sluigi
101884377Sluigi#-------------------------------------------------------------------
101984377Sluigi# Main entry of the script. Initialize variables, parse command line
102084377Sluigi# arguments.
102184093Sluigi
1022218359Sluigi# o_par="-j 8"	# parallel make and other make options
1023218359Sluigi
102484377Sluigiset_defaults
1025188835Sluigiwhile [ true ]; do
1026190383Sluigi    log "Parsing $1"
102772770Sluigi    case $1 in
1028229511Sluigi    --par)
1029229511Sluigi	o_par="-j 8"
1030229511Sluigi	;;
1031229511Sluigi
103278494Sluigi    --src)	# set the source path instead of /usr/src
1033190383Sluigi	SRC=`realpath $2`
103484093Sluigi	shift
103578494Sluigi	;;
1036229511Sluigi
1037229511Sluigi    --init)	# run a partial buildworld on the source tree
103884377Sluigi	o_init_src="YES"
103984377Sluigi	;;
104082917Sluigi
1041229511Sluigi    --arch)	# override the target architecture
1042227878Sluigi	o_arch=$2
1043227878Sluigi	shift
1044227878Sluigi	;;
1045227878Sluigi
1046229511Sluigi    --floppy_size)	# image size
104784377Sluigi	fd_size=$2
104872770Sluigi	shift
104972770Sluigi	;;
105084377Sluigi
105184377Sluigi    --all_in_mfs)
105284377Sluigi	o_all_in_mfs="yes"
105384377Sluigi	;;
105484377Sluigi
105584377Sluigi    --no_all_in_mfs)
1056188835Sluigi	o_all_in_mfs="no"
105784377Sluigi	;;
105884377Sluigi
105985833Sluigi    --modules)	# also build kernel modules
106085833Sluigi	o_do_modules="yes"
106185833Sluigi	;;
1062229511Sluigi
106372770Sluigi    -n)
106484377Sluigi	o_interactive="NO"
106572770Sluigi	;;
106684377Sluigi
106784377Sluigi    -clear|-clean|-c) # clean
106884377Sluigi	o_clean="YES"
106984377Sluigi	o_interactive="NO"
107072770Sluigi	;;
107184377Sluigi
107284377Sluigi    -v) # need -v -v to wait for user input
107384377Sluigi	o_verbose=$((${o_verbose}+1))	# verbose level
107484377Sluigi	o_tarv="v"			# tar verbose flag
107584377Sluigi	o_makeopts="-d l" # be verbose
107672770Sluigi	;;
1077188835Sluigi
1078188835Sluigi    --iso) # generate iso image
1079188835Sluigi	generate_iso="YES"
1080188835Sluigi	;;
1081188835Sluigi
1082189978Sluigi    --cfg) # read additional config from this file
1083189978Sluigi	o_additional_config=`realpath $2`
1084189978Sluigi	shift
1085189978Sluigi	;;
1086189978Sluigi
1087190383Sluigi    --objdir)	# Place with results of a previous buildworld
1088190383Sluigi		# useful if you want to copy shared binaries and libs
1089190383Sluigi	o_objdir=`realpath $2`
1090190383Sluigi	shift
1091190383Sluigi	;;
1092190383Sluigi
109372770Sluigi    *)
1094188835Sluigi	break
109572770Sluigi	;;
109672770Sluigi
109772770Sluigi    esac
109872770Sluigi    shift
109972770Sluigidone
1100190378Sluigi
110184377Sluigiset_build_parameters	# things that depend on ${SRC}
1102188835Sluigiset_type $1 $2		# type and site, respectively
110372770Sluigi
1104173602Sluigi[ "${o_interactive}" != "NO" ] && main_dialog
1105173602Sluigi
110684377Sluigiif [ "${o_clean}" = "YES" ] ; then
110772770Sluigi    clean_tree
110872770Sluigielse
110972770Sluigi    build_image
111072770Sluigi    do_install
111172770Sluigifi
111272770Sluigifinal_cleanup
111372770Sluigiexit 0
1114