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