]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - release/picobsd/build/picobsd
Autogenerate hardware notes for hptrr(4).
[FreeBSD/FreeBSD.git] / release / picobsd / build / picobsd
1 #!/bin/sh -
2 #
3 # $FreeBSD$
4 # This file requires sysutils/makefs to run
5 #
6 # The new PicoBSD build script. Invoked as
7 #
8 # picobsd [options] floppy_type site_name
9 #
10 # Where floppy_type is a directory where the picobsd config info
11 # is held, and ${floppy_type}/floppy.tree.${site_name} contains
12 # optional site-specific configuration.
13 #
14 # For Options, see the bottom of the file where the processing is
15 # done. The picobsd(8) manpage might be of some help, but code and docs
16 # tend to lose sync over time...
17 #
18 # This script depends on the following files:
19 #
20 # in ${PICO_TREE} :
21 #   Makefile.conf       Makefile used to build the kernel
22 #   config              shell variables, sourced here.
23 #   mfs.mtree           mtree config file
24 #
25 #   floppy.tree/        files which go on the floppy
26 #   mfs_tree/           files which go onto the mfs
27 #
28 # in ${MY_TREE} :
29 #   PICOBSD             kernel config file
30 #   config              shell variables, sourced here.
31 #   crunch.conf         crunchgen configuration
32 #   floppy.tree.exclude files from floppy.tree/ which we do not need here.
33 #   floppy.tree/        local additions to the floppy.tree
34 #   floppy.tree.${site}/ same as above, site specific.
35 #   mfs_tree/           local additions to the mfs_free
36
37 #
38 #--- The main entry point is at the end.
39 #
40
41 # There are two set of initialization. The first one (set_defaults)
42 # is done on entry to the script, and is used to set default values
43 # for all variables which do not depend on floppy type and source tree.
44 #
45 # The second set is done after command line parsing, e.g.
46 # to resolve dependencies on the source tree.
47 #
48 # Naming:
49 # + variables that control operation (e.g. verbosity) and are generally
50 #   set from the command line have o_ ("option") as a name prefix
51 #
52 # + variables which contain pathnames and values that should not change
53 #   have c_ ("constant") as a name prefix
54 #
55 # + variables exported to Makefiles and subshells are CAPITAL
56 #
57 # + variables local to the script are lowercase, possibly with
58 #   an l_ ("local") prefix
59
60 # SRC points to your FreeBSD source tree.
61 # l_usrtree points to the /usr subdir for the source tree.
62 #     Normally /usr or ${SRC}/../usr
63 # l_objtree points to the obj tree. Normally ${l_usrtree}/obj-pico
64 # PICO_TREE is where standard picobsd stuff resides.
65 #     Normally ${SRC}/release/picobsd
66 # You can set SRC with --src <directory>
67 # It is not recommended to override the other variables.
68
69 # MY_TREE (set later) is where this floppy type resides.
70 # BUILDDIR is the build directory
71
72 # set some default values for variables.
73 # needs to be done as the first thing in the script.
74
75 # log something on stdout if verbose.
76 o_verbose=0     # this needs to be here!
77 log() {
78     local foo
79     [ ${o_verbose} -gt 0 ] && printf "\n*** %s\n" "$*"
80     [ ${o_verbose}  -gt 1 ] && read -p "=== Press enter to continue" foo
81     return 0
82 }
83
84 logverbose() {
85     local foo
86     printf "\n*** %s\n" "$*"
87     read -p "=== Press enter to continue" foo
88     return 0
89 }
90
91 set_defaults() {
92     # no way to use logging in this function, variable not set yet.
93
94     # EDITOR is the editor you use
95     # fd_size  floppy size in KB (default to 1440). You can use 1480,
96     #   1720, 2880, etc. but beware that only 1440 and 1480 will boot
97     #   from 1.44M floppy drives (1480 will not work on vmware).
98     EDITOR=${EDITOR:-vi}
99     fd_size=${fd_size:-1440}
100
101     o_all_in_mfs="yes"          # put all files in mfs so you can boot and run
102                                 # the image via diskless boot.
103     o_clean=""                  # do not clean
104     o_interactive=""            # default is interactive
105     o_verbose=0                 # verbose level, 0 is silent
106     o_tarv=""                   # tar verbose flag, "" or "v"
107     o_init_src=""               # non "" if we need to init libs and includes.
108     o_makeopts=${MAKEOPTS:--s}  # make options, be silent by default
109     o_no_devfs=yes              # we do not want devfs
110     o_do_modules=""             # do not build modules
111
112     SRC="/usr/src"              # default location for sources
113     c_startdir=`pwd`            # directory where we start
114                                 # used to lookup config and create BUILDDIR
115
116     # XXX 6.x/7.x have a single /boot/boot block, which is the concatenation
117     # of the old two. For the time being, we keep these, but this should
118     # be fixed at some point.
119
120     # blocks
121     c_boot1=/boot/boot1         # boot blocks (in case you want custom ones)
122     c_boot2=/boot/boot2
123
124     c_reply=${c_reply:-`mktemp "/tmp/reply.XXXXXXXXXX"`}
125                                 # file where User replies will be put
126     c_mnt=`mktemp -d "/tmp/picobsd.XXXXXXXXXX"`
127                                 # mountpoint used to build memory filesystems
128     c_fs=fs.PICOBSD             # filename used for the memory filesystem
129     c_img=picobsd.bin           # filename used for the picobsd image
130
131     # select the right memory disk name
132     case `uname -r` in
133         7.*|6.*|5.*)
134             l_label="bsdlabel"
135             ;;
136         *)
137             l_label="disklabel"
138             ;;
139     esac
140
141     set -e
142
143     trap fail 2
144     #trap fail 3
145     #trap fail 6
146     trap fail 15
147 }
148
149 create_includes_and_libraries2() {
150     local no
151     log "create_includes_and_libraries2() for ${SRC}"
152     if [ ${OSVERSION} -ge 600000 ] ; then
153         no="-DNO_CLEAN -DNO_PROFILE -DNO_GAMES -DNO_LIBC_R"
154     else
155         no="-DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R"
156     fi
157     MAKEOBJDIRPREFIX=${l_objtree}
158     export MAKEOBJDIRPREFIX
159     ( cd ${SRC};
160     # make -DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R -DPICOBSD buildworld
161     make _+_= $no toolchain
162     )
163 }
164
165 # entry for 4.x and earlier trees
166 create_includes_and_libraries() {
167     local e i
168
169     log "create_includes_and_libraries() for ${SRC}"
170     # Optionally creates include directory and libraries.
171     mkdir -p ${l_usrtree}/include               # the include directory...
172     mkdir -p ${l_usrtree}/share/misc    # a few things go here
173     mkdir -p ${l_usrtree}/lib           # libraries
174     mkdir -p ${l_usrtree}/sbin          # some binaries
175     # override variables for ownershiip and destinations
176     # BINOWN:BINGRP are also used for include files
177     (cd ${SRC}; \
178         BINOWN=`id -un` BINGRP=`id -gn` \
179         DESTDIR=${l_usrtree}/.. \
180         make -m ${SRC}/share/mk includes ) || fail $? includes
181     # Pick up the correct headers for libraries.
182     CFLAGS="-nostdinc -I${l_usrtree}/include" ; export CFLAGS
183
184     (cd ${SRC}
185         # $e is the invocation of make with correct environment
186         # XXX check the NO* options below, maybe system dependent.
187         e="MAKEOBJDIRPREFIX=${l_objtree}/picobsd/libraries \
188             BINOWN=`id -un` BINGRP=`id -gn` \
189             DESTDIR=${l_usrtree}/.. \
190             make -m ${SRC}/share/mk \
191                 -DNOHTML -DNOINFO -DNOMAN -DNOSHARE -DNOFSCHG "
192         log "do a 'make obj' in a few places."
193         # This is very version-specific... The following works for 5.0
194         for i in lib secure/lib gnu/lib \
195                 gnu/usr.bin/perl usr.bin/lex usr.sbin/config ; do
196             (cd ${i}; eval $e obj)
197         done
198         log "now make the static libraries"
199         eval $e -DNOPROFILE -DNOPIC libraries
200         (cd ${SRC}/usr.sbin/config
201         eval $e         # build binary
202         eval $e install # install it
203         )
204     ) || fail $? "libraries"
205     log "Libraries done"
206 }
207
208 # set_type <type> looks in user or system directories for the floppy type
209 # specified as first argument, and sets variables according to the config.
210 # file. Sets THETYPE, SITE, name, MY_TREE and BUILDDIR
211
212 set_type() {
213     local a i
214
215     log "set_type() : Type '$1' site '$2'"
216     THETYPE=$1
217     SITE=$2
218     a=$1
219     name=""     # clear in case of errors
220     for i in ${c_startdir}/${a} ${PICO_TREE}/${a} ; do
221         log "set_type: checking $i"
222         [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ] || continue
223         set -- `cat $i/PICOBSD | \
224             awk '/^#PicoBSD/ {print $2, $3, $4, $5, $6}'`
225         [ x"$1" != "x" ] || continue
226         MFS_SIZE=$1 ; init_name=$2
227         mfs_inodes=$3 ; fd_inodes=$4
228         name=`(cd $i ; pwd) `
229         name=`basename $name`
230         MY_TREE=$i
231         BUILDDIR=${c_startdir}/build_dir-${name}
232         log "Matching file $name in $i"
233         return ;
234     done
235     logverbose "Type $a NOT FOUND"
236 }
237
238 clean_tree() {
239     log "clean_tree()"
240     if [ "${name}" = "" ] ; then
241         echo "---> Wrong floppy type"
242         exit 3
243     fi
244     rm -rf ${BUILDDIR}
245 }
246
247 # prepare a message to be printed in the dialog menus.
248 set_msgs() {            # OK
249     log "set_msgs()"
250
251     MSG1="Type: ${THETYPE} name $name"
252
253     MSG="PicoBSD build -- Current parameters:\n\n\t1.  ${MSG1}\n\
254 \t2.  MFS size: ${MFS_SIZE} kB\n\
255 \t3.  Site-info: ${SITE}\n\t4.  Full-path: ${MY_TREE}\n"
256 }
257
258
259 # Main build procedure.
260 build_image() {
261     log "build_image() <${name}>"
262     [ "${name}" != "" ] || fail $? bad_type
263     clear
264     set_msgs
265     printf "${MSG}---> We'll use the sources living in ${SRC}\n\n"
266
267     # read config variables from a global and then a type-specific file
268     # basically STAND_LINKS and MY_DEVS, but can also override other
269     # variables.
270     # 
271     . ${PICO_TREE}/build/config
272     if [ -f ${MY_TREE}/config ] ; then
273         . ${MY_TREE}/config
274     fi
275
276     # location of the object directory
277     PICO_OBJ=${l_objtree}/picobsd/${THETYPE}
278     log "PICO_OBJ is ${PICO_OBJ}"
279
280     if [ ${OSVERSION} -ge 500035 ] ; then
281         export MAKEOBJDIRPREFIX=${l_objtree}
282         eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V BINMAKE`\""
283         eval export `cd ${SRC}; ${BINMAKE} -f Makefile.inc1 -V WMAKEENV`
284     fi
285     # create build directory and subtree
286     mkdir -p ${BUILDDIR}/crunch
287     # remove any old stuff
288     rm -f ${BUILDDIR}/kernel.gz ${BUILDDIR}/${c_fs}
289     # invoke commands to build a kernel
290     do_kernel
291     # fill a subdirectory with things that go into the floppy
292     # (mostly /etc and similar stuff)
293     populate_floppy_fs
294     # populate it and produce a file with the MFS image
295     populate_mfs_tree           # things which go into mfs
296     # create, mount and fill a filesystem with floppy image
297     fill_floppy_image # copies everything into the floppy
298 }
299
300 build_package() {
301     local z msg
302
303     log "build_package()"
304     rm -rf build.status
305     echo "##############################################" >>build.status
306     echo "## `date` ">>build.status
307     echo "##############################################" >>build.status
308     for z in bridge dial router net isp ; do
309         set_type ${z}
310         if [ "${name}" = "" ] ; then
311             echo "*** TYPE=${z} not found" >>build.status
312             continue
313         fi
314         echo "---------------------------------------------">>build.status
315         echo "Building TYPE=${z}, SIZE=${MFS_SIZE}" >>build.status
316         msg="(ok)"      # error message
317         build_image || msg="** FAILED! **"
318         echo "  ${msg}">>build.status
319         # where do i put things ?
320         # clean_tree
321     done
322     exit 0
323 }
324
325 # Set build parameters interactively
326
327 main_dialog() {
328   local ans i l
329
330   log "main_dialog()"
331   while [ true ] ; do
332     set_msgs
333     rm ${c_reply}
334     dialog --menu "PicoBSD build menu -- (29 sep 2001)" 19 70 12 \
335         N "--> READY, build it <---" \
336         T "${MSG1}" \
337         K "edit Kernel config file" \
338         E "Edit crunch.conf file" \
339         S "MFS Size: ${MFS_SIZE}kB" \
340         I "Init type: ${init_name}" \
341         F "Floppy size: ${fd_size}kB" \
342         M "MFS bytes per inode: ${mfs_inodes}" \
343         U "UFS bytes per inode: ${fd_inodes}" \
344         $ "Site-info: ${SITE}" \
345         Q "Quit" \
346         2> ${c_reply}
347     ans=`cat ${c_reply}`
348     rm ${c_reply}
349     case ${ans} in
350     T)
351         l=""
352         for i in ${c_startdir} ${c_startdir}/* ${PICO_TREE}/* ; do
353             if [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ]; then
354                 l="$l `basename $i` `basename $i`"
355             fi
356         done
357         log $l
358         { dialog --menu "Setup the type of configuration" 12 70 5 $l \
359                 2> ${c_reply} && set_type "`cat ${c_reply}`" ${SITE} ; } || true
360         ;;
361     I)
362         { dialog --menu "Choose your init(8) program" \
363         10 70 2 init "Standard init (requires getty)" \
364         oinit "small init from TinyWare" 2> ${c_reply} \
365                 && init_name=`cat ${c_reply}` ; } || true
366         ;;
367
368     K) ${EDITOR} ${MY_TREE}/PICOBSD ;;
369
370     E) ${EDITOR} ${MY_TREE}/crunch.conf ;;
371
372     S)
373         { dialog --title "MFS Size setup" --inputbox \
374 "MFS size depends on what you need to put on the MFS image. Typically \
375 ranges between 820kB (for very small bridge/router images) to \
376 as much as 2500kB kB for a densely packed image. \
377 Keep in mind that this memory is \
378 totally lost to other programs. Usually you want to keep \
379 this as small as possible. " 10 70 2> ${c_reply} \
380         && MFS_SIZE=`cat ${c_reply}` ; } || true
381         ;;
382
383     \$)
384         { dialog --title "Site info setup" --inputbox \
385         "Please enter the full path to the directory \
386         containing site-specific setup. \
387         This directory tree must contain files that replace \
388         standard ones in floppy.tree/ and mfs.tree/ . " \
389         10 70 2> ${c_reply} && SITE=`cat ${c_reply}` ; } || true
390         ;;
391
392     F)
393         { dialog --menu "Set floppy size" 15 70 4 \
394             1440 "1.44MB" 1720 "1.72MB" 2880 "2.88MB" 4096 "4MB" \
395                  2> ${c_reply} && fd_size=`cat ${c_reply}` ; } || true
396         ;;
397
398     M)
399         { dialog --title "MFS bytes per inode:" --inputbox \
400         "Enter MFS bytes per inode (typically 4096..65536). \
401         A larger value means fewer inodes but more space on MFS" \
402         10 70 2> ${c_reply} && mfs_inodes=`cat ${c_reply}`  ; } || true
403         ;;
404
405     U)
406         { dialog --title "Floppy bytes per inode:" --inputbox \
407         "Enter floppy bytes per inode (typically 3072..65536). \
408         A larger value means fewer inodes but more space on the floppy." \
409         10 70 2> ${c_reply} && fd_inodes=`cat ${c_reply}` ; } || true
410         ;;
411
412     N) break 2
413         ;;
414
415     Q) exit 0 ;;
416
417     *) echo "\aUnknown option \"${ans}\". Try again."
418         sleep 2
419         clear
420         ;;
421     esac
422   done
423 }
424
425 # Call the build procedure
426 # Install image
427 do_install() {
428     log "do_install()"
429
430     if [ "${o_interactive}" = "NO" ] ; then
431         echo "+++ Build completed +++"
432         cat .build.reply || true
433         return
434     fi
435     dialog --title "Build ${THETYPE} completed" --inputbox \
436 "\nThe build process was completed successfuly.\n\
437 `cat .build.reply` \n\n\
438 Now we are going to install the image on the floppy.\n\
439 Please insert a blank floppy in /dev/fd0.\\n
440 WARNING: the contents of the floppy will be permanently erased!\n\
441 \n\
442 Your options:\n\
443         * ^C or [Cancel] to abort,\n\
444         * Enter to install ${c_img},\n\
445 " 20 80 2> ${c_reply}
446     if [ "$?" = "0" ]; then
447         echo "Writing ${c_img}..."
448         dd if=${BUILDDIR}/${c_img} of=/dev/fd0.${fd_size}
449     else
450         echo "Ok, the image is in ${c_img}"
451     fi
452     echo "Done."
453 }
454
455
456 #-------------------------------------------------------------------
457
458 # invoke the picobsd Makefile to compile the kernel.
459 # if MODULES is set (value is irrelevant) the makefile will build modules.
460 do_kernel() {           # OK
461     log "do_kernel() Preparing kernel \"$name\" in $MY_TREE"
462     (cd $MY_TREE; export name SRC BUILDDIR # used in this makefile ;
463         # export CONFIG
464         [ "${o_do_modules}" = "yes" ] && export MODULES=""
465         ${BINMAKE} -v -f ${PICO_TREE}/build/Makefile.conf ) || \
466         fail $? missing_kernel
467 }
468
469 # Populate the variable part of the floppy filesystem. Must be done before
470 # the MFS because its content might need to be copied there as well.
471 #
472 # This involves fetching files from three subtrees, in this order:
473 #
474 #  1. a standard one, from which type-specific files are excluded;
475 #  2. a type-specific one;
476 #  3. a site-specific one.
477 #
478 # Files are first copied to a local tree and then compressed.
479
480 populate_floppy_fs() {          # OK
481     local dst excl srcdir
482
483     log "populate_floppy_fs()"
484     dst=${BUILDDIR}/floppy.tree
485     log "pwd=`pwd` Populating floppy filesystem..."
486
487     # clean relics from old compilations.
488     rm -rf ${dst} || true
489     mkdir ${dst}
490
491     excl=${MY_TREE}/floppy.tree.exclude
492     if [ -f ${excl} ] ; then
493         log "Files excluded from generic tree: `echo;cat ${excl}`"
494         excl="--exclude-from ${excl}"
495     else
496         excl=""
497     fi
498     (cd ${PICO_TREE}/floppy.tree ; tar -cf - --exclude CVS ${excl} . ) | \
499                 (cd ${dst} ; tar x${o_tarv}f - )
500     log "Copied from generic floppy-tree `echo; ls -laR ${dst}`"
501
502     srcdir=${MY_TREE}/floppy.tree
503     if [ -d ${srcdir} ] ; then
504         log "update with type-specific files:"
505         (cd ${srcdir} ; tar -cf - --exclude CVS . ) | \
506             (cd ${dst} ; tar x${o_tarv}f - )
507         log "Copied from type floppy-tree `echo; ls -laR ${dst}`"
508     else
509         log "No type-specific floppy-tree"
510     fi
511     if [ -d ${srcdir}.${SITE} ] ; then
512         log "Update with site-specific (${SITE}) files:"
513         (cd ${srcdir}.${SITE} ; tar -cf - --exclude CVS . ) | \
514             (cd ${dst} ; tar x${o_tarv}f - )
515         log "Copied from site floppy-tree `echo; ls -laR ${dst}`"
516     else
517         log "No site-specific floppy-tree"
518     fi
519
520     # gzip returns an error if it fails to compress some file
521     (cd $dst ; gzip -9 etc/*
522             log "Compressed files in etc/ `echo; ls -l etc`"
523     ) || true
524 }
525
526 # Populate the memory filesystem with binaries and non-variable
527 # configuration files.
528 # First do an mtree pass, then create directory links and device entries,
529 # then run crunchgen etc. to build the binary and create links.
530 # Then copy the specific/generic mfs_tree.
531 # Finally, if required, make a copy of the floppy.tree onto /fd
532
533 populate_mfs_tree() {
534     local a dst
535
536     log "populate_mfs_tree()"
537     dst=${BUILDDIR}/mfs.tree
538     # clean relics from old compilations.
539     rm -rf ${dst} || true
540     mkdir ${dst}
541
542     log "pwd=`pwd`, Populating MFS tree..."
543
544     # use type-specific mfs.mtree, default to generic one.
545     a=${MY_TREE}/mfs.mtree
546     [ -f ${a} ] || a=${PICO_TREE}/build/mfs.mtree
547     log "Running mtree using $a..."
548     mtree -deU -f $a -p ${dst} > /dev/null || fail $? mtree
549
550     # XXX create links
551     for i in ${STAND_LINKS}; do
552         ln -s /stand ${dst}/$i
553     done
554     ln -s /dev/null ${dst}/var/run/log
555     ln -s /etc/termcap ${dst}/usr/share/misc/termcap
556
557
558     (
559     cd ${BUILDDIR}/crunch
560     log "Making and installing crunch1 from `pwd` src ${SRC}..."
561     a=${BUILDDIR}/crunch1.conf
562     ( export BUILDDIR SRC MY_TREE PICO_OBJ ;
563         ${BINMAKE} \
564                 -v -f ${PICO_TREE}/build/Makefile.conf ${BUILDDIR}/crunch.mk )
565     log "Libs are ${LIBS} "
566     export SRC # used by crunch.mk
567     # export LIBS CFLAGS
568     log "Now make -f crunch.mk"
569     ${BINMAKE} ${o_makeopts} -f ${BUILDDIR}/crunch.mk
570     strip --remove-section=.note --remove-section=.comment crunch1
571     mv crunch1 ${dst}/stand/crunch
572     chmod 555 ${dst}/stand/crunch
573     log "Making links for binaries..."
574     for i in `crunchgen -l $a` ; do
575         ln ${dst}/stand/crunch ${dst}/stand/${i};
576     done
577     # rm $a # do not remove!
578     ) || fail $? crunch
579
580     if [ -f ${dst}/stand/sshd ] ; then
581         log "Setting up host key for sshd:"
582         if [ -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key.gz ] ; then
583             log "Using existing host key"
584         else
585             log "Generating new host key" 
586             ssh-keygen -t rsa1 -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key \
587                  -N "" -C "root@picobsd"
588             gzip -9 ${BUILDDIR}/floppy.tree/etc/ssh_host_key* || true
589         fi
590     fi
591
592     log "Copy generic and site-specific MFS tree..."
593     for MFS_TREE in ${PICO_TREE}/mfs_tree ${MY_TREE}/mfs_tree ; do
594         if [ -d ${MFS_TREE} ] ; then
595             log "Copy ${MFS_TREE} ..."
596             (cd ${MFS_TREE} ; tar -cf - --exclude CVS . ) | \
597                     (cd ${dst} ; tar x${o_tarv}f - )
598         fi
599     done
600
601     if [ "${o_all_in_mfs}" = "yes" ]; then
602         log "Copy generic floppy_tree into MFS..."
603         # this may fail in case the floppy is empty
604         cp -Rp ${BUILDDIR}/floppy.tree/* ${dst}/fd || true
605     fi
606
607     if [ "${o_no_devfs}" != "" ] ; then
608         # create device entries using MAKEDEV
609         (cd ${dst}/dev
610         ln -s ${SRC}/etc/MAKEDEV ; chmod 555 MAKEDEV
611         # log `pwd`
612         sh ./MAKEDEV ${MY_DEVS}
613         rm MAKEDEV
614         )
615     fi
616     if [ "`id -u`" = "0" ] ; then
617         log "Fixing permissions"
618         (cd ${dst}; chown -R root . )
619     fi
620
621     if [ -n "${import_files}" ] ; then
622         log "importing ${import_files} into mfs"
623         # We do it in a chroot environment on the target so
624         # symlinks are followed correctly.
625         cp `which tar` ${dst}/my_copy_of_tar
626         (cd ${l_usrtree}/.. ; tar cf - ${import_files} ) | \
627             (chroot ${dst} /my_copy_of_tar xf - )
628         rm ${dst}/my_copy_of_tar
629     fi
630
631     (cd ${BUILDDIR}
632         # override the owner
633         echo "/set uid=0 gid=0" > mtree.out
634         mtree -c -p ${dst} -k "" >> mtree.out
635         log "mtre.out at ${BUILDDIR}/mtree.out"
636         makefs -t ffs -o bsize=4096 -o fsize=512 \
637                 -s ${MFS_SIZE}k -f 100 -F mtree.out ${c_fs} ${dst}
638         ls -l ${c_fs} )
639     log "done mfs image"
640 }
641
642 final_cleanup() {
643     log "final_cleanup()"
644     rm -rf ${c_mnt} ${c_reply} 2> /dev/null || true
645     rm -f ${c_reply}
646 }
647
648 # fail errno errcode
649 # This function is used to trap errors and print msgs
650 #
651 fail() {
652     local errno errocode where
653
654     errno=$1
655     errcode=$2
656     where=$3
657     echo "---> fail: Error <${errno}> error code <${errcode}> in <${where}>"
658     case ${errcode} in
659     mtree)
660         echo "Error while making hierarchy in ${c_mnt}"
661         ;;
662     crunch)
663         echo "Error while building ${name}."
664         ;;
665     missing_kernel)
666         echo "Error: you must build PICOBSD${suffix} kernel first"
667         ;;
668     includes)
669         echo "Error: failed while making includes"
670         ;;
671     libraries)
672         echo "Error: failed while making libraries"
673         ;;
674     bad_type)
675         echo "Error: unknown floppy type ${name}"
676         ;;
677     no_space)
678         echo "Error: no space left on device (${where})"
679         ;;
680     no_mfs)
681         echo "Error: while writing MFS into the kernel."
682         ;;
683     "")
684         echo "User break"
685         errcode="userbreak"
686         ;;
687     *)
688         echo "unknown error, maybe user break: $errno $errcode"
689         ;;
690     esac
691     echo "---> Aborting $0"
692     # try to cleanup the vnode.
693     final_cleanup
694     exit 2
695 }
696
697 fill_floppy_image() {
698     local blocks dst mfs_start mfs_end mfs_size img_size
699
700     log "fill_floppy_image()"
701     dst=${c_mnt}        # where to create the image
702
703     log "Preparing ${fd_size}kB floppy filesystem..."
704
705     # correct blocks according to size.
706     blocks=${fd_size};
707     if [ "${blocks}" = "1720" ]; then
708         blocks=1722
709     elif [ "${blocks}" = "1480" ]; then
710         blocks=1476
711     fi
712
713     log "Labeling floppy image"
714     log "patch ${c_boot2} to boot /kernel right away"
715     b2=${BUILDDIR}/boot2 # modified boot2
716     cp -f ${c_boot2} ${b2}
717     chmod 0644 ${b2}
718
719     set `strings -at d ${b2} | grep "/boot/loader"`
720     echo -e "/kernel\0\0\0\0\0" | \
721         dd of=${b2} obs=$1 oseek=1 conv=notrunc 2>/dev/null
722     chmod 0444 ${b2}
723
724     dst=${BUILDDIR}/image.tree
725     rm -rf ${dst}
726     mkdir -p ${dst}
727     (
728     cd ${BUILDDIR}
729     set 0 0 # reset variables
730     # $1 takes the offset of the MFS filesystem
731     set `strings -at d kernel | grep "MFS Filesystem goes here"`
732     mfs_start=$1
733     set 0 0 # reset variables
734     set `strings -at d kernel | grep "MFS Filesystem had better"`
735     mfs_end=$1
736     mfs_size="$((${mfs_end} - ${mfs_start}))"
737     set -- `ls -l ${c_fs}`; imgsize="$5"
738     if [ ${mfs_start} -gt 0 -a ${mfs_size} -ge ${imgsize} ] ; then
739         mfs_ofs=$((${mfs_start} + 8192))
740         log "Preload kernel with file ${c_fs} at ${mfs_ofs}"
741         dd if=${c_fs} ibs=8192 iseek=1 of=kernel obs=${mfs_ofs} \
742             oseek=1 conv=notrunc 2> /dev/null
743     else
744         log "not loading mfs, size ${mfs_size} img ${imgsize}"
745     fi
746     log "Compress with kgzip and copy to floppy image"
747     kgzip -o kernel.gz kernel
748     cp -p kernel.gz ${dst}/kernel || fail $? no_space "copying kernel"
749
750     log "Now transfer floppy tree if not already in MFS image"
751     # now transfer the floppy tree. If it is already in mfs, dont bother.
752     if [ "${o_all_in_mfs}" != "yes" ] ; then
753         cp -Rp floppy.tree/* ${dst} || \
754                 fail $? no_space "copying floppy tree"
755     fi
756     )
757     (cd ${BUILDDIR}
758     makefs -t ffs -o bsize=4096 -o fsize=512 \
759         -s ${blocks}k -f 50 ${c_img} ${dst}
760     # ${l_label} -f `pwd`/${c_img}
761     ${l_label} -w -f `pwd`/${c_img} auto # write in a label
762     # copy partition c: into a: with some sed magic
763     ${l_label} -f `pwd`/${c_img} | sed -e '/  c:/{p;s/c:/a:/;}' | \
764         ${l_label} -R -f `pwd`/${c_img} /dev/stdin
765     ${l_label} -f `pwd`/${c_img}
766     ls -l ${c_img}
767         logverbose "after disklabel"
768          )
769     # dump the primary and secondary boot
770     # XXX primary is 512 bytes
771     dd if=${c_boot1} of=${BUILDDIR}/${c_img} conv=notrunc 2>/dev/null
772     # XXX secondary starts after the 0x114 = dec 276 bytes of the label
773     # so we skip 276 from the source, and 276+512=788 from dst
774     # the old style blocks used 512 and 1024 respectively
775
776     dd if=${b2} iseek=1 ibs=276 2> /dev/null | \
777         dd of=${BUILDDIR}/${c_img} oseek=1 obs=788 conv=notrunc 2>/dev/null
778     logverbose "done floppy image"
779     # XXX (log "Fixing permissions"; cd ${dst}; chown -R root *)
780     rm -rf ${BUILDDIR}/floppy.tree || true # cleanup
781     # df -ik ${dst} | colrm 70 > .build.reply
782     rm -rf ${dst}
783     rm ${BUILDDIR}/kernel.gz ${BUILDDIR}/${c_fs}
784 }
785
786 # This function creates variables which depend on the source tree in use:
787 # SRC, l_usrtree, l_objtree
788 # Optionally creates libraries, includes and the like (for cross compiles,
789 # needs to be done once).
790
791 set_build_parameters() {
792     log "set_build_parameters() SRC is ${SRC}"
793     if [ "${SRC}" = "/usr/src" ] ; then
794         l_usrtree=${USR:-/usr}
795     else
796         l_usrtree=${USR:-${SRC}/../usr}
797     fi
798     l_objtree=${l_usrtree}/obj-pico
799     PICO_TREE=${PICO_TREE:-${SRC}/release/picobsd}
800     set `grep "#define[\t ]__FreeBSD_version" ${SRC}/sys/sys/param.h`
801     OSVERSION=$3
802     log "OSVERSION is ${OSVERSION}"
803     if [ "${o_init_src}" != "" ] ; then
804         if [ ${OSVERSION} -lt 500035 ] ; then
805             create_includes_and_libraries
806         else
807             create_includes_and_libraries2
808         fi
809     fi
810     if [ ${OSVERSION} -lt 500035 ] ; then
811         # Create the right LIBS and CFLAGS for further builds.
812         # and build the config program
813         LIBS="-L${l_usrtree}/lib"
814         CFLAGS="-nostdinc -I${l_usrtree}/include"
815         export LIBS CFLAGS
816         CONFIG=${l_usrtree}/sbin/config
817         export CONFIG
818     fi
819 }
820
821 #-------------------------------------------------------------------
822 # Main entry of the script. Initialize variables, parse command line
823 # arguments.
824
825 set_defaults
826 args=""
827 while [ x"$1" != x ]; do
828     case $1 in
829     --src)      # set the source path instead of /usr/src
830         SRC=`(cd $2; pwd)`
831         shift
832         ;;
833     --init)
834         o_init_src="YES"
835         ;;
836
837     --floppy_size)
838         fd_size=$2
839         shift
840         ;;
841
842     --all_in_mfs)
843         o_all_in_mfs="yes"
844         ;;
845
846     --no_all_in_mfs)
847         o_all_in_mfs=""
848         ;;
849
850     --modules)  # also build kernel modules
851         o_do_modules="yes"
852         ;;
853     -n)
854         o_interactive="NO"
855         ;;
856
857     -clear|-clean|-c) # clean
858         o_clean="YES"
859         o_interactive="NO"
860         ;;
861
862     -v) # need -v -v to wait for user input
863         o_verbose=$((${o_verbose}+1))   # verbose level
864         o_tarv="v"                      # tar verbose flag
865         o_makeopts="-d l" # be verbose
866         ;;
867     *)
868         args="$args $1"                 # accumulate args
869         ;;
870
871     esac
872     shift
873 done
874 set_build_parameters    # things that depend on ${SRC}
875
876 # If $1="package", it creates a neat set of floppies
877 set -- ${args}
878 [ "$1" = "package" ] && build_package
879
880 set_type $args          # type and site, respectively
881
882 [ "${o_interactive}" != "NO" ] && main_dialog
883
884 if [ "${o_clean}" = "YES" ] ; then
885     clean_tree
886 else
887     build_image
888     do_install
889 fi
890 final_cleanup
891 exit 0