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