picobsd revision 173602
172770Sluigi#!/bin/sh - 272770Sluigi# 372770Sluigi# $FreeBSD: head/release/picobsd/build/picobsd 173602 2007-11-14 07:38:22Z luigi $ 4155136Sluigi# This file requires sysutils/makefs to run 572770Sluigi# 672770Sluigi# The new PicoBSD build script. Invoked as 772770Sluigi# 872770Sluigi# picobsd [options] floppy_type site_name 972770Sluigi# 1072770Sluigi# Where floppy_type is a directory where the picobsd config info 1172770Sluigi# is held, and ${floppy_type}/floppy.tree.${site_name} contains 1272770Sluigi# optional site-specific configuration. 1372770Sluigi# 1472770Sluigi# For Options, see the bottom of the file where the processing is 1578494Sluigi# done. The picobsd(8) manpage might be of some help, but code and docs 1678494Sluigi# tend to lose sync over time... 1772770Sluigi# 1872770Sluigi# This script depends on the following files: 1972770Sluigi# 2072770Sluigi# in ${PICO_TREE} : 2172770Sluigi# Makefile.conf Makefile used to build the kernel 2272770Sluigi# config shell variables, sourced here. 2372770Sluigi# mfs.mtree mtree config file 2472770Sluigi# 2572770Sluigi# floppy.tree/ files which go on the floppy 2672770Sluigi# mfs_tree/ files which go onto the mfs 2772770Sluigi# 2872770Sluigi# in ${MY_TREE} : 2972770Sluigi# PICOBSD kernel config file 3072770Sluigi# config shell variables, sourced here. 3172770Sluigi# crunch.conf crunchgen configuration 3272770Sluigi# floppy.tree.exclude files from floppy.tree/ which we do not need here. 3372770Sluigi# floppy.tree/ local additions to the floppy.tree 3472770Sluigi# floppy.tree.${site}/ same as above, site specific. 35122229Ssimokawa# mfs_tree/ local additions to the mfs_free 3672770Sluigi 3772770Sluigi# 3872770Sluigi#--- The main entry point is at the end. 3972770Sluigi# 4072770Sluigi 4184377Sluigi# There are two set of initialization. The first one (set_defaults) 4284377Sluigi# is done on entry to the script, and is used to set default values 4384377Sluigi# for all variables which do not depend on floppy type and source tree. 4484377Sluigi# 4584377Sluigi# The second set is done after command line parsing, e.g. 4684377Sluigi# to resolve dependencies on the source tree. 4784377Sluigi# 4884377Sluigi# Naming: 4984377Sluigi# + variables that control operation (e.g. verbosity) and are generally 5084377Sluigi# set from the command line have o_ ("option") as a name prefix 5184377Sluigi# 5284377Sluigi# + variables which contain pathnames and values that should not change 5384377Sluigi# have c_ ("constant") as a name prefix 5484377Sluigi# 5584377Sluigi# + variables exported to Makefiles and subshells are CAPITAL 5684377Sluigi# 5784377Sluigi# + variables local to the script are lowercase, possibly with 5884377Sluigi# an l_ ("local") prefix 5972770Sluigi 6084377Sluigi# SRC points to your FreeBSD source tree. 6184377Sluigi# l_usrtree points to the /usr subdir for the source tree. 6284377Sluigi# Normally /usr or ${SRC}/../usr 6384377Sluigi# l_objtree points to the obj tree. Normally ${l_usrtree}/obj-pico 6484377Sluigi# PICO_TREE is where standard picobsd stuff resides. 6584377Sluigi# Normally ${SRC}/release/picobsd 6684377Sluigi# You can set SRC with --src <directory> 6784377Sluigi# It is not recommended to override the other variables. 6872770Sluigi 6984377Sluigi# MY_TREE (set later) is where this floppy type resides. 7084377Sluigi# BUILDDIR is the build directory 7172770Sluigi 7284377Sluigi# set some default values for variables. 7384377Sluigi# needs to be done as the first thing in the script. 7472770Sluigi 7584377Sluigi# log something on stdout if verbose. 7684377Sluigio_verbose=0 # this needs to be here! 7784377Sluigilog() { 78173602Sluigi local foo 79173602Sluigi [ ${o_verbose} -gt 0 ] && printf "\n*** %s\n" "$*" 80173602Sluigi [ ${o_verbose} -gt 1 ] && read -p "=== Press enter to continue" foo 81173602Sluigi return 0 8284377Sluigi} 8383723Sjoe 8491846Sluigilogverbose() { 85127266Sluigi local foo 8691846Sluigi printf "\n*** %s\n" "$*" 8791846Sluigi read -p "=== Press enter to continue" foo 88173602Sluigi return 0 8991846Sluigi} 9091846Sluigi 9184377Sluigiset_defaults() { 9284377Sluigi # no way to use logging in this function, variable not set yet. 9372770Sluigi 9472770Sluigi # EDITOR is the editor you use 9584377Sluigi # fd_size floppy size in KB (default to 1440). You can use 1480, 9672770Sluigi # 1720, 2880, etc. but beware that only 1440 and 1480 will boot 9772770Sluigi # from 1.44M floppy drives (1480 will not work on vmware). 9872770Sluigi EDITOR=${EDITOR:-vi} 9984377Sluigi fd_size=${fd_size:-1440} 10072770Sluigi 10184377Sluigi o_all_in_mfs="yes" # put all files in mfs so you can boot and run 10284377Sluigi # the image via diskless boot. 10384377Sluigi o_clean="" # do not clean 10484377Sluigi o_interactive="" # default is interactive 10584377Sluigi o_verbose=0 # verbose level, 0 is silent 10684377Sluigi o_tarv="" # tar verbose flag, "" or "v" 10784377Sluigi o_init_src="" # non "" if we need to init libs and includes. 10884377Sluigi o_makeopts=${MAKEOPTS:--s} # make options, be silent by default 10984377Sluigi o_no_devfs=yes # we do not want devfs 11085833Sluigi o_do_modules="" # do not build modules 11172770Sluigi 11284377Sluigi SRC="/usr/src" # default location for sources 113155136Sluigi c_startdir=`pwd` # directory where we start 114155136Sluigi # used to lookup config and create BUILDDIR 11584377Sluigi 116155136Sluigi # XXX 6.x/7.x have a single /boot/boot block, which is the concatenation 117155136Sluigi # of the old two. For the time being, we keep these, but this should 118155136Sluigi # be fixed at some point. 119155136Sluigi 120155136Sluigi # blocks 121127266Sluigi c_boot1=/boot/boot1 # boot blocks (in case you want custom ones) 12284377Sluigi c_boot2=/boot/boot2 12384377Sluigi 12484377Sluigi c_reply=${c_reply:-`mktemp "/tmp/reply.XXXXXXXXXX"`} 125155136Sluigi # file where User replies will be put 12684377Sluigi c_mnt=`mktemp -d "/tmp/picobsd.XXXXXXXXXX"` 127155136Sluigi # mountpoint used to build memory filesystems 128155136Sluigi c_fs=fs.PICOBSD # filename used for the memory filesystem 129155136Sluigi c_img=picobsd.bin # filename used for the picobsd image 13084377Sluigi 13184377Sluigi # select the right memory disk name 13284377Sluigi case `uname -r` in 133155136Sluigi 7.*|6.*|5.*) 134155136Sluigi l_label="bsdlabel" 13584377Sluigi ;; 13684377Sluigi *) 137155136Sluigi l_label="disklabel" 138127266Sluigi ;; 13984377Sluigi esac 14072770Sluigi 14172770Sluigi set -e 14272770Sluigi 14384377Sluigi trap fail 2 14484377Sluigi #trap fail 3 14584377Sluigi #trap fail 6 14684377Sluigi trap fail 15 14772770Sluigi} 14872770Sluigi 14999946Sluigicreate_includes_and_libraries2() { 150155136Sluigi local no 15199946Sluigi log "create_includes_and_libraries2() for ${SRC}" 152155136Sluigi if [ ${OSVERSION} -ge 600000 ] ; then 153155136Sluigi no="-DNO_CLEAN -DNO_PROFILE -DNO_GAMES -DNO_LIBC_R" 154155136Sluigi else 155155136Sluigi no="-DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R" 156155136Sluigi fi 15799946Sluigi MAKEOBJDIRPREFIX=${l_objtree} 15899946Sluigi export MAKEOBJDIRPREFIX 15999946Sluigi ( cd ${SRC}; 160155136Sluigi # make -DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R -DPICOBSD buildworld 161155136Sluigi make _+_= $no toolchain 16299946Sluigi ) 16399946Sluigi} 16499946Sluigi 165173602Sluigi# entry for 4.x and earlier trees 16684377Sluigicreate_includes_and_libraries() { 167127266Sluigi local e i 168127266Sluigi 16984377Sluigi log "create_includes_and_libraries() for ${SRC}" 17084377Sluigi # Optionally creates include directory and libraries. 17184377Sluigi mkdir -p ${l_usrtree}/include # the include directory... 17284377Sluigi mkdir -p ${l_usrtree}/share/misc # a few things go here 17384377Sluigi mkdir -p ${l_usrtree}/lib # libraries 17484377Sluigi mkdir -p ${l_usrtree}/sbin # some binaries 175127266Sluigi # override variables for ownershiip and destinations 176127266Sluigi # BINOWN:BINGRP are also used for include files 177127266Sluigi (cd ${SRC}; \ 178127266Sluigi BINOWN=`id -un` BINGRP=`id -gn` \ 179127266Sluigi DESTDIR=${l_usrtree}/.. \ 180127266Sluigi make -m ${SRC}/share/mk includes ) || fail $? includes 18192964Sru # Pick up the correct headers for libraries. 18292964Sru CFLAGS="-nostdinc -I${l_usrtree}/include" ; export CFLAGS 18384377Sluigi 18484377Sluigi (cd ${SRC} 18584377Sluigi # $e is the invocation of make with correct environment 186155136Sluigi # XXX check the NO* options below, maybe system dependent. 18784377Sluigi e="MAKEOBJDIRPREFIX=${l_objtree}/picobsd/libraries \ 188127266Sluigi BINOWN=`id -un` BINGRP=`id -gn` \ 189127266Sluigi DESTDIR=${l_usrtree}/.. \ 19086876Sluigi make -m ${SRC}/share/mk \ 191155136Sluigi -DNOHTML -DNOINFO -DNOMAN -DNOSHARE -DNOFSCHG " 19292063Sluigi log "do a 'make obj' in a few places." 19392063Sluigi # This is very version-specific... The following works for 5.0 194158687Sphk for i in lib secure/lib gnu/lib \ 19584377Sluigi gnu/usr.bin/perl usr.bin/lex usr.sbin/config ; do 19684377Sluigi (cd ${i}; eval $e obj) 19784377Sluigi done 19892063Sluigi log "now make the static libraries" 199155136Sluigi eval $e -DNOPROFILE -DNOPIC libraries 20084377Sluigi (cd ${SRC}/usr.sbin/config 20184377Sluigi eval $e # build binary 20284377Sluigi eval $e install # install it 20384377Sluigi ) 20484377Sluigi ) || fail $? "libraries" 20584377Sluigi log "Libraries done" 20672770Sluigi} 20772770Sluigi 20884377Sluigi# set_type <type> looks in user or system directories for the floppy type 20984377Sluigi# specified as first argument, and sets variables according to the config. 210173602Sluigi# file. Sets THETYPE, SITE, name, MY_TREE and BUILDDIR 21172770Sluigi 21284377Sluigiset_type() { 213127266Sluigi local a i 21484377Sluigi 215173602Sluigi log "set_type() : Type '$1' site '$2'" 21684377Sluigi THETYPE=$1 21784377Sluigi SITE=$2 21872770Sluigi a=$1 219173602Sluigi name="" # clear in case of errors 22084377Sluigi for i in ${c_startdir}/${a} ${PICO_TREE}/${a} ; do 22178494Sluigi log "set_type: checking $i" 222173602Sluigi [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ] || continue 223173602Sluigi set -- `cat $i/PICOBSD | \ 22472770Sluigi awk '/^#PicoBSD/ {print $2, $3, $4, $5, $6}'` 225173602Sluigi [ x"$1" != "x" ] || continue 226173602Sluigi MFS_SIZE=$1 ; init_name=$2 227173602Sluigi mfs_inodes=$3 ; fd_inodes=$4 228173602Sluigi name=`(cd $i ; pwd) ` 229173602Sluigi name=`basename $name` 230173602Sluigi MY_TREE=$i 231173602Sluigi BUILDDIR=${c_startdir}/build_dir-${name} 232173602Sluigi log "Matching file $name in $i" 233173602Sluigi return ; 23472770Sluigi done 235173602Sluigi logverbose "Type $a NOT FOUND" 23672770Sluigi} 23772770Sluigi 23872770Sluigiclean_tree() { 23984377Sluigi log "clean_tree()" 24072770Sluigi if [ "${name}" = "" ] ; then 24184377Sluigi echo "---> Wrong floppy type" 24272770Sluigi exit 3 24372770Sluigi fi 24472770Sluigi rm -rf ${BUILDDIR} 24572770Sluigi} 24672770Sluigi 24772770Sluigi# prepare a message to be printed in the dialog menus. 24872770Sluigiset_msgs() { # OK 24984377Sluigi log "set_msgs()" 25084377Sluigi 25172770Sluigi MSG1="Type: ${THETYPE} name $name" 25272770Sluigi 25372770Sluigi MSG="PicoBSD build -- Current parameters:\n\n\t1. ${MSG1}\n\ 25472770Sluigi\t2. MFS size: ${MFS_SIZE} kB\n\ 25572770Sluigi\t3. Site-info: ${SITE}\n\t4. Full-path: ${MY_TREE}\n" 25672770Sluigi} 25772770Sluigi 25872770Sluigi 25972770Sluigi# Main build procedure. 26072770Sluigibuild_image() { 26184377Sluigi log "build_image() <${name}>" 26284377Sluigi [ "${name}" != "" ] || fail $? bad_type 26372770Sluigi clear 26472770Sluigi set_msgs 26584377Sluigi printf "${MSG}---> We'll use the sources living in ${SRC}\n\n" 26672770Sluigi 26784377Sluigi # read config variables from a global and then a type-specific file 26884377Sluigi # basically STAND_LINKS and MY_DEVS, but can also override other 26984377Sluigi # variables. 27084377Sluigi # 27184377Sluigi . ${PICO_TREE}/build/config 27284377Sluigi if [ -f ${MY_TREE}/config ] ; then 27384377Sluigi . ${MY_TREE}/config 27484377Sluigi fi 27584377Sluigi 27684377Sluigi # location of the object directory 27784377Sluigi PICO_OBJ=${l_objtree}/picobsd/${THETYPE} 27884377Sluigi log "PICO_OBJ is ${PICO_OBJ}" 27984377Sluigi 28099946Sluigi if [ ${OSVERSION} -ge 500035 ] ; then 281173602Sluigi export MAKEOBJDIRPREFIX=${l_objtree} 282173597Sluigi eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V BINMAKE`\"" 283173597Sluigi eval export `cd ${SRC}; ${BINMAKE} -f Makefile.inc1 -V WMAKEENV` 28499946Sluigi fi 28584377Sluigi # create build directory and subtree 28684377Sluigi mkdir -p ${BUILDDIR}/crunch 28784377Sluigi # remove any old stuff 28884377Sluigi rm -f ${BUILDDIR}/kernel.gz ${BUILDDIR}/${c_fs} 28984377Sluigi # invoke commands to build a kernel 29072770Sluigi do_kernel 29184377Sluigi # fill a subdirectory with things that go into the floppy 29284377Sluigi # (mostly /etc and similar stuff) 29384377Sluigi populate_floppy_fs 29484377Sluigi # populate it and produce a file with the MFS image 29584377Sluigi populate_mfs_tree # things which go into mfs 29684377Sluigi # create, mount and fill a filesystem with floppy image 29772770Sluigi fill_floppy_image # copies everything into the floppy 29872770Sluigi} 29972770Sluigi 30072770Sluigibuild_package() { 30184377Sluigi local z msg 30284377Sluigi 30384377Sluigi log "build_package()" 304173602Sluigi rm -rf build.status 30572770Sluigi echo "##############################################" >>build.status 30672770Sluigi echo "## `date` ">>build.status 30772770Sluigi echo "##############################################" >>build.status 30876380Sluigi for z in bridge dial router net isp ; do 30972770Sluigi set_type ${z} 310173602Sluigi if [ "${name}" = "" ] ; then 311173602Sluigi echo "*** TYPE=${z} not found" >>build.status 312173602Sluigi continue 313173602Sluigi fi 31472770Sluigi echo "---------------------------------------------">>build.status 31572770Sluigi echo "Building TYPE=${z}, SIZE=${MFS_SIZE}" >>build.status 31684377Sluigi msg="(ok)" # error message 31784377Sluigi build_image || msg="** FAILED! **" 31884377Sluigi echo " ${msg}">>build.status 31984377Sluigi # where do i put things ? 32084377Sluigi # clean_tree 32172770Sluigi done 32272770Sluigi exit 0 32372770Sluigi} 32472770Sluigi 32572770Sluigi# Set build parameters interactively 32672770Sluigi 32772770Sluigimain_dialog() { 32884377Sluigi local ans i l 32984377Sluigi 33084377Sluigi log "main_dialog()" 33172770Sluigi while [ true ] ; do 33272770Sluigi set_msgs 33384377Sluigi rm ${c_reply} 33484377Sluigi dialog --menu "PicoBSD build menu -- (29 sep 2001)" 19 70 12 \ 33572770Sluigi N "--> READY, build it <---" \ 33672770Sluigi T "${MSG1}" \ 33772770Sluigi K "edit Kernel config file" \ 33872770Sluigi E "Edit crunch.conf file" \ 33972770Sluigi S "MFS Size: ${MFS_SIZE}kB" \ 34084377Sluigi I "Init type: ${init_name}" \ 34184377Sluigi F "Floppy size: ${fd_size}kB" \ 34284377Sluigi M "MFS bytes per inode: ${mfs_inodes}" \ 34384377Sluigi U "UFS bytes per inode: ${fd_inodes}" \ 34472770Sluigi $ "Site-info: ${SITE}" \ 34572770Sluigi Q "Quit" \ 34684377Sluigi 2> ${c_reply} 34784377Sluigi ans=`cat ${c_reply}` 34884377Sluigi rm ${c_reply} 34972770Sluigi case ${ans} in 35072770Sluigi T) 35172770Sluigi l="" 35284377Sluigi for i in ${c_startdir} ${c_startdir}/* ${PICO_TREE}/* ; do 35372770Sluigi if [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ]; then 35472770Sluigi l="$l `basename $i` `basename $i`" 35572770Sluigi fi 35672770Sluigi done 35772770Sluigi log $l 35890659Sluigi { dialog --menu "Setup the type of configuration" 12 70 5 $l \ 35990659Sluigi 2> ${c_reply} && set_type "`cat ${c_reply}`" ${SITE} ; } || true 36072770Sluigi ;; 36172770Sluigi I) 36290659Sluigi { dialog --menu "Choose your init(8) program" \ 36372770Sluigi 10 70 2 init "Standard init (requires getty)" \ 36484377Sluigi oinit "small init from TinyWare" 2> ${c_reply} \ 36590659Sluigi && init_name=`cat ${c_reply}` ; } || true 36672770Sluigi ;; 36772770Sluigi 36872770Sluigi K) ${EDITOR} ${MY_TREE}/PICOBSD ;; 36972770Sluigi 37072770Sluigi E) ${EDITOR} ${MY_TREE}/crunch.conf ;; 37172770Sluigi 37272770Sluigi S) 37390659Sluigi { dialog --title "MFS Size setup" --inputbox \ 37472770Sluigi"MFS size depends on what you need to put on the MFS image. Typically \ 37572770Sluigiranges between 820kB (for very small bridge/router images) to \ 37672770Sluigias much as 2500kB kB for a densely packed image. \ 37772770SluigiKeep in mind that this memory is \ 37872770Sluigitotally lost to other programs. Usually you want to keep \ 37984377Sluigithis as small as possible. " 10 70 2> ${c_reply} \ 38090659Sluigi && MFS_SIZE=`cat ${c_reply}` ; } || true 38172770Sluigi ;; 38272770Sluigi 38372770Sluigi \$) 38490659Sluigi { dialog --title "Site info setup" --inputbox \ 38572770Sluigi "Please enter the full path to the directory \ 38672770Sluigi containing site-specific setup. \ 38772770Sluigi This directory tree must contain files that replace \ 38872770Sluigi standard ones in floppy.tree/ and mfs.tree/ . " \ 38990659Sluigi 10 70 2> ${c_reply} && SITE=`cat ${c_reply}` ; } || true 39072770Sluigi ;; 39172770Sluigi 39272770Sluigi F) 39391846Sluigi { dialog --menu "Set floppy size" 15 70 4 \ 39484377Sluigi 1440 "1.44MB" 1720 "1.72MB" 2880 "2.88MB" 4096 "4MB" \ 39591846Sluigi 2> ${c_reply} && fd_size=`cat ${c_reply}` ; } || true 39672770Sluigi ;; 39772770Sluigi 39872770Sluigi M) 39991846Sluigi { dialog --title "MFS bytes per inode:" --inputbox \ 40072770Sluigi "Enter MFS bytes per inode (typically 4096..65536). \ 40172770Sluigi A larger value means fewer inodes but more space on MFS" \ 40292063Sluigi 10 70 2> ${c_reply} && mfs_inodes=`cat ${c_reply}` ; } || true 40372770Sluigi ;; 40472770Sluigi 40572770Sluigi U) 40691846Sluigi { dialog --title "Floppy bytes per inode:" --inputbox \ 40772770Sluigi "Enter floppy bytes per inode (typically 3072..65536). \ 40872770Sluigi A larger value means fewer inodes but more space on the floppy." \ 40991846Sluigi 10 70 2> ${c_reply} && fd_inodes=`cat ${c_reply}` ; } || true 41072770Sluigi ;; 41172770Sluigi 41272770Sluigi N) break 2 41372770Sluigi ;; 41472770Sluigi 41572770Sluigi Q) exit 0 ;; 41672770Sluigi 41772770Sluigi *) echo "Unknown option \"${ans}\". Try again." 41872770Sluigi sleep 2 41972770Sluigi clear 42072770Sluigi ;; 42172770Sluigi esac 42272770Sluigi done 42372770Sluigi} 42472770Sluigi 42572770Sluigi# Call the build procedure 42672770Sluigi# Install image 42772770Sluigido_install() { 42884377Sluigi log "do_install()" 42984377Sluigi 43085833Sluigi if [ "${o_interactive}" = "NO" ] ; then 43185833Sluigi echo "+++ Build completed +++" 432155136Sluigi cat .build.reply || true 43385833Sluigi return 43485833Sluigi fi 43582747Sluigi dialog --title "Build ${THETYPE} completed" --inputbox \ 43672770Sluigi"\nThe build process was completed successfuly.\n\ 43772770Sluigi`cat .build.reply` \n\n\ 43872770SluigiNow we are going to install the image on the floppy.\n\ 43972770SluigiPlease insert a blank floppy in /dev/fd0.\\n 44072770SluigiWARNING: the contents of the floppy will be permanently erased!\n\ 44172770Sluigi\n\ 44272770SluigiYour options:\n\ 44372770Sluigi * ^C or [Cancel] to abort,\n\ 44484377Sluigi * Enter to install ${c_img},\n\ 44584377Sluigi" 20 80 2> ${c_reply} 44672770Sluigi if [ "$?" = "0" ]; then 44784377Sluigi echo "Writing ${c_img}..." 44884377Sluigi dd if=${BUILDDIR}/${c_img} of=/dev/fd0.${fd_size} 44972770Sluigi else 45084377Sluigi echo "Ok, the image is in ${c_img}" 45172770Sluigi fi 45272770Sluigi echo "Done." 45372770Sluigi} 45472770Sluigi 45572770Sluigi 45672770Sluigi#------------------------------------------------------------------- 45772770Sluigi 458173602Sluigi# invoke the picobsd Makefile to compile the kernel. 459173602Sluigi# if MODULES is set (value is irrelevant) the makefile will build modules. 46072770Sluigido_kernel() { # OK 46184377Sluigi log "do_kernel() Preparing kernel \"$name\" in $MY_TREE" 46299946Sluigi (cd $MY_TREE; export name SRC BUILDDIR # used in this makefile ; 46399946Sluigi # export CONFIG 464173602Sluigi [ "${o_do_modules}" = "yes" ] && export MODULES="" 465173597Sluigi ${BINMAKE} -v -f ${PICO_TREE}/build/Makefile.conf ) || \ 46672770Sluigi fail $? missing_kernel 46772770Sluigi} 46872770Sluigi 46984377Sluigi# Populate the variable part of the floppy filesystem. Must be done before 47084377Sluigi# the MFS because its content might need to be copied there as well. 47172770Sluigi# 47284377Sluigi# This involves fetching files from three subtrees, in this order: 47372770Sluigi# 47484377Sluigi# 1. a standard one, from which type-specific files are excluded; 47572770Sluigi# 2. a type-specific one; 47672770Sluigi# 3. a site-specific one. 47772770Sluigi# 47872770Sluigi# Files are first copied to a local tree and then compressed. 47972770Sluigi 48072770Sluigipopulate_floppy_fs() { # OK 48183692Sluigi local dst excl srcdir 48272770Sluigi 48384377Sluigi log "populate_floppy_fs()" 48472770Sluigi dst=${BUILDDIR}/floppy.tree 48584377Sluigi log "pwd=`pwd` Populating floppy filesystem..." 48672770Sluigi 48783692Sluigi # clean relics from old compilations. 48883692Sluigi rm -rf ${dst} || true 48983692Sluigi mkdir ${dst} 49072770Sluigi 49172770Sluigi excl=${MY_TREE}/floppy.tree.exclude 49272770Sluigi if [ -f ${excl} ] ; then 493173597Sluigi log "Files excluded from generic tree: `echo;cat ${excl}`" 49472770Sluigi excl="--exclude-from ${excl}" 49572770Sluigi else 49672770Sluigi excl="" 49772770Sluigi fi 49872770Sluigi (cd ${PICO_TREE}/floppy.tree ; tar -cf - --exclude CVS ${excl} . ) | \ 49984377Sluigi (cd ${dst} ; tar x${o_tarv}f - ) 50084377Sluigi log "Copied from generic floppy-tree `echo; ls -laR ${dst}`" 50172770Sluigi 50272770Sluigi srcdir=${MY_TREE}/floppy.tree 50372770Sluigi if [ -d ${srcdir} ] ; then 50484377Sluigi log "update with type-specific files:" 50572770Sluigi (cd ${srcdir} ; tar -cf - --exclude CVS . ) | \ 50684377Sluigi (cd ${dst} ; tar x${o_tarv}f - ) 50784377Sluigi log "Copied from type floppy-tree `echo; ls -laR ${dst}`" 50872770Sluigi else 50984377Sluigi log "No type-specific floppy-tree" 51072770Sluigi fi 51172770Sluigi if [ -d ${srcdir}.${SITE} ] ; then 51284377Sluigi log "Update with site-specific (${SITE}) files:" 51372770Sluigi (cd ${srcdir}.${SITE} ; tar -cf - --exclude CVS . ) | \ 51484377Sluigi (cd ${dst} ; tar x${o_tarv}f - ) 51584377Sluigi log "Copied from site floppy-tree `echo; ls -laR ${dst}`" 51672770Sluigi else 51784377Sluigi log "No site-specific floppy-tree" 51872770Sluigi fi 51992063Sluigi 52072770Sluigi # gzip returns an error if it fails to compress some file 52184377Sluigi (cd $dst ; gzip -9 etc/* 52284377Sluigi log "Compressed files in etc/ `echo; ls -l etc`" 52372770Sluigi ) || true 52472770Sluigi} 52572770Sluigi 52672770Sluigi# Populate the memory filesystem with binaries and non-variable 52772770Sluigi# configuration files. 52872770Sluigi# First do an mtree pass, then create directory links and device entries, 52972770Sluigi# then run crunchgen etc. to build the binary and create links. 53072770Sluigi# Then copy the specific/generic mfs_tree. 53172770Sluigi# Finally, if required, make a copy of the floppy.tree onto /fd 53272770Sluigi 53384377Sluigipopulate_mfs_tree() { 53484377Sluigi local a dst 53572770Sluigi 53684377Sluigi log "populate_mfs_tree()" 537155136Sluigi dst=${BUILDDIR}/mfs.tree 538155136Sluigi # clean relics from old compilations. 539155136Sluigi rm -rf ${dst} || true 540155136Sluigi mkdir ${dst} 54172770Sluigi 54284377Sluigi log "pwd=`pwd`, Populating MFS tree..." 54384377Sluigi 54484377Sluigi # use type-specific mfs.mtree, default to generic one. 54584377Sluigi a=${MY_TREE}/mfs.mtree 54684377Sluigi [ -f ${a} ] || a=${PICO_TREE}/build/mfs.mtree 54784377Sluigi log "Running mtree using $a..." 54884377Sluigi mtree -deU -f $a -p ${dst} > /dev/null || fail $? mtree 54984377Sluigi 55072770Sluigi # XXX create links 55172770Sluigi for i in ${STAND_LINKS}; do 55284377Sluigi ln -s /stand ${dst}/$i 55372770Sluigi done 55484377Sluigi ln -s /dev/null ${dst}/var/run/log 55584377Sluigi ln -s /etc/termcap ${dst}/usr/share/misc/termcap 55672770Sluigi 55772770Sluigi 55872770Sluigi ( 55972770Sluigi cd ${BUILDDIR}/crunch 56084377Sluigi log "Making and installing crunch1 from `pwd` src ${SRC}..." 56172770Sluigi a=${BUILDDIR}/crunch1.conf 56278541Sluigi ( export BUILDDIR SRC MY_TREE PICO_OBJ ; 563173597Sluigi ${BINMAKE} \ 56486876Sluigi -v -f ${PICO_TREE}/build/Makefile.conf ${BUILDDIR}/crunch.mk ) 56584377Sluigi log "Libs are ${LIBS} " 56699946Sluigi export SRC # used by crunch.mk 56799946Sluigi # export LIBS CFLAGS 56872770Sluigi log "Now make -f crunch.mk" 569173597Sluigi ${BINMAKE} ${o_makeopts} -f ${BUILDDIR}/crunch.mk 57072770Sluigi strip --remove-section=.note --remove-section=.comment crunch1 57184377Sluigi mv crunch1 ${dst}/stand/crunch 57284377Sluigi chmod 555 ${dst}/stand/crunch 57384377Sluigi log "Making links for binaries..." 57472770Sluigi for i in `crunchgen -l $a` ; do 57584377Sluigi ln ${dst}/stand/crunch ${dst}/stand/${i}; 57672770Sluigi done 57778541Sluigi # rm $a # do not remove! 57872770Sluigi ) || fail $? crunch 57972770Sluigi 58084377Sluigi if [ -f ${dst}/stand/sshd ] ; then 58192063Sluigi log "Setting up host key for sshd:" 58292063Sluigi if [ -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key.gz ] ; then 58384627Sluigi log "Using existing host key" 58484627Sluigi else 58592063Sluigi log "Generating new host key" 586127266Sluigi ssh-keygen -t rsa1 -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key \ 58792063Sluigi -N "" -C "root@picobsd" 58892063Sluigi gzip -9 ${BUILDDIR}/floppy.tree/etc/ssh_host_key* || true 58984627Sluigi fi 59072770Sluigi fi 59172770Sluigi 59291846Sluigi log "Copy generic and site-specific MFS tree..." 59391846Sluigi for MFS_TREE in ${PICO_TREE}/mfs_tree ${MY_TREE}/mfs_tree ; do 59491846Sluigi if [ -d ${MFS_TREE} ] ; then 59591846Sluigi log "Copy ${MFS_TREE} ..." 59691846Sluigi (cd ${MFS_TREE} ; tar -cf - --exclude CVS . ) | \ 59792063Sluigi (cd ${dst} ; tar x${o_tarv}f - ) 59891846Sluigi fi 59991846Sluigi done 60072770Sluigi 60184377Sluigi if [ "${o_all_in_mfs}" = "yes" ]; then 60284377Sluigi log "Copy generic floppy_tree into MFS..." 603155136Sluigi # this may fail in case the floppy is empty 604155136Sluigi cp -Rp ${BUILDDIR}/floppy.tree/* ${dst}/fd || true 60572770Sluigi fi 60684377Sluigi 60784377Sluigi if [ "${o_no_devfs}" != "" ] ; then 60884377Sluigi # create device entries using MAKEDEV 60984377Sluigi (cd ${dst}/dev 610155136Sluigi ln -s ${SRC}/etc/MAKEDEV ; chmod 555 MAKEDEV 611155136Sluigi # log `pwd` 612155136Sluigi sh ./MAKEDEV ${MY_DEVS} 61384377Sluigi rm MAKEDEV 61484377Sluigi ) 61584377Sluigi fi 616155136Sluigi if [ "`id -u`" = "0" ] ; then 617155136Sluigi log "Fixing permissions" 618155136Sluigi (cd ${dst}; chown -R root . ) 619155136Sluigi fi 62084377Sluigi 62192853Sluigi if [ -n "${import_files}" ] ; then 62292853Sluigi log "importing ${import_files} into mfs" 62392853Sluigi # We do it in a chroot environment on the target so 62492853Sluigi # symlinks are followed correctly. 62592853Sluigi cp `which tar` ${dst}/my_copy_of_tar 62692853Sluigi (cd ${l_usrtree}/.. ; tar cf - ${import_files} ) | \ 62792853Sluigi (chroot ${dst} /my_copy_of_tar xf - ) 62892853Sluigi rm ${dst}/my_copy_of_tar 62992853Sluigi fi 63092853Sluigi 631155136Sluigi (cd ${BUILDDIR} 632155136Sluigi # override the owner 633155136Sluigi echo "/set uid=0 gid=0" > mtree.out 634155136Sluigi mtree -c -p ${dst} -k "" >> mtree.out 635155136Sluigi log "mtre.out at ${BUILDDIR}/mtree.out" 636155136Sluigi makefs -t ffs -o bsize=4096 -o fsize=512 \ 637155136Sluigi -s ${MFS_SIZE}k -f 100 -F mtree.out ${c_fs} ${dst} 638155136Sluigi ls -l ${c_fs} ) 639155136Sluigi log "done mfs image" 64072770Sluigi} 64172770Sluigi 64272770Sluigifinal_cleanup() { 64384377Sluigi log "final_cleanup()" 64484377Sluigi rm -rf ${c_mnt} ${c_reply} 2> /dev/null || true 64584377Sluigi rm -f ${c_reply} 64672770Sluigi} 64772770Sluigi 64872770Sluigi# fail errno errcode 64972770Sluigi# This function is used to trap errors and print msgs 65072770Sluigi# 65172770Sluigifail() { 65284377Sluigi local errno errocode where 65384377Sluigi 65472770Sluigi errno=$1 65572770Sluigi errcode=$2 65684377Sluigi where=$3 65784377Sluigi echo "---> fail: Error <${errno}> error code <${errcode}> in <${where}>" 65884377Sluigi case ${errcode} in 65972770Sluigi mtree) 66084377Sluigi echo "Error while making hierarchy in ${c_mnt}" 66172770Sluigi ;; 66272770Sluigi crunch) 66372770Sluigi echo "Error while building ${name}." 66472770Sluigi ;; 66572770Sluigi missing_kernel) 66675880Sjoe echo "Error: you must build PICOBSD${suffix} kernel first" 66772770Sluigi ;; 66882917Sluigi includes) 66982917Sluigi echo "Error: failed while making includes" 67082917Sluigi ;; 67182917Sluigi libraries) 67282917Sluigi echo "Error: failed while making libraries" 67382917Sluigi ;; 67484377Sluigi bad_type) 67584377Sluigi echo "Error: unknown floppy type ${name}" 67684377Sluigi ;; 67784377Sluigi no_space) 67884377Sluigi echo "Error: no space left on device (${where})" 67984377Sluigi ;; 68092853Sluigi no_mfs) 68192853Sluigi echo "Error: while writing MFS into the kernel." 68292853Sluigi ;; 68372770Sluigi "") 68472770Sluigi echo "User break" 68584377Sluigi errcode="userbreak" 68672770Sluigi ;; 68772770Sluigi *) 68872770Sluigi echo "unknown error, maybe user break: $errno $errcode" 68972770Sluigi ;; 69072770Sluigi esac 69172770Sluigi echo "---> Aborting $0" 69272770Sluigi # try to cleanup the vnode. 69372770Sluigi final_cleanup 69472770Sluigi exit 2 69572770Sluigi} 69672770Sluigi 69772770Sluigifill_floppy_image() { 698155136Sluigi local blocks dst mfs_start mfs_end mfs_size img_size 69972770Sluigi 70084377Sluigi log "fill_floppy_image()" 70184377Sluigi dst=${c_mnt} # where to create the image 70284377Sluigi 70384377Sluigi log "Preparing ${fd_size}kB floppy filesystem..." 70484377Sluigi 705155136Sluigi # correct blocks according to size. 706155136Sluigi blocks=${fd_size}; 70772770Sluigi if [ "${blocks}" = "1720" ]; then 708155136Sluigi blocks=1722 70972770Sluigi elif [ "${blocks}" = "1480" ]; then 710155136Sluigi blocks=1476 71172770Sluigi fi 71272770Sluigi 71384377Sluigi log "Labeling floppy image" 714155136Sluigi log "patch ${c_boot2} to boot /kernel right away" 715127266Sluigi b2=${BUILDDIR}/boot2 # modified boot2 716155136Sluigi cp -f ${c_boot2} ${b2} 717127266Sluigi chmod 0644 ${b2} 718155136Sluigi 719127266Sluigi set `strings -at d ${b2} | grep "/boot/loader"` 720155136Sluigi echo -e "/kernel\0\0\0\0\0" | \ 721155136Sluigi dd of=${b2} obs=$1 oseek=1 conv=notrunc 2>/dev/null 722127266Sluigi chmod 0444 ${b2} 72391846Sluigi 724155136Sluigi dst=${BUILDDIR}/image.tree 725155136Sluigi rm -rf ${dst} 726155136Sluigi mkdir -p ${dst} 72772770Sluigi ( 72872770Sluigi cd ${BUILDDIR} 729155136Sluigi set 0 0 # reset variables 73099946Sluigi # $1 takes the offset of the MFS filesystem 73199946Sluigi set `strings -at d kernel | grep "MFS Filesystem goes here"` 732155136Sluigi mfs_start=$1 733155136Sluigi set 0 0 # reset variables 734155136Sluigi set `strings -at d kernel | grep "MFS Filesystem had better"` 735155136Sluigi mfs_end=$1 736155136Sluigi mfs_size="$((${mfs_end} - ${mfs_start}))" 737155136Sluigi set -- `ls -l ${c_fs}`; imgsize="$5" 738155136Sluigi if [ ${mfs_start} -gt 0 -a ${mfs_size} -ge ${imgsize} ] ; then 739155136Sluigi mfs_ofs=$((${mfs_start} + 8192)) 740155136Sluigi log "Preload kernel with file ${c_fs} at ${mfs_ofs}" 741155136Sluigi dd if=${c_fs} ibs=8192 iseek=1 of=kernel obs=${mfs_ofs} \ 742155136Sluigi oseek=1 conv=notrunc 2> /dev/null 743155136Sluigi else 744155136Sluigi log "not loading mfs, size ${mfs_size} img ${imgsize}" 745155136Sluigi fi 74684377Sluigi log "Compress with kgzip and copy to floppy image" 74772770Sluigi kgzip -o kernel.gz kernel 74884377Sluigi cp -p kernel.gz ${dst}/kernel || fail $? no_space "copying kernel" 74972770Sluigi 750155136Sluigi log "Now transfer floppy tree if not already in MFS image" 75172770Sluigi # now transfer the floppy tree. If it is already in mfs, dont bother. 75284377Sluigi if [ "${o_all_in_mfs}" != "yes" ] ; then 75384377Sluigi cp -Rp floppy.tree/* ${dst} || \ 75484377Sluigi fail $? no_space "copying floppy tree" 75572770Sluigi fi 75672770Sluigi ) 757155136Sluigi (cd ${BUILDDIR} 758155136Sluigi makefs -t ffs -o bsize=4096 -o fsize=512 \ 759155136Sluigi -s ${blocks}k -f 50 ${c_img} ${dst} 760155136Sluigi # ${l_label} -f `pwd`/${c_img} 761155136Sluigi ${l_label} -w -f `pwd`/${c_img} auto # write in a label 762155136Sluigi # copy partition c: into a: with some sed magic 763155136Sluigi ${l_label} -f `pwd`/${c_img} | sed -e '/ c:/{p;s/c:/a:/;}' | \ 764155136Sluigi ${l_label} -R -f `pwd`/${c_img} /dev/stdin 765155136Sluigi ${l_label} -f `pwd`/${c_img} 766155136Sluigi ls -l ${c_img} 767155136Sluigi logverbose "after disklabel" 768155136Sluigi ) 769155136Sluigi # dump the primary and secondary boot 770155136Sluigi # XXX primary is 512 bytes 771155136Sluigi dd if=${c_boot1} of=${BUILDDIR}/${c_img} conv=notrunc 2>/dev/null 772155136Sluigi # XXX secondary starts after the 0x114 = dec 276 bytes of the label 773155136Sluigi # so we skip 276 from the source, and 276+512=788 from dst 774155136Sluigi # the old style blocks used 512 and 1024 respectively 77572770Sluigi 776155136Sluigi dd if=${b2} iseek=1 ibs=276 2> /dev/null | \ 777155136Sluigi dd of=${BUILDDIR}/${c_img} oseek=1 obs=788 conv=notrunc 2>/dev/null 778155136Sluigi logverbose "done floppy image" 779155136Sluigi # XXX (log "Fixing permissions"; cd ${dst}; chown -R root *) 780155136Sluigi rm -rf ${BUILDDIR}/floppy.tree || true # cleanup 781155136Sluigi # df -ik ${dst} | colrm 70 > .build.reply 78284377Sluigi rm -rf ${dst} 78384377Sluigi rm ${BUILDDIR}/kernel.gz ${BUILDDIR}/${c_fs} 78472770Sluigi} 78572770Sluigi 78684377Sluigi# This function creates variables which depend on the source tree in use: 78799946Sluigi# SRC, l_usrtree, l_objtree 78884377Sluigi# Optionally creates libraries, includes and the like (for cross compiles, 78984377Sluigi# needs to be done once). 79084377Sluigi 79184377Sluigiset_build_parameters() { 79284377Sluigi log "set_build_parameters() SRC is ${SRC}" 79384377Sluigi if [ "${SRC}" = "/usr/src" ] ; then 79484377Sluigi l_usrtree=${USR:-/usr} 79584377Sluigi else 79684377Sluigi l_usrtree=${USR:-${SRC}/../usr} 79784093Sluigi fi 79884377Sluigi l_objtree=${l_usrtree}/obj-pico 79984377Sluigi PICO_TREE=${PICO_TREE:-${SRC}/release/picobsd} 80099946Sluigi set `grep "#define[\t ]__FreeBSD_version" ${SRC}/sys/sys/param.h` 80199946Sluigi OSVERSION=$3 80299951Sluigi log "OSVERSION is ${OSVERSION}" 80384377Sluigi if [ "${o_init_src}" != "" ] ; then 80499946Sluigi if [ ${OSVERSION} -lt 500035 ] ; then 80599946Sluigi create_includes_and_libraries 80699946Sluigi else 80799946Sluigi create_includes_and_libraries2 80899946Sluigi fi 80984093Sluigi fi 81099946Sluigi if [ ${OSVERSION} -lt 500035 ] ; then 81199946Sluigi # Create the right LIBS and CFLAGS for further builds. 81299946Sluigi # and build the config program 81399946Sluigi LIBS="-L${l_usrtree}/lib" 81499946Sluigi CFLAGS="-nostdinc -I${l_usrtree}/include" 81599946Sluigi export LIBS CFLAGS 81699946Sluigi CONFIG=${l_usrtree}/sbin/config 81799946Sluigi export CONFIG 81899946Sluigi fi 81984093Sluigi} 82084093Sluigi 82184377Sluigi#------------------------------------------------------------------- 82284377Sluigi# Main entry of the script. Initialize variables, parse command line 82384377Sluigi# arguments. 82484093Sluigi 82584377Sluigiset_defaults 826173602Sluigiargs="" 827173602Sluigiwhile [ x"$1" != x ]; do 82872770Sluigi case $1 in 82978494Sluigi --src) # set the source path instead of /usr/src 83084627Sluigi SRC=`(cd $2; pwd)` 83184093Sluigi shift 83278494Sluigi ;; 83384377Sluigi --init) 83484377Sluigi o_init_src="YES" 83584377Sluigi ;; 83682917Sluigi 83772770Sluigi --floppy_size) 83884377Sluigi fd_size=$2 83972770Sluigi shift 84072770Sluigi ;; 84184377Sluigi 84284377Sluigi --all_in_mfs) 84384377Sluigi o_all_in_mfs="yes" 84484377Sluigi ;; 84584377Sluigi 84684377Sluigi --no_all_in_mfs) 84784377Sluigi o_all_in_mfs="" 84884377Sluigi ;; 84984377Sluigi 85085833Sluigi --modules) # also build kernel modules 85185833Sluigi o_do_modules="yes" 85285833Sluigi ;; 85372770Sluigi -n) 85484377Sluigi o_interactive="NO" 85572770Sluigi ;; 85684377Sluigi 85784377Sluigi -clear|-clean|-c) # clean 85884377Sluigi o_clean="YES" 85984377Sluigi o_interactive="NO" 86072770Sluigi ;; 86184377Sluigi 86284377Sluigi -v) # need -v -v to wait for user input 86384377Sluigi o_verbose=$((${o_verbose}+1)) # verbose level 86484377Sluigi o_tarv="v" # tar verbose flag 86584377Sluigi o_makeopts="-d l" # be verbose 86672770Sluigi ;; 86772770Sluigi *) 868173602Sluigi args="$args $1" # accumulate args 86972770Sluigi ;; 87072770Sluigi 87172770Sluigi esac 87272770Sluigi shift 87372770Sluigidone 87484377Sluigiset_build_parameters # things that depend on ${SRC} 87572770Sluigi 87672770Sluigi# If $1="package", it creates a neat set of floppies 877173602Sluigiset -- ${args} 878173602Sluigi[ "$1" = "package" ] && build_package 87972770Sluigi 880173602Sluigiset_type $args # type and site, respectively 881173602Sluigi 882173602Sluigi[ "${o_interactive}" != "NO" ] && main_dialog 883173602Sluigi 88484377Sluigiif [ "${o_clean}" = "YES" ] ; then 88572770Sluigi clean_tree 88672770Sluigielse 88772770Sluigi build_image 88872770Sluigi do_install 88972770Sluigifi 89072770Sluigifinal_cleanup 89172770Sluigiexit 0 892