nanobsd.sh revision 164660
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 164660 2006-11-27 12:16:03Z n_hibma $ 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# Object tree directory 49# default is subdir of /usr/obj 50# XXX: MAKEOBJDIRPREFIX handling... ? 51#NANO_OBJ="" 52 53# Parallel Make 54NANO_PMAKE="make -j 3" 55 56# Options to put in make.conf during buildworld only 57CONF_BUILD=' ' 58 59# Options to put in make.conf during installworld only 60CONF_INSTALL=' ' 61 62# Options to put in make.conf during both build- & installworld. 63CONF_WORLD=' ' 64 65# Kernel config file to use 66NANO_KERNEL=GENERIC 67 68# Customize commands. 69NANO_CUSTOMIZE="" 70 71# Newfs paramters to use 72NANO_NEWFS="-b 4096 -f 512 -i 8192 -O1 -U" 73 74# The drive name of the media at runtime 75NANO_DRIVE=ad0 76 77# Target media size in 512 bytes sectors 78NANO_MEDIASIZE=1048576 79 80# Number of code images on media (1 or 2) 81NANO_IMAGES=2 82 83# Size of code file system in 512 bytes sectors 84# If zero, size will be as large as possible. 85NANO_CODESIZE=0 86 87# Size of configuration file system in 512 bytes sectors 88# Cannot be zero. 89NANO_CONFSIZE=2048 90 91# Size of data file system in 512 bytes sectors 92# If zero: no partition configured. 93# If negative: max size possible 94NANO_DATASIZE=0 95 96# Size of the /etc ramdisk in 512 bytes sectors 97NANO_RAM_ETCSIZE=10240 98 99# Size of the /tmp+/var ramdisk in 512 bytes sectors 100NANO_RAM_TMPVARSIZE=10240 101 102# Media geometry, only relevant if bios doesn't understand LBA. 103NANO_SECTS=32 104NANO_HEADS=16 105 106####################################################################### 107# Not a variable at this time 108 109NANO_ARCH=i386 110 111####################################################################### 112# 113# The functions which do the real work. 114# Can be overridden from the config file(s) 115# 116####################################################################### 117 118clean_build ( ) ( 119 echo "## Clean and create object directory (${MAKEOBJDIRPREFIX})" 120 121 if rm -rf ${MAKEOBJDIRPREFIX} > /dev/null 2>&1 ; then 122 true 123 else 124 chflags -R noschg ${MAKEOBJDIRPREFIX} 125 rm -rf ${MAKEOBJDIRPREFIX} 126 fi 127 mkdir -p ${MAKEOBJDIRPREFIX} 128 printenv > ${MAKEOBJDIRPREFIX}/_.env 129) 130 131make_conf_build ( ) ( 132 echo "## Construct build make.conf ($NANO_MAKE_CONF)" 133 134 echo "${CONF_WORLD}" > ${NANO_MAKE_CONF} 135 echo "${CONF_BUILD}" >> ${NANO_MAKE_CONF} 136) 137 138build_world ( ) ( 139 echo "## run buildworld" 140 echo "### log: ${MAKEOBJDIRPREFIX}/_.bw" 141 142 cd ${NANO_SRC} 143 ${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF} buildworld \ 144 > ${MAKEOBJDIRPREFIX}/_.bw 2>&1 145) 146 147build_kernel ( ) ( 148 echo "## build kernel ($NANO_KERNEL)" 149 echo "### log: ${MAKEOBJDIRPREFIX}/_.bk" 150 151 if [ -f ${NANO_KERNEL} ] ; then 152 cp ${NANO_KERNEL} ${NANO_SRC}/sys/${NANO_ARCH}/conf 153 fi 154 155 cd ${NANO_SRC} 156 ${NANO_PMAKE} buildkernel \ 157 __MAKE_CONF=${NANO_MAKE_CONF} KERNCONF=`basename ${NANO_KERNEL}` \ 158 > ${MAKEOBJDIRPREFIX}/_.bk 2>&1 159) 160 161clean_world ( ) ( 162 echo "## Clean and create world directory (${NANO_WORLDDIR})" 163 if rm -rf ${NANO_WORLDDIR}/ > /dev/null 2>&1 ; then 164 true 165 else 166 chflags -R noschg ${NANO_WORLDDIR}/ 167 rm -rf ${NANO_WORLDDIR}/ 168 fi 169 mkdir -p ${NANO_WORLDDIR}/ 170) 171 172make_conf_install ( ) ( 173 echo "## Construct install make.conf ($NANO_MAKE_CONF)" 174 175 echo "${CONF_WORLD}" > ${NANO_MAKE_CONF} 176 echo "${CONF_INSTALL}" >> ${NANO_MAKE_CONF} 177) 178 179install_world ( ) ( 180 echo "## installworld" 181 echo "### log: ${MAKEOBJDIRPREFIX}/_.iw" 182 183 cd ${NANO_SRC} 184 ${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF} installworld \ 185 DESTDIR=${NANO_WORLDDIR} \ 186 > ${MAKEOBJDIRPREFIX}/_.iw 2>&1 187 chflags -R noschg ${NANO_WORLDDIR} 188) 189 190install_etc ( ) ( 191 192 echo "## install /etc" 193 echo "### log: ${MAKEOBJDIRPREFIX}/_.etc" 194 195 cd ${NANO_SRC} 196 ${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF} distribution \ 197 DESTDIR=${NANO_WORLDDIR} \ 198 > ${MAKEOBJDIRPREFIX}/_.etc 2>&1 199) 200 201install_kernel ( ) ( 202 echo "## install kernel" 203 echo "### log: ${MAKEOBJDIRPREFIX}/_.ik" 204 205 cd ${NANO_SRC} 206 ${NANO_PMAKE} installkernel \ 207 DESTDIR=${NANO_WORLDDIR} \ 208 __MAKE_CONF=${NANO_MAKE_CONF} KERNCONF=`basename ${NANO_KERNEL}` \ 209 > ${MAKEOBJDIRPREFIX}/_.ik 2>&1 210) 211 212run_customize() ( 213 214 echo "## run customize scripts" 215 for c in $NANO_CUSTOMIZE 216 do 217 echo "## customize \"$c\"" 218 echo "### log: ${MAKEOBJDIRPREFIX}/_.cust.$c" 219 echo "### `type $c`" 220 ( $c ) > ${MAKEOBJDIRPREFIX}/_.cust.$c 2>&1 221 done 222) 223 224setup_nanobsd ( ) ( 225 echo "## configure nanobsd setup" 226 echo "### log: ${MAKEOBJDIRPREFIX}/_.dl" 227 228 ( 229 cd ${NANO_WORLDDIR} 230 231 for d in var etc 232 do 233 # link /$d under /conf 234 # we use hard links so we have them both places. 235 # the files in /$d will be hidden by the mount. 236 # XXX: configure /$d ramdisk size 237 mkdir -p conf/base/$d conf/default/$d 238 find $d -print | cpio -dumpl conf/base/ 239 done 240 241 echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size 242 echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size 243 244 # pick up config files from the special partition 245 echo "mount -o ro /dev/${NANO_DRIVE}s3" > conf/default/etc/remount 246 247 # Put /tmp on the /var ramdisk (could be symlink already) 248 rmdir tmp || true 249 rm tmp || true 250 ln -s var/tmp tmp 251 252 ) > ${MAKEOBJDIRPREFIX}/_.dl 2>&1 253) 254 255setup_nanobsd_etc ( ) ( 256 echo "## configure nanobsd /etc" 257 258 ( 259 cd ${NANO_WORLDDIR} 260 261 # create diskless marker file 262 touch etc/diskless 263 264 # save config file for scripts 265 echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf 266 267 echo "/dev/${NANO_DRIVE}s1a / ufs ro 1 1" > etc/fstab 268 echo "/dev/${NANO_DRIVE}s3 /cfg ufs rw,noauto 2 2" >> etc/fstab 269 mkdir -p cfg 270 ) 271) 272 273prune_usr() ( 274 275 # Remove all empty directories in /usr 276 find ${NANO_WORLDDIR}/usr -type d -depth -print | 277 while read d 278 do 279 rmdir $d > /dev/null 2>&1 || true 280 done 281) 282 283create_i386_diskimage ( ) ( 284 echo "## build diskimage" 285 echo "### log: ${MAKEOBJDIRPREFIX}/_.di" 286 287 ( 288 echo $NANO_MEDIASIZE $NANO_IMAGES \ 289 $NANO_SECTS $NANO_HEADS \ 290 $NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE | 291 awk ' 292 { 293 printf "# %s\n", $0 294 295 # size of cylinder in sectors 296 cs = $3 * $4 297 298 # number of full cylinders on media 299 cyl = int ($1 / cs) 300 301 # output fdisk geometry spec, truncate cyls to 1023 302 if (cyl <= 1023) 303 print "g c" cyl " h" $4 " s" $3 304 else 305 print "g c" 1023 " h" $4 " s" $3 306 307 if ($7 > 0) { 308 # size of data partition in full cylinders 309 dsl = int (($7 + cs - 1) / cs) 310 } else { 311 dsl = 0; 312 } 313 314 # size of config partition in full cylinders 315 csl = int (($6 + cs - 1) / cs) 316 317 if ($5 == 0) { 318 # size of image partition(s) in full cylinders 319 isl = int ((cyl - dsl - csl) / $2) 320 } else { 321 isl = int (($5 + cs - 1) / cs) 322 } 323 324 # First image partition start at second track 325 print "p 1 165 " $3, isl * cs - $3 326 c = isl * cs; 327 328 # Second image partition (if any) also starts offset one 329 # track to keep them identical. 330 if ($2 > 1) { 331 print "p 2 165 " $3 + c, isl * cs - $3 332 c += isl * cs; 333 } 334 335 # Config partition starts at cylinder boundary. 336 print "p 3 165 " c, csl * cs 337 c += csl * cs 338 339 # Data partition (if any) starts at cylinder boundary. 340 if ($7 > 0) { 341 print "p 4 165 " c, dsl * cs 342 } else if ($7 < 0 && $1 > $c) { 343 print "p 4 165 " c, $1 - $c 344 } else if ($1 < c) { 345 print "Disk space overcommitted by", \ 346 c - $1, "sectors" > "/dev/stderr" 347 exit 2 348 } 349 } 350 ' > ${MAKEOBJDIRPREFIX}/_.fdisk 351 352 IMG=${MAKEOBJDIRPREFIX}/_.disk.full 353 MNT=${MAKEOBJDIRPREFIX}/_.mnt 354 mkdir -p ${MNT} 355 356 dd if=/dev/zero of=${IMG} bs=${NANO_SECTS}b \ 357 count=`expr ${NANO_MEDIASIZE} / ${NANO_SECTS}` 358 359 MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} -y ${NANO_HEADS}` 360 361 trap "df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT 362 363 fdisk -i -f ${MAKEOBJDIRPREFIX}/_.fdisk ${MD} 364 fdisk ${MD} 365 # XXX: params 366 # XXX: pick up cached boot* files, they may not be in image anymore. 367 boot0cfg -B -b ${NANO_WORLDDIR}/boot/boot0sio -o packet -s 1 -m 3 ${MD} 368 bsdlabel -w -B -b ${NANO_WORLDDIR}/boot/boot ${MD}s1 369 bsdlabel ${MD}s1 370 371 # Create first image 372 newfs ${NANO_NEWFS} /dev/${MD}s1a 373 mount /dev/${MD}s1a ${MNT} 374 df -i ${MNT} 375 ( cd ${NANO_WORLDDIR} && find . -print | cpio -dump ${MNT} ) 376 df -i ${MNT} 377 ( cd ${MNT} && mtree -c ) > ${MAKEOBJDIRPREFIX}/_.mtree 378 ( cd ${MNT} && du -k ) > ${MAKEOBJDIRPREFIX}/_.du 379 umount ${MNT} 380 381 if [ $NANO_IMAGES -gt 1 ] ; then 382 # Duplicate to second image (if present) 383 dd if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k 384 fi 385 386 # Create Config slice 387 newfs ${NANO_NEWFS} /dev/${MD}s3 388 # XXX: fill from where ? 389 390 # Create Data slice, if any. 391 if [ $NANO_DATASIZE -gt 0 ] ; then 392 newfs ${NANO_NEWFS} /dev/${MD}s4 393 # XXX: fill from where ? 394 fi 395 396 dd if=/dev/${MD}s1 of=${MAKEOBJDIRPREFIX}/_.disk.image bs=64k 397 mdconfig -d -u $MD 398 ) > ${MAKEOBJDIRPREFIX}/_.di 2>&1 399) 400 401last_orders () ( 402 # Redefine this function with any last orders you may have 403 # after the build completed, for instance to copy the finished 404 # image to a more convenient place: 405 # cp ${MAKEOBJDIRPREFIX}/_.disk.image /home/ftp/pub/nanobsd.disk 406) 407 408####################################################################### 409# 410# Optional convenience functions. 411# 412####################################################################### 413 414####################################################################### 415# Common Flash device geometries 416# 417 418FlashDevice () { 419 if [ -d ${NANO_TOOLS} ] ; then 420 . ${NANO_TOOLS}/FlashDevice.sub 421 else 422 . ${NANO_SRC}/${NANO_TOOLS}/FlashDevice.sub 423 fi 424 sub_FlashDevice $1 $2 425} 426 427 428####################################################################### 429# Setup serial console 430 431cust_comconsole () ( 432 # Enable getty on console 433 sed -i "" -e /ttyd0/s/off/on/ ${NANO_WORLDDIR}/etc/ttys 434 435 # Disable getty on syscons devices 436 sed -i "" -e '/^ttyv[0-8]/s/ on/ off/' ${NANO_WORLDDIR}/etc/ttys 437 438 # Tell loader to use serial console early. 439 echo " -h" > ${NANO_WORLDDIR}/boot.config 440) 441 442####################################################################### 443# Allow root login via ssh 444 445cust_allow_ssh_root () ( 446 sed -i "" -e '/PermitRootLogin/s/.*/PermitRootLogin yes/' \ 447 ${NANO_WORLDDIR}/etc/ssh/sshd_config 448) 449 450####################################################################### 451# Install the stuff under ./Files 452 453cust_install_files () ( 454 cd ${NANO_TOOLS}/Files 455 find . -print | grep -v /CVS | cpio -dumpv ${NANO_WORLDDIR} 456) 457 458####################################################################### 459# Convenience function: 460# Register $1 as customize function. 461 462customize_cmd () { 463 NANO_CUSTOMIZE="$NANO_CUSTOMIZE $1" 464} 465 466####################################################################### 467# 468# All set up to go... 469# 470####################################################################### 471 472usage () { 473 ( 474 echo "Usage: $0 [-b/-k/-w] [-c config_file]" 475 echo " -b suppress builds (both kernel and world)" 476 echo " -k suppress buildkernel" 477 echo " -w suppress buildworld" 478 echo " -c specify config file" 479 ) 1>&2 480 exit 2 481} 482 483####################################################################### 484# Parse arguments 485 486do_kernel=true 487do_world=true 488 489set +e 490args=`getopt bc:hkw $*` 491if [ $? -ne 0 ] ; then 492 usage 493 exit 2 494fi 495set -e 496 497set -- $args 498for i 499do 500 case "$i" 501 in 502 -b) 503 shift; 504 do_world=false 505 do_kernel=false 506 ;; 507 -k) 508 shift; 509 do_kernel=false 510 ;; 511 -c) 512 . "$2" 513 shift; 514 shift; 515 ;; 516 -h) 517 usage 518 ;; 519 -w) 520 shift; 521 do_world=false 522 ;; 523 --) 524 shift; 525 break; 526 esac 527done 528 529if [ $# -gt 0 ] ; then 530 echo "$0: Extraneous arguments supplied" 531 usage 532fi 533 534####################################################################### 535# Setup and Export Internal variables 536# 537if [ "x${NANO_OBJ}" = "x" ] ; then 538 MAKEOBJDIRPREFIX=/usr/obj/nanobsd.${NANO_NAME}/ 539 NANO_OBJ=${MAKEOBJDIRPREFIX} 540else 541 MAKEOBJDIRPREFIX=${NANO_OBJ} 542fi 543 544NANO_WORLDDIR=${MAKEOBJDIRPREFIX}/_.w 545NANO_MAKE_CONF=${MAKEOBJDIRPREFIX}/make.conf 546 547if [ -d ${NANO_TOOLS} ] ; then 548 true 549elif [ -d ${NANO_SRC}/${NANO_TOOLS} ] ; then 550 NANO_TOOLS=${NANO_SRC}/${NANO_TOOLS} 551else 552 echo "NANO_TOOLS directory does not exist" 1>&2 553 exit 1 554fi 555 556export MAKEOBJDIRPREFIX 557 558export NANO_ARCH 559export NANO_CODESIZE 560export NANO_CONFSIZE 561export NANO_CUSTOMIZE 562export NANO_DATASIZE 563export NANO_DRIVE 564export NANO_HEADS 565export NANO_IMAGES 566export NANO_MAKE_CONF 567export NANO_MEDIASIZE 568export NANO_NAME 569export NANO_NEWFS 570export NANO_OBJ 571export NANO_PMAKE 572export NANO_SECTS 573export NANO_SRC 574export NANO_TOOLS 575export NANO_WORLDDIR 576 577####################################################################### 578# And then it is as simple as that... 579 580if $do_world ; then 581 clean_build 582 make_conf_build 583 build_world 584else 585 echo "## Skipping buildworld (as instructed)" 586fi 587 588if $do_kernel ; then 589 build_kernel 590else 591 echo "## Skipping buildkernel (as instructed)" 592fi 593 594clean_world 595make_conf_install 596install_world 597install_etc 598setup_nanobsd_etc 599install_kernel 600 601run_customize 602setup_nanobsd 603prune_usr 604create_${NANO_ARCH}_diskimage 605last_orders 606 607echo "# NanoBSD image completed" 608