nanobsd.sh revision 215070
1#!/bin/sh 2# 3# Copyright (c) 2005 Poul-Henning Kamp. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26# 27# $FreeBSD: head/tools/tools/nanobsd/nanobsd.sh 215070 2010-11-10 00:56:44Z imp $ 28# 29 30set -e 31 32####################################################################### 33# 34# Setup default values for all controlling variables. 35# These values can be overridden from the config file(s) 36# 37####################################################################### 38 39# Name of this NanoBSD build. (Used to construct workdir names) 40NANO_NAME=full 41 42# Source tree directory 43NANO_SRC=/usr/src 44 45# Where nanobsd additional files live under the source tree 46NANO_TOOLS=tools/tools/nanobsd 47 48# Where cust_pkg() finds packages to install 49NANO_PACKAGE_DIR=${NANO_SRC}/${NANO_TOOLS}/Pkg 50NANO_PACKAGE_LIST="*" 51 52# Object tree directory 53# default is subdir of /usr/obj 54#NANO_OBJ="" 55 56# The directory to put the final images 57# default is ${NANO_OBJ} 58#NANO_DISKIMGDIR="" 59 60# Parallel Make 61NANO_PMAKE="make -j 3" 62 63# The default name for any image we create. 64NANO_IMGNAME="_.disk.full" 65 66# Options to put in make.conf during buildworld only 67CONF_BUILD=' ' 68 69# Options to put in make.conf during installworld only 70CONF_INSTALL=' ' 71 72# Options to put in make.conf during both build- & installworld. 73CONF_WORLD=' ' 74 75# Kernel config file to use 76NANO_KERNEL=GENERIC 77 78# Kernel modules to build; default is none 79NANO_MODULES= 80 81# Customize commands. 82NANO_CUSTOMIZE="" 83 84# Late customize commands. 85NANO_LATE_CUSTOMIZE="" 86 87# Newfs paramters to use 88NANO_NEWFS="-b 4096 -f 512 -i 8192 -O1 -U" 89 90# The drive name of the media at runtime 91NANO_DRIVE=ad0 92 93# Target media size in 512 bytes sectors 94NANO_MEDIASIZE=1200000 95 96# Number of code images on media (1 or 2) 97NANO_IMAGES=2 98 99# 0 -> Leave second image all zeroes so it compresses better. 100# 1 -> Initialize second image with a copy of the first 101NANO_INIT_IMG2=1 102 103# Size of code file system in 512 bytes sectors 104# If zero, size will be as large as possible. 105NANO_CODESIZE=0 106 107# Size of configuration file system in 512 bytes sectors 108# Cannot be zero. 109NANO_CONFSIZE=2048 110 111# Size of data file system in 512 bytes sectors 112# If zero: no partition configured. 113# If negative: max size possible 114NANO_DATASIZE=0 115 116# Size of the /etc ramdisk in 512 bytes sectors 117NANO_RAM_ETCSIZE=10240 118 119# Size of the /tmp+/var ramdisk in 512 bytes sectors 120NANO_RAM_TMPVARSIZE=10240 121 122# Media geometry, only relevant if bios doesn't understand LBA. 123NANO_SECTS=63 124NANO_HEADS=16 125 126# boot0 flags/options and configuration 127NANO_BOOT0CFG="-o packet -s 1 -m 3" 128NANO_BOOTLOADER="boot/boot0sio" 129 130# boot2 flags/options 131# default force serial console 132NANO_BOOT2CFG="-h" 133 134# Backing type of md(4) device 135# Can be "file" or "swap" 136NANO_MD_BACKING="file" 137 138# Progress Print level 139PPLEVEL=3 140 141# Set NANO_LABEL to non-blank to form the basis for using /dev/ufs/label 142# in preference to /dev/${NANO_DRIVE} 143# Root partition will be ${NANO_LABEL}s{1,2} 144# /cfg partition will be ${NANO_LABEL}s3 145# /data partition will be ${NANO_LABEL}s4 146NANO_LABEL="" 147 148####################################################################### 149# Architecture to build. Corresponds to TARGET_ARCH in a buildworld. 150# Unfortunately, there's no way to set TARGET at this time, and it 151# conflates the two, so architectures where TARGET != TARGET_ARCH do 152# not work. This defaults to the arch of the current machine. 153 154NANO_ARCH=`uname -p` 155 156# Directory to populate /cfg from 157NANO_CFGDIR="" 158 159# Directory to populate /data from 160NANO_DATADIR="" 161 162####################################################################### 163# 164# The functions which do the real work. 165# Can be overridden from the config file(s) 166# 167####################################################################### 168 169clean_build ( ) ( 170 pprint 2 "Clean and create object directory (${MAKEOBJDIRPREFIX})" 171 172 if ! rm -rf ${MAKEOBJDIRPREFIX} > /dev/null 2>&1 ; then 173 chflags -R noschg ${MAKEOBJDIRPREFIX} 174 rm -r ${MAKEOBJDIRPREFIX} 175 fi 176 mkdir -p ${MAKEOBJDIRPREFIX} 177 printenv > ${MAKEOBJDIRPREFIX}/_.env 178) 179 180make_conf_build ( ) ( 181 pprint 2 "Construct build make.conf ($NANO_MAKE_CONF_BUILD)" 182 183 echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_BUILD} 184 echo "${CONF_BUILD}" >> ${NANO_MAKE_CONF_BUILD} 185) 186 187build_world ( ) ( 188 pprint 2 "run buildworld" 189 pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bw" 190 191 cd ${NANO_SRC} 192 env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} \ 193 __MAKE_CONF=${NANO_MAKE_CONF_BUILD} buildworld \ 194 > ${MAKEOBJDIRPREFIX}/_.bw 2>&1 195) 196 197build_kernel ( ) ( 198 pprint 2 "build kernel ($NANO_KERNEL)" 199 pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bk" 200 201 ( 202 if [ -f ${NANO_KERNEL} ] ; then 203 kernconfdir=$(realpath $(dirname ${NANO_KERNEL})) 204 kernconf=$(basename ${NANO_KERNEL}) 205 else 206 kernconf=${NANO_KERNEL} 207 fi 208 209 cd ${NANO_SRC}; 210 # unset these just in case to avoid compiler complaints 211 # when cross-building 212 unset TARGET_CPUTYPE 213 unset TARGET_BIG_ENDIAN 214 # Note: We intentionally build all modules, not only the ones in 215 # NANO_MODULES so the built world can be reused by multiple images. 216 env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} buildkernel \ 217 __MAKE_CONF=${NANO_MAKE_CONF_BUILD} \ 218 ${kernconfdir:+"KERNCONFDIR="}${kernconfdir} \ 219 KERNCONF=${kernconf} 220 ) > ${MAKEOBJDIRPREFIX}/_.bk 2>&1 221) 222 223clean_world ( ) ( 224 if [ "${NANO_OBJ}" != "${MAKEOBJDIRPREFIX}" ]; then 225 pprint 2 "Clean and create object directory (${NANO_OBJ})" 226 if ! rm -rf ${NANO_OBJ} > /dev/null 2>&1 ; then 227 chflags -R noschg ${NANO_OBJ} 228 rm -r ${NANO_OBJ} 229 fi 230 mkdir -p ${NANO_OBJ} ${NANO_WORLDDIR} 231 printenv > ${NANO_OBJ}/_.env 232 else 233 pprint 2 "Clean and create world directory (${NANO_WORLDDIR})" 234 if ! rm -rf ${NANO_WORLDDIR}/ > /dev/null 2>&1 ; then 235 chflags -R noschg ${NANO_WORLDDIR} 236 rm -rf ${NANO_WORLDDIR} 237 fi 238 mkdir -p ${NANO_WORLDDIR} 239 fi 240) 241 242make_conf_install ( ) ( 243 pprint 2 "Construct install make.conf ($NANO_MAKE_CONF_INSTALL)" 244 245 echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_INSTALL} 246 echo "${CONF_INSTALL}" >> ${NANO_MAKE_CONF_INSTALL} 247) 248 249install_world ( ) ( 250 pprint 2 "installworld" 251 pprint 3 "log: ${NANO_OBJ}/_.iw" 252 253 cd ${NANO_SRC} 254 env TARGET_ARCH=${NANO_ARCH} \ 255 ${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} installworld \ 256 DESTDIR=${NANO_WORLDDIR} \ 257 > ${NANO_OBJ}/_.iw 2>&1 258 chflags -R noschg ${NANO_WORLDDIR} 259) 260 261install_etc ( ) ( 262 263 pprint 2 "install /etc" 264 pprint 3 "log: ${NANO_OBJ}/_.etc" 265 266 cd ${NANO_SRC} 267 env TARGET_ARCH=${NANO_ARCH} \ 268 ${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} distribution \ 269 DESTDIR=${NANO_WORLDDIR} \ 270 > ${NANO_OBJ}/_.etc 2>&1 271 # make.conf doesn't get created by default, but some ports need it 272 # so they can spam it. 273 cp /dev/null ${NANO_WORLDDIR}/etc/make.conf 274) 275 276install_kernel ( ) ( 277 pprint 2 "install kernel ($NANO_KERNEL)" 278 pprint 3 "log: ${NANO_OBJ}/_.ik" 279 280 ( 281 if [ -f ${NANO_KERNEL} ] ; then 282 kernconfdir=$(realpath $(dirname ${NANO_KERNEL})) 283 kernconf=$(basename ${NANO_KERNEL}) 284 else 285 kernconf=${NANO_KERNEL} 286 fi 287 288 cd ${NANO_SRC} 289 env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} installkernel \ 290 DESTDIR=${NANO_WORLDDIR} \ 291 __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} \ 292 ${kernconfdir:+"KERNCONFDIR="}${kernconfdir} \ 293 KERNCONF=${kernconf} \ 294 MODULES_OVERRIDE="${NANO_MODULES}" 295 ) > ${NANO_OBJ}/_.ik 2>&1 296) 297 298run_customize() ( 299 300 pprint 2 "run customize scripts" 301 for c in $NANO_CUSTOMIZE 302 do 303 pprint 2 "customize \"$c\"" 304 pprint 3 "log: ${NANO_OBJ}/_.cust.$c" 305 pprint 4 "`type $c`" 306 ( set -x ; $c ) > ${NANO_OBJ}/_.cust.$c 2>&1 307 done 308) 309 310run_late_customize() ( 311 312 pprint 2 "run late customize scripts" 313 for c in $NANO_LATE_CUSTOMIZE 314 do 315 pprint 2 "late customize \"$c\"" 316 pprint 3 "log: ${NANO_OBJ}/_.late_cust.$c" 317 pprint 4 "`type $c`" 318 ( set -x ; $c ) > ${NANO_OBJ}/_.late_cust.$c 2>&1 319 done 320) 321 322setup_nanobsd ( ) ( 323 pprint 2 "configure nanobsd setup" 324 pprint 3 "log: ${NANO_OBJ}/_.dl" 325 326 ( 327 cd ${NANO_WORLDDIR} 328 329 # Move /usr/local/etc to /etc/local so that the /cfg stuff 330 # can stomp on it. Otherwise packages like ipsec-tools which 331 # have hardcoded paths under ${prefix}/etc are not tweakable. 332 if [ -d usr/local/etc ] ; then 333 ( 334 mkdir -p etc/local 335 cd usr/local/etc 336 find . -print | cpio -dumpl ../../../etc/local 337 cd .. 338 rm -rf etc 339 ln -s ../../etc/local etc 340 ) 341 fi 342 343 for d in var etc 344 do 345 # link /$d under /conf 346 # we use hard links so we have them both places. 347 # the files in /$d will be hidden by the mount. 348 # XXX: configure /$d ramdisk size 349 mkdir -p conf/base/$d conf/default/$d 350 find $d -print | cpio -dumpl conf/base/ 351 done 352 353 echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size 354 echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size 355 356 # pick up config files from the special partition 357 echo "mount -o ro /dev/${NANO_DRIVE}s3" > conf/default/etc/remount 358 359 # Put /tmp on the /var ramdisk (could be symlink already) 360 rmdir tmp || true 361 rm tmp || true 362 ln -s var/tmp tmp 363 364 ) > ${NANO_OBJ}/_.dl 2>&1 365) 366 367setup_nanobsd_etc ( ) ( 368 pprint 2 "configure nanobsd /etc" 369 370 ( 371 cd ${NANO_WORLDDIR} 372 373 # create diskless marker file 374 touch etc/diskless 375 376 # Make root filesystem R/O by default 377 echo "root_rw_mount=NO" >> etc/defaults/rc.conf 378 379 # save config file for scripts 380 echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf 381 382 echo "/dev/${NANO_DRIVE}s1a / ufs ro 1 1" > etc/fstab 383 echo "/dev/${NANO_DRIVE}s3 /cfg ufs rw,noauto 2 2" >> etc/fstab 384 mkdir -p cfg 385 ) 386) 387 388prune_usr() ( 389 390 # Remove all empty directories in /usr 391 find ${NANO_WORLDDIR}/usr -type d -depth -print | 392 while read d 393 do 394 rmdir $d > /dev/null 2>&1 || true 395 done 396) 397 398newfs_part ( ) ( 399 local dev mnt lbl 400 dev=$1 401 mnt=$2 402 lbl=$3 403 echo newfs ${NANO_NEWFS} ${NANO_LABEL:+-L${NANO_LABEL}${lbl}} ${dev} 404 newfs ${NANO_NEWFS} ${NANO_LABEL:+-L${NANO_LABEL}${lbl}} ${dev} 405 mount ${dev} ${mnt} 406) 407 408populate_slice ( ) ( 409 local dev dir mnt lbl 410 dev=$1 411 dir=$2 412 mnt=$3 413 lbl=$4 414 test -z $2 && dir=/var/empty 415 test -d $dir || dir=/var/empty 416 echo "Creating ${dev} with ${dir} (mounting on ${mnt})" 417 newfs_part $dev $mnt $lbl 418 cd ${dir} 419 find . -print | grep -Ev '/(CVS|\.svn)' | cpio -dumpv ${mnt} 420 df -i ${mnt} 421 umount ${mnt} 422) 423 424populate_cfg_slice ( ) ( 425 populate_slice "$1" "$2" "$3" "$4" 426) 427 428populate_data_slice ( ) ( 429 populate_slice "$1" "$2" "$3" "$4" 430) 431 432create_i386_diskimage ( ) ( 433 pprint 2 "build diskimage" 434 pprint 3 "log: ${NANO_OBJ}/_.di" 435 436 ( 437 echo $NANO_MEDIASIZE $NANO_IMAGES \ 438 $NANO_SECTS $NANO_HEADS \ 439 $NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE | 440 awk ' 441 { 442 printf "# %s\n", $0 443 444 # size of cylinder in sectors 445 cs = $3 * $4 446 447 # number of full cylinders on media 448 cyl = int ($1 / cs) 449 450 # output fdisk geometry spec, truncate cyls to 1023 451 if (cyl <= 1023) 452 print "g c" cyl " h" $4 " s" $3 453 else 454 print "g c" 1023 " h" $4 " s" $3 455 456 if ($7 > 0) { 457 # size of data partition in full cylinders 458 dsl = int (($7 + cs - 1) / cs) 459 } else { 460 dsl = 0; 461 } 462 463 # size of config partition in full cylinders 464 csl = int (($6 + cs - 1) / cs) 465 466 if ($5 == 0) { 467 # size of image partition(s) in full cylinders 468 isl = int ((cyl - dsl - csl) / $2) 469 } else { 470 isl = int (($5 + cs - 1) / cs) 471 } 472 473 # First image partition start at second track 474 print "p 1 165 " $3, isl * cs - $3 475 c = isl * cs; 476 477 # Second image partition (if any) also starts offset one 478 # track to keep them identical. 479 if ($2 > 1) { 480 print "p 2 165 " $3 + c, isl * cs - $3 481 c += isl * cs; 482 } 483 484 # Config partition starts at cylinder boundary. 485 print "p 3 165 " c, csl * cs 486 c += csl * cs 487 488 # Data partition (if any) starts at cylinder boundary. 489 if ($7 > 0) { 490 print "p 4 165 " c, dsl * cs 491 } else if ($7 < 0 && $1 > c) { 492 print "p 4 165 " c, $1 - c 493 } else if ($1 < c) { 494 print "Disk space overcommitted by", \ 495 c - $1, "sectors" > "/dev/stderr" 496 exit 2 497 } 498 499 # Force slice 1 to be marked active. This is necessary 500 # for booting the image from a USB device to work. 501 print "a 1" 502 } 503 ' > ${NANO_OBJ}/_.fdisk 504 505 IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME} 506 MNT=${NANO_OBJ}/_.mnt 507 mkdir -p ${MNT} 508 509 if [ "${NANO_MD_BACKING}" = "swap" ] ; then 510 MD=`mdconfig -a -t swap -s ${NANO_MEDIASIZE} -x ${NANO_SECTS} \ 511 -y ${NANO_HEADS}` 512 else 513 echo "Creating md backing file..." 514 dd if=/dev/zero of=${IMG} bs=${NANO_SECTS}b \ 515 count=`expr ${NANO_MEDIASIZE} / ${NANO_SECTS}` 516 MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \ 517 -y ${NANO_HEADS}` 518 fi 519 520 trap "echo 'Running exit trap code' ; df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT 521 522 fdisk -i -f ${NANO_OBJ}/_.fdisk ${MD} 523 fdisk ${MD} 524 # XXX: params 525 # XXX: pick up cached boot* files, they may not be in image anymore. 526 boot0cfg -B -b ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ${NANO_BOOT0CFG} ${MD} 527 bsdlabel -w -B -b ${NANO_WORLDDIR}/boot/boot ${MD}s1 528 bsdlabel ${MD}s1 529 530 # Create first image 531 populate_slice /dev/${MD}s1a ${NANO_WORLDDIR} ${MNT} "s1a" 532 mount /dev/${MD}s1a ${MNT} 533 echo "Generating mtree..." 534 ( cd ${MNT} && mtree -c ) > ${NANO_OBJ}/_.mtree 535 ( cd ${MNT} && du -k ) > ${NANO_OBJ}/_.du 536 umount ${MNT} 537 538 if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then 539 # Duplicate to second image (if present) 540 echo "Duplicating to second image..." 541 dd if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k 542 mount /dev/${MD}s2a ${MNT} 543 for f in ${MNT}/etc/fstab ${MNT}/conf/base/etc/fstab 544 do 545 sed -i "" "s=${NANO_DRIVE}s1=${NANO_DRIVE}s2=g" $f 546 done 547 umount ${MNT} 548 # Override the label from the first partition so we 549 # don't confuse glabel with duplicates. 550 if [ ! -z ${NANO_LABEL} ]; then 551 tunefs -L ${NANO_LABEL}"s2a" /dev/${MD}s2a 552 fi 553 fi 554 555 # Create Config slice 556 populate_cfg_slice /dev/${MD}s3 "${NANO_CFGDIR}" ${MNT} "s3" 557 558 # Create Data slice, if any. 559 if [ $NANO_DATASIZE -ne 0 ] ; then 560 populate_data_slice /dev/${MD}s4 "${NANO_DATADIR}" ${MNT} "s4" 561 fi 562 563 if [ "${NANO_MD_BACKING}" = "swap" ] ; then 564 echo "Writing out ${NANO_IMGNAME}..." 565 dd if=/dev/${MD} of=${IMG} bs=64k 566 fi 567 568 echo "Writing out _.disk.image..." 569 dd if=/dev/${MD}s1 of=${NANO_DISKIMGDIR}/_.disk.image bs=64k 570 mdconfig -d -u $MD 571 572 trap - 1 2 15 EXIT 573 574 ) > ${NANO_OBJ}/_.di 2>&1 575) 576 577# i386 and amd64 are identical for disk images 578create_amd64_diskimage ( ) ( 579 create_i386_diskimage 580) 581 582last_orders () ( 583 # Redefine this function with any last orders you may have 584 # after the build completed, for instance to copy the finished 585 # image to a more convenient place: 586 # cp ${NANO_DISKIMGDIR}/_.disk.image /home/ftp/pub/nanobsd.disk 587) 588 589####################################################################### 590# 591# Optional convenience functions. 592# 593####################################################################### 594 595####################################################################### 596# Common Flash device geometries 597# 598 599FlashDevice () { 600 if [ -d ${NANO_TOOLS} ] ; then 601 . ${NANO_TOOLS}/FlashDevice.sub 602 else 603 . ${NANO_SRC}/${NANO_TOOLS}/FlashDevice.sub 604 fi 605 sub_FlashDevice $1 $2 606} 607 608####################################################################### 609# USB device geometries 610# 611# Usage: 612# UsbDevice Generic 1000 # a generic flash key sold as having 1GB 613# 614# This function will set NANO_MEDIASIZE, NANO_HEADS and NANO_SECTS for you. 615# 616# Note that the capacity of a flash key is usually advertised in MB or 617# GB, *not* MiB/GiB. As such, the precise number of cylinders available 618# for C/H/S geometry may vary depending on the actual flash geometry. 619# 620# The following generic device layouts are understood: 621# generic An alias for generic-hdd. 622# generic-hdd 255H 63S/T xxxxC with no MBR restrictions. 623# generic-fdd 64H 32S/T xxxxC with no MBR restrictions. 624# 625# The generic-hdd device is preferred for flash devices larger than 1GB. 626# 627 628UsbDevice () { 629 a1=`echo $1 | tr '[:upper:]' '[:lower:]'` 630 case $a1 in 631 generic-fdd) 632 NANO_HEADS=64 633 NANO_SECTS=32 634 NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 )) 635 ;; 636 generic|generic-hdd) 637 NANO_HEADS=255 638 NANO_SECTS=63 639 NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 )) 640 ;; 641 *) 642 echo "Unknown USB flash device" 643 exit 2 644 ;; 645 esac 646} 647 648####################################################################### 649# Setup serial console 650 651cust_comconsole () ( 652 # Enable getty on console 653 sed -i "" -e /tty[du]0/s/off/on/ ${NANO_WORLDDIR}/etc/ttys 654 655 # Disable getty on syscons devices 656 sed -i "" -e '/^ttyv[0-8]/s/ on/ off/' ${NANO_WORLDDIR}/etc/ttys 657 658 # Tell loader to use serial console early. 659 echo " -h" > ${NANO_WORLDDIR}/boot.config 660) 661 662####################################################################### 663# Allow root login via ssh 664 665cust_allow_ssh_root () ( 666 sed -i "" -e '/PermitRootLogin/s/.*/PermitRootLogin yes/' \ 667 ${NANO_WORLDDIR}/etc/ssh/sshd_config 668) 669 670####################################################################### 671# Install the stuff under ./Files 672 673cust_install_files () ( 674 cd ${NANO_TOOLS}/Files 675 find . -print | grep -Ev '/(CVS|\.svn)' | cpio -dumpv ${NANO_WORLDDIR} 676) 677 678####################################################################### 679# Install packages from ${NANO_PACKAGE_DIR} 680 681cust_pkg () ( 682 683 # Copy packages into chroot 684 mkdir -p ${NANO_WORLDDIR}/Pkg 685 ( 686 cd ${NANO_PACKAGE_DIR} 687 find ${NANO_PACKAGE_LIST} -print | 688 cpio -dumpv ${NANO_WORLDDIR}/Pkg 689 ) 690 691 # Count & report how many we have to install 692 todo=`ls ${NANO_WORLDDIR}/Pkg | wc -l` 693 echo "=== TODO: $todo" 694 ls ${NANO_WORLDDIR}/Pkg 695 echo "===" 696 while true 697 do 698 # Record how many we have now 699 have=`ls ${NANO_WORLDDIR}/var/db/pkg | wc -l` 700 701 # Attempt to install more packages 702 # ...but no more than 200 at a time due to pkg_add's internal 703 # limitations. 704 chroot ${NANO_WORLDDIR} sh -c \ 705 'ls Pkg/*tbz | xargs -n 200 pkg_add -F' || true 706 707 # See what that got us 708 now=`ls ${NANO_WORLDDIR}/var/db/pkg | wc -l` 709 echo "=== NOW $now" 710 ls ${NANO_WORLDDIR}/var/db/pkg 711 echo "===" 712 713 714 if [ $now -eq $todo ] ; then 715 echo "DONE $now packages" 716 break 717 elif [ $now -eq $have ] ; then 718 echo "FAILED: Nothing happened on this pass" 719 exit 2 720 fi 721 done 722 rm -rf ${NANO_WORLDDIR}/Pkg 723) 724 725####################################################################### 726# Convenience function: 727# Register all args as customize function. 728 729customize_cmd () { 730 NANO_CUSTOMIZE="$NANO_CUSTOMIZE $*" 731} 732 733####################################################################### 734# Convenience function: 735# Register all args as late customize function to run just before 736# image creation. 737 738late_customize_cmd () { 739 NANO_LATE_CUSTOMIZE="$NANO_LATE_CUSTOMIZE $*" 740} 741 742####################################################################### 743# 744# All set up to go... 745# 746####################################################################### 747 748# Progress Print 749# Print $2 at level $1. 750pprint() { 751 if [ "$1" -le $PPLEVEL ]; then 752 runtime=$(( `date +%s` - $NANO_STARTTIME )) 753 printf "%s %.${1}s %s\n" "`date -u -r $runtime +%H:%M:%S`" "#####" "$2" 1>&3 754 fi 755} 756 757usage () { 758 ( 759 echo "Usage: $0 [-biknqvw] [-c config_file]" 760 echo " -b suppress builds (both kernel and world)" 761 echo " -i suppress disk image build" 762 echo " -k suppress buildkernel" 763 echo " -n add -DNO_CLEAN to buildworld, buildkernel, etc" 764 echo " -q make output more quiet" 765 echo " -v make output more verbose" 766 echo " -w suppress buildworld" 767 echo " -c specify config file" 768 ) 1>&2 769 exit 2 770} 771 772####################################################################### 773# Parse arguments 774 775do_clean=true 776do_kernel=true 777do_world=true 778do_image=true 779 780set +e 781args=`getopt bc:hiknqvw $*` 782if [ $? -ne 0 ] ; then 783 usage 784 exit 2 785fi 786set -e 787 788set -- $args 789for i 790do 791 case "$i" 792 in 793 -b) 794 do_world=false 795 do_kernel=false 796 shift 797 ;; 798 -k) 799 do_kernel=false 800 shift 801 ;; 802 -c) 803 . "$2" 804 shift 805 shift 806 ;; 807 -h) 808 usage 809 ;; 810 -i) 811 do_image=false 812 shift 813 ;; 814 -n) 815 do_clean=false 816 shift 817 ;; 818 -q) 819 PPLEVEL=$(($PPLEVEL - 1)) 820 shift 821 ;; 822 -v) 823 PPLEVEL=$(($PPLEVEL + 1)) 824 shift 825 ;; 826 -w) 827 do_world=false 828 shift 829 ;; 830 --) 831 shift 832 break 833 esac 834done 835 836if [ $# -gt 0 ] ; then 837 echo "$0: Extraneous arguments supplied" 838 usage 839fi 840 841####################################################################### 842# Setup and Export Internal variables 843# 844test -n "${NANO_OBJ}" || NANO_OBJ=/usr/obj/nanobsd.${NANO_NAME}/ 845test -n "${MAKEOBJDIRPREFIX}" || MAKEOBJDIRPREFIX=${NANO_OBJ} 846test -n "${NANO_DISKIMGDIR}" || NANO_DISKIMGDIR=${NANO_OBJ} 847 848NANO_WORLDDIR=${NANO_OBJ}/_.w 849NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build 850NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install 851 852if [ -d ${NANO_TOOLS} ] ; then 853 true 854elif [ -d ${NANO_SRC}/${NANO_TOOLS} ] ; then 855 NANO_TOOLS=${NANO_SRC}/${NANO_TOOLS} 856else 857 echo "NANO_TOOLS directory does not exist" 1>&2 858 exit 1 859fi 860 861if $do_clean ; then 862 true 863else 864 NANO_PMAKE="${NANO_PMAKE} -DNO_CLEAN" 865fi 866 867# Override user's NANO_DRIVE if they specified a NANO_LABEL 868if [ ! -z "${NANO_LABEL}" ]; then 869 NANO_DRIVE=ufs/${NANO_LABEL} 870fi 871 872export MAKEOBJDIRPREFIX 873 874export NANO_ARCH 875export NANO_CODESIZE 876export NANO_CONFSIZE 877export NANO_CUSTOMIZE 878export NANO_DATASIZE 879export NANO_DRIVE 880export NANO_HEADS 881export NANO_IMAGES 882export NANO_IMGNAME 883export NANO_MAKE_CONF_BUILD 884export NANO_MAKE_CONF_INSTALL 885export NANO_MEDIASIZE 886export NANO_NAME 887export NANO_NEWFS 888export NANO_OBJ 889export NANO_PMAKE 890export NANO_SECTS 891export NANO_SRC 892export NANO_TOOLS 893export NANO_WORLDDIR 894export NANO_BOOT0CFG 895export NANO_BOOTLOADER 896export NANO_LABEL 897 898####################################################################### 899# And then it is as simple as that... 900 901# File descriptor 3 is used for logging output, see pprint 902exec 3>&1 903 904NANO_STARTTIME=`date +%s` 905pprint 1 "NanoBSD image ${NANO_NAME} build starting" 906 907if $do_world ; then 908 if $do_clean ; then 909 clean_build 910 else 911 pprint 2 "Using existing build tree (as instructed)" 912 fi 913 make_conf_build 914 build_world 915else 916 pprint 2 "Skipping buildworld (as instructed)" 917fi 918 919if $do_kernel ; then 920 if ! $do_world ; then 921 make_conf_build 922 fi 923 build_kernel 924else 925 pprint 2 "Skipping buildkernel (as instructed)" 926fi 927 928clean_world 929make_conf_install 930install_world 931install_etc 932setup_nanobsd_etc 933install_kernel 934 935run_customize 936setup_nanobsd 937prune_usr 938run_late_customize 939if $do_image ; then 940 create_${NANO_ARCH}_diskimage 941else 942 pprint 2 "Skipping image build (as instructed)" 943fi 944last_orders 945 946pprint 1 "NanoBSD image ${NANO_NAME} completed" 947