Index: stable/4/release/picobsd/build/picobsd =================================================================== --- stable/4/release/picobsd/build/picobsd (revision 83737) +++ stable/4/release/picobsd/build/picobsd (revision 83738) @@ -1,762 +1,764 @@ #!/bin/sh - # # $FreeBSD$ # # The new PicoBSD build script. Invoked as # # picobsd [options] floppy_type site_name # # Where floppy_type is a directory where the picobsd config info # is held, and ${floppy_type}/floppy.tree.${site_name} contains # optional site-specific configuration. # # For Options, see the bottom of the file where the processing is # done. The picobsd(8) manpage might be of some help, but code and docs # tend to lose sync over time... # # This script depends on the following files: # # in ${PICO_TREE} : # Makefile.conf Makefile used to build the kernel # config shell variables, sourced here. # mfs.mtree mtree config file # # floppy.tree/ files which go on the floppy # mfs_tree/ files which go onto the mfs # # in ${MY_TREE} : # PICOBSD kernel config file # config shell variables, sourced here. # crunch.conf crunchgen configuration # floppy.tree.exclude files from floppy.tree/ which we do not need here. # floppy.tree/ local additions to the floppy.tree # floppy.tree.${site}/ same as above, site specific. # #--- here are various functions used by the script. #--- The main entry point is at the end. # # initialize some shell variables used by the script. # This must be done after option parsing so user-specified values # are used to compute dependent ones. Make sure to use the # VAR=${VAR:-value} construct for those variables which can # be overridden from the command line. -# select the right memory disk name -case `uname -r` in - 5.*) - VN="md" - ;; - *) - VN="vn" -esac - init_vars() { # OK # if you include the floppy tree in the mfs, you # can boot from the image via diskless. Default to yes. INCLUDE_FLOPPY_IN_MFS=${INCLUDE_FLOPPY_IN_MFS:-yes} # SRC points to your FreeBSD source tree. # OBJ points to the obj tree. Normally /usr/obj-pico. # PICO_TREE is where standard picobsd stuff resides. # MY_TREE (set later) is where this floppy type resides. # START_DIR is the directory where we start # BUILDDIR is the build directory, which is the current one. SRC=${SRC:-/usr/src} OBJ=${OBJ:-/usr/obj-pico} PICO_TREE=${PICO_TREE:-${SRC}/release/picobsd} START_DIR=`pwd` + # select the right memory disk name + case `uname -r` in + 5.*) + VN="md" + MAKEDEV="${SRC}/etc/MAKEDEV" + ;; + *) + VN="vn" + MAKEDEV="/dev/MAKEDEV" + esac + # Various temporary files and directories. # User replies will be put in $RISU RISU=${RISU:-`mktemp "/tmp/reply.XXXXXXXXXX"`} MFS_MOUNTPOINT=`mktemp -d "/tmp/picobsd.XXXXXXXXXX"` MFS_NAME=fs.PICOBSD # EDITOR is the editor you use # SITE is site_name above. # FLOPPY_SIZE floppy size in KB (default to 1440). You can use 1480, # 1720, 2880, etc. but beware that only 1440 and 1480 will boot # from 1.44M floppy drives (1480 will not work on vmware). EDITOR=${EDITOR:-vi} SITE=${SITE:-} FLOPPY_SIZE=${FLOPPY_SIZE:-1440} NO_DEVFS=yes # DEVFS is currently broken. Always set this. # Find a suitable vnode VNUM=`mount | awk "/${VN}/ { num++ } END { printf \"%d\", num }"` VNDEV=${VN}${VNUM} log "---> Using ${VNDEV}..." # Location of the boot blocks (in case you want them custom-built) boot1=/boot/boot1 boot2=/boot/boot2 makeopts=${MAKEOPTS:--s} # be silent by default # abort in case of error... set -e trap fail 2 # catch user interrupt free_vnode } # log something on stdout if verbose. log() { if [ "$verbose" != "" ] ; then printf "%s\n" "$*" read -p "(log) enter to continue" foo fi } # set_type looks for the floppy type specified as # first argument in user- or standard- directory. # If found set variables accordingly. set_type() { # OK a=$1 for i in ${START_DIR}/${a} ${PICO_TREE}/${a} ; do log "set_type: checking $i" if [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ] ; then set -- `cat $i/PICOBSD | \ awk '/^#PicoBSD/ {print $2, $3, $4, $5, $6}'` if [ "$1" != "" ]; then MFS_SIZE=$1 ; INIT=$2 MFS_INODES=$3 ; FLOPPY_INODES=$4 name=`(cd $i ; pwd) ` name=`basename $name` MY_TREE=$i BUILDDIR=${START_DIR}/build_dir-${name} log "---> Matching file $name in $i" return ; fi fi done echo "Type $a NOT FOUND" } clean_tree() { if [ "${name}" = "" ] ; then echo "---> wrong floppy type" exit 3 fi rm -rf ${BUILDDIR} } # free as much as possible from the vnode free_vnode() { umount ${MFS_MOUNTPOINT} 2> /dev/null || true umount /dev/${VNDEV} 2> /dev/null || true if [ "${VN}" = "vn" ] ; then vnconfig -u ${VNDEV} 2> /dev/null || true else mdconfig -d -u ${VNUM} 2> /dev/null || true fi } # prepare a message to be printed in the dialog menus. set_msgs() { # OK MSG1="Type: ${THETYPE} name $name" MSG="PicoBSD build -- Current parameters:\n\n\t1. ${MSG1}\n\ \t2. MFS size: ${MFS_SIZE} kB\n\ \t3. Site-info: ${SITE}\n\t4. Full-path: ${MY_TREE}\n" } # Main build procedure. build_image() { if [ "${name}" = "" ] ; then echo "-> wrong floppy type" final_cleanup exit 1 fi clear set_msgs printf "${MSG}" echo "-> We'll use the sources living in ${SRC}" echo "-> vnode is ${VNDEV}" echo "" echo "-> I hope you have checked the PICOBSD config file..." echo "" echo "" init_stage1 do_kernel populate_floppy_fs # things which go into floppy create_mfs populate_mfs # things which go into mfs fill_floppy_image # copies everything into the floppy } build_package() { touch build.status echo "##############################################" >>build.status echo "## `date` ">>build.status echo "##############################################" >>build.status for z in bridge dial router net isp ; do set_type ${z} echo "---------------------------------------------">>build.status echo "Building TYPE=${z}, SIZE=${MFS_SIZE}" >>build.status build_image if [ "X$?" != "X0" ] ; then echo " ** FAILED! **">>build.status else echo " (ok)">>build.status fi mv ${BUILDDIR}/picobsd.bin ${BUILDDIR}/picobsd.${name}.bin echo "Cleaning ${z}">>build.status clean_tree done exit 0 } # Set build parameters interactively main_dialog() { while [ true ] ; do set_msgs dialog --menu "PicoBSD build menu -- (29 aug 2001)" 19 70 12 \ N "--> READY, build it <---" \ T "${MSG1}" \ K "edit Kernel config file" \ E "Edit crunch.conf file" \ S "MFS Size: ${MFS_SIZE}kB" \ I "Init type: ${INIT}" \ F "Floppy size: ${FLOPPY_SIZE}kB" \ M "MFS bytes per inode: ${MFS_INODES}" \ U "UFS bytes per inode: ${FLOPPY_INODES}" \ $ "Site-info: ${SITE}" \ Q "Quit" \ 2> ${RISU} ans=`cat ${RISU}` rm ${RISU} case ${ans} in T) l="" for i in ${START_DIR} ${START_DIR}/* ${PICO_TREE}/* ; do if [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ]; then l="$l `basename $i` `basename $i`" fi done log $l dialog --menu "Setup the type of configuration" 12 70 5 $l \ 2> ${RISU} || rm ${RISU} if [ -f ${RISU} ] ; then THETYPE=`cat ${RISU}` set_type $THETYPE fi ;; I) dialog --menu "Choose your init(8) program" \ 10 70 2 init "Standard init (requires getty)" \ oinit "small init from TinyWare" 2> ${RISU} || rm ${RISU} if [ -f ${RISU} ] ; then INIT=`cat ${RISU}` fi ;; K) ${EDITOR} ${MY_TREE}/PICOBSD ;; E) ${EDITOR} ${MY_TREE}/crunch.conf ;; S) dialog --title "MFS Size setup" --inputbox \ "MFS size depends on what you need to put on the MFS image. Typically \ ranges between 820kB (for very small bridge/router images) to \ as much as 2500kB kB for a densely packed image. \ Keep in mind that this memory is \ totally lost to other programs. Usually you want to keep \ this as small as possible. " 10 70 2> ${RISU} || rm ${RISU} if [ -f ${RISU} ] ; then MFS_SIZE=`cat ${RISU}` fi ;; \$) dialog --title "Site info setup" --inputbox \ "Please enter the full path to the directory \ containing site-specific setup. \ This directory tree must contain files that replace \ standard ones in floppy.tree/ and mfs.tree/ . " \ 10 70 2> ${RISU} || rm ${RISU} if [ -f ${RISU} ] ; then SITE=`cat ${RISU}` fi ;; F) dialog --menu "Set floppy size" 15 70 4 \ 1440 "1.44MB" 1720 "1.72MB" \ 2880 "2.88MB" 4096 "4MB" 2> ${RISU} || rm ${RISU} if [ -f ${RISU} ] ; then FLOPPY_SIZE=`cat ${RISU}` fi ;; M) dialog --title "MFS bytes per inode:" --inputbox \ "Enter MFS bytes per inode (typically 4096..65536). \ A larger value means fewer inodes but more space on MFS" \ 10 70 2> ${RISU} || rm ${RISU} if [ -f ${RISU} ] ; then MFS_INODES=`cat ${RISU}` fi ;; U) dialog --title "Floppy bytes per inode:" --inputbox \ "Enter floppy bytes per inode (typically 3072..65536). \ A larger value means fewer inodes but more space on the floppy." \ 10 70 2> ${RISU} || rm ${RISU} if [ -f ${RISU} ] ; then FLOPPY_INODES=`cat ${RISU}` fi ;; N) break 2 ;; Q) exit 0 ;; *) echo "Unknown option \"${ans}\". Try again." sleep 2 clear ;; esac done } # Call the build procedure # Install image do_install() { dialog --title "Build ${THETYPE} completed" --inputbox \ "\nThe build process was completed successfuly.\n\ `cat .build.reply` \n\n\ Now we are going to install the image on the floppy.\n\ Please insert a blank floppy in /dev/fd0.\\n WARNING: the contents of the floppy will be permanently erased!\n\ \n\ Your options:\n\ * ^C or [Cancel] to abort,\n\ * Enter to install \"picobsd.bin\",\n\ " 20 80 2> ${RISU} if [ "$?" = "0" ]; then echo "Writing picobsd.bin..." dd if=${BUILDDIR}/picobsd.bin of=/dev/fd0.${FLOPPY_SIZE} else echo "Ok, the image is in picobsd.bin" fi echo "Done." } #------------------------------------------------------------------- init_stage1() { # read config variables from a global and then a type-specific file # . ${PICO_TREE}/build/config if [ -f ${MY_TREE}/config ]; then . ${MY_TREE}/config fi PICO_OBJ=${OBJ}/picobsd/${THETYPE} log "PICO_OBJ is ${PICO_OBJ}" if [ ! -d ${BUILDDIR} ]; then log "Creating builddir" mkdir $BUILDDIR if [ ! -d ${BUILDDIR}/crunch ]; then log "creating crunch dir" mkdir ${BUILDDIR}/crunch fi else rm -f ${BUILDDIR}/kernel.gz ${BUILDDIR}/${MFS_NAME} # cleanup... fi } # invoke the makefile to compile the kernel. # Then copy it here and strip as much as possible. do_kernel() { # OK log "---> Preparing kernel \"$name\" in $MY_TREE" (cd $MY_TREE; export name SRC CONFIG BUILDDIR # used in this makefile ; make -v -f ${PICO_TREE}/build/Makefile.conf ) || \ fail $? missing_kernel } # Populate the variable part of the floppy filesystem. Should be # done before the MFS because it might need to be copied there as well. # # This involves three subtrees, in this order: # # 1. a standard one from which type-specific files are excluded; # 2. a type-specific one; # 3. a site-specific one. # # Files are first copied to a local tree and then compressed. populate_floppy_fs() { # OK local dst excl srcdir dst=${BUILDDIR}/floppy.tree log "---> pwd=`pwd` Populating floppy filesystem..." # clean relics from old compilations. rm -rf ${dst} || true mkdir ${dst} excl=${MY_TREE}/floppy.tree.exclude if [ -f ${excl} ] ; then excl="--exclude-from ${excl}" log "---> Files excluded from generic tree: `echo;cat ${excl}`" else excl="" fi (cd ${PICO_TREE}/floppy.tree ; tar -cf - --exclude CVS ${excl} . ) | \ (cd ${dst} ; tar x${TAR_VERBOSE}f - ) log "---> Copied from generic floppy-tree `echo; ls -laR ${dst}`" srcdir=${MY_TREE}/floppy.tree if [ -d ${srcdir} ] ; then log "---> update with type-specific files:" (cd ${srcdir} ; tar -cf - --exclude CVS . ) | \ (cd ${dst} ; tar x${TAR_VERBOSE}f - ) log "---> Copied from type floppy-tree `echo; ls -laR ${dst}`" else log "---> No type-specific floppy-tree" fi if [ -d ${srcdir}.${SITE} ] ; then log "-> update with site-specific (${SITE}) files:" (cd ${srcdir}.${SITE} ; tar -cf - --exclude CVS . ) | \ (cd ${dst} ; tar x${TAR_VERBOSE}f - ) log "---> Copied from site floppy-tree `echo; ls -laR ${dst}`" else log "---> No site-specific floppy-tree" fi # gzip returns an error if it fails to compress some file (cd $dst gzip -9 etc/* log "---> Compressed files in etc/ `echo; ls -l etc`" ) || true } create_mfs() { # OK log "---> Preparing MFS filesystem..." free_vnode # zero-fill the MFS image init_fs_image ${BUILDDIR}/${MFS_NAME} ${MFS_SIZE} log "---> Labeling MFS image" # Disklabel "auto" behaves strangely for sizes < 1024K. Basically # it fails to install a label on the system. On the other hand, # if you provide a specific disk type, the boot code is not # installed so you have more space on the disk... # For small image sizes, use std disktypes if [ ${MFS_SIZE} -lt 1024 ] ; then disklabel -rw ${VNDEV} fd${MFS_SIZE} || fail $? mfs_disklabel else disklabel -rw ${VNDEV} auto || fail $? mfs_disklabel fi newfs -i ${MFS_INODES} -m 0 -p 0 -o space /dev/${VNDEV}c > /dev/null mount /dev/${VNDEV}c ${MFS_MOUNTPOINT} || fail $? no_mount log "`df /dev/${VNDEV}c`" } # Populate the memory filesystem with binaries and non-variable # configuration files. # First do an mtree pass, then create directory links and device entries, # then run crunchgen etc. to build the binary and create links. # Then copy the specific/generic mfs_tree. # Finally, if required, make a copy of the floppy.tree onto /fd populate_mfs() { log "---> pwd=`pwd`, Populating MFS tree..." # cd ${THETYPE} log "---> Running mtree ..." if [ -f ${MY_TREE}/mfs.mtree ] ; then a=${MY_TREE}/mfs.mtree else a=${PICO_TREE}/build/mfs.mtree fi mtree -deU -f $a -p ${MFS_MOUNTPOINT} > /dev/null || fail $? mtree # XXX create links for i in ${STAND_LINKS}; do ln -s /stand ${MFS_MOUNTPOINT}/$i done ln -s /dev/null ${MFS_MOUNTPOINT}/var/run/log ln -s /etc/termcap ${MFS_MOUNTPOINT}/usr/share/misc/termcap # XXX-fixme in -current, MAKEDEV is from /usr/src/etc/MAKEDEV if [ "${NO_DEVFS}" != "" ] ; then - (cd ${MFS_MOUNTPOINT}/dev ; ln -s /dev/MAKEDEV ; + (cd ${MFS_MOUNTPOINT}/dev ; ln -s ${MAKEDEV} ; chmod 555 MAKEDEV ; ./MAKEDEV ${MY_DEVS}; rm MAKEDEV) fi ( cd ${BUILDDIR}/crunch log "---> Making and installing crunch1 from `pwd` src ${SRC}..." a=${BUILDDIR}/crunch1.conf ( export BUILDDIR SRC MY_TREE PICO_OBJ ; make -v -f ${PICO_TREE}/build/Makefile.conf ${BUILDDIR}/crunch.mk ) log "-- libs are ${LIBS} " export SRC LIBS CFLAGS # used by crunch.mk log "Now make -f crunch.mk" make ${makeopts} -f ${BUILDDIR}/crunch.mk strip --remove-section=.note --remove-section=.comment crunch1 mv crunch1 ${MFS_MOUNTPOINT}/stand/crunch chmod 555 ${MFS_MOUNTPOINT}/stand/crunch log "---> Making links for binaries..." for i in `crunchgen -l $a` ; do ln ${MFS_MOUNTPOINT}/stand/crunch ${MFS_MOUNTPOINT}/stand/${i}; done # rm $a # do not remove! ) || fail $? crunch if [ -f ${MFS_MOUNTPOINT}/stand/sshd ] ; then log "creating host key for sshd" ssh-keygen -f ${MFS_MOUNTPOINT}/etc/ssh_host_key -N "" -C "root@picobsd" fi if [ -d ${MY_TREE}/mfs_tree ]; then log "---> Copy site-specific MFS tree..." MFS_TREE=${MY_TREE}/mfs_tree else log "---> Copy generic MFS tree..." MFS_TREE=${PICO_TREE}/mfs_tree fi (cd ${MFS_TREE} ; tar -cf - --exclude CVS . ) | \ (cd ${MFS_MOUNTPOINT} ; tar x${TAR_VERBOSE}f - ) if [ "${INCLUDE_FLOPPY_IN_MFS}" = "yes" ]; then log "---> Copy generic floppy_tree into MFS..." cp -Rp ${BUILDDIR}/floppy.tree/* ${MFS_MOUNTPOINT}/fd fi (log "---> Fixing permissions"; cd ${MFS_MOUNTPOINT}; chown -R root . ) df -ik ${MFS_MOUNTPOINT} umount ${MFS_MOUNTPOINT} fsck -p /dev/${VNDEV}c free_vnode } final_cleanup() { free_vnode rm -rf ${MFS_MOUNTPOINT} ${RISU} 2> /dev/null || true } # fail errno errcode # This function is used to trap errors and print msgs # fail() { errno=$1 errcode=$2 echo "---> fail: Error <$errno> error code <$errcode>" case $errcode in no_vnconfig) echo "Error while doing vnconfig of ${imgname} on /dev/${VNDEV}..." echo " Most probably your running kernel doesn't have the ${VN}(4) device." ;; mfs_disklabel) echo "Error while labeling ${MFS_NAME} size ${MFS_SIZE}" ;; no_mount) echo "Error while mounting ${MFS_NAME} (/dev/${VNDEV}c) on ${MFS_MOUNTPOINT}" ;; mtree) echo "Error while making hierarchy in ${MFS_MOUNTPOINT}" ;; crunch) echo "Error while building ${name}." ;; floppy_disklabel) echo "Error while doing disklabel on of floppy.img size $FLOPPY_SIZE" ;; missing_kernel) echo "Error: you must build PICOBSD${suffix} kernel first" ;; includes) echo "Error: failed while making includes" ;; libraries) echo "Error: failed while making libraries" ;; "") echo "User break" errcode="userbreak"; ;; *) echo "unknown error, maybe user break: $errno $errcode" ;; esac echo "---> Aborting $0" # try to cleanup the vnode. final_cleanup exit 2 } # # Create a zero-filled disk image with a boot sector, and vnconfig it. # init_fs_image() { # filename size_in_kbytes imgname=$1 ; imgsize=$2 dd if=/dev/zero of=${imgname} count=${imgsize} bs=1k 2> /dev/null dd if=${boot1} of=${imgname} conv=notrunc 2> /dev/null if [ "${VN}" = "vn" ] ; then vnconfig -c -s labels ${VNDEV} ${imgname} || fail $? no_vnconfig else mdconfig -a -t vnode -u ${VNUM} -f ${imgname} || fail $? no_vnconfig fi } fill_floppy_image() { log "---> Preparing ${FLOPPY_SIZE}kB floppy filesystem..." # correct block and number of sectors according to size. blocks=${FLOPPY_SIZE}; sectors=18 if [ "${blocks}" = "1720" ]; then blocks=1722 ; sectors=21 elif [ "${blocks}" = "1480" ]; then blocks=1476 ; fi init_fs_image ${BUILDDIR}/picobsd.bin ${blocks} log "---> Labeling floppy image" b2=${BUILDDIR}/boot2 # modified boot2 perl -pne 's/\/boot\/loader/\/kernel\0\0\0\0\0/' ${boot2} > ${b2} disklabel -Brw -b ${boot1} -s ${b2} ${VNDEV} fd${FLOPPY_SIZE} || \ fail $? floppy_disklabel newfs -i ${FLOPPY_INODES} -m 0 -p 0 -o space /dev/${VNDEV}c > /dev/null mount /dev/${VNDEV}c ${MFS_MOUNTPOINT} # preload kernel, compress with kgzip and copy to floppy image ( cd ${BUILDDIR} cc -o wmk ${PICO_TREE}/../write_mfs_in_kernel.c ./wmk kernel ${MFS_NAME} rm wmk kgzip -o kernel.gz kernel cp -p kernel.gz ${MFS_MOUNTPOINT}/kernel # now transfer the floppy tree. If it is already in mfs, dont bother. if [ "${INCLUDE_FLOPPY_IN_MFS}" != "yes" ]; then cp -Rp floppy.tree/* ${MFS_MOUNTPOINT} fi ) (log "---> Fixing permissions"; cd ${MFS_MOUNTPOINT}; chown -R root *) rm -rf ${BUILDDIR}/floppy.tree || true # cleanup df -ik ${MFS_MOUNTPOINT} | colrm 70 > .build.reply free_vnode rm -rf ${MFS_MOUNTPOINT} rm ${BUILDDIR}/kernel.gz ${BUILDDIR}/${MFS_NAME} } #------------------------------------------------------------------- # Main entry of the script verbose="" TAR_VERBOSE="" CONFIG=config while [ true ]; do case $1 in --src) # set the source path instead of /usr/src SRC=$2 if [ "$3" = "--init" ] ; then shift # Optionally creates include directory and libraries. mkdir -p ${SRC}/usr/include # the include directory... mkdir -p ${SRC}/usr/share/misc # a few things go here mkdir -p ${SRC}/usr/lib # libraries (cd ${SRC}; INCOWN=`id -un` DESTDIR=${SRC} make includes ) || \ fail $? includes # libraries already have the include path in the Makefile CFLAGS="-nostdinc" ; export CFLAGS (cd ${SRC} # $e is the invocation of make with correct environment e="MAKEOBJDIRPREFIX=/usr/obj-pico/picobsd/libraries \ BINOWN=`id -un` DESTDIR=${SRC} \ make -DNOHTML -DNOINFO -DNOMAN -DNOSHARE -DNOFSCHG " # need to 'make obj' in a few places. This is very # version-specific... The following works for 5.0 for i in lib secure/lib gnu/lib usr.sbin/pcvt/keycap \ gnu/usr.bin/perl usr.bin/lex ; do (cd ${i}; eval $e obj) done # now make the static libraries eval $e -DNOPROFILE -DNOPIC libraries ) || fail $? "libraries" log "libraries done" fi # pass the right LIBS and CFLAGS to the Makefile, # and build the config program LIBS="-L${SRC}/usr/lib" CFLAGS="-nostdinc -I${SRC}/usr/include" export LIBS CFLAGS (cd ${SRC}/usr.sbin/config ; CFLAGS="" make ) CONFIG=${SRC}/usr.sbin/config/config shift ;; --floppy_size) FLOPPY_SIZE=$2 shift ;; -n) interactive="NO" ;; -c*) # clean clean="YES" interactive="NO" ;; -v) verbose="YES" TAR_VERBOSE="v" makeopts="-d l" # be verbose ;; *) break ; ;; esac shift done init_vars THETYPE=$1 SITE=$2 set_type $THETYPE # If $1="package", it creates a neat set of floppies if [ "$1" = "package" ] ; then build_package fi if [ "$interactive" != "NO" ] ; then main_dialog fi if [ "$clean" = "YES" ] ; then clean_tree else build_image do_install fi final_cleanup exit 0