nanobsd.sh revision 156496
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 156496 2006-03-09 14:43:07Z phk $ 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=${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}/etc 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=${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 # create diskless marker file 232 touch etc/diskless 233 234 # save config file for scripts 235 echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf 236 237 echo "/dev/${NANO_DRIVE}s1a / ufs ro 1 1" > etc/fstab 238 echo "/dev/${NANO_DRIVE}s3 /cfg ufs rw,noauto 2 2" >> etc/fstab 239 mkdir -p cfg 240 241 for d in var etc 242 do 243 # link /$d under /conf 244 # we use hard links so we have them both places. 245 # the files in /$d will be hidden by the mount. 246 # XXX: configure /$d ramdisk size 247 mkdir -p conf/base/$d conf/default/$d 248 find $d -print | cpio -dumpl conf/base/ 249 done 250 251 echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size 252 echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size 253 254 # pick up config files from the special partition 255 echo "mount -o ro /dev/${NANO_DRIVE}s3" > conf/default/etc/remount 256 257 # Put /tmp on the /var ramdisk (could be symlink already) 258 rmdir tmp || true 259 rm tmp || true 260 ln -s var/tmp tmp 261 262 ) > ${MAKEOBJDIRPREFIX}/_.dl 2>&1 263) 264 265prune_usr() ( 266 267 # Remove all empty directories in /usr 268 find ${NANO_WORLDDIR}/usr -type d -depth -print | 269 while read d 270 do 271 rmdir $d > /dev/null 2>&1 || true 272 done 273) 274 275create_i386_diskimage ( ) ( 276 echo "## build diskimage" 277 echo "### log: ${MAKEOBJDIRPREFIX}/_.di" 278 279 ( 280 echo $NANO_MEDIASIZE $NANO_IMAGES \ 281 $NANO_SECTS $NANO_HEADS \ 282 $NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE | 283 awk ' 284 { 285 printf "# %s\n", $0 286 287 # size of cylinder in sectors 288 cs = $3 * $4 289 290 # number of full cylinders on media 291 cyl = int ($1 / cs) 292 293 # output fdisk geometry spec, truncate cyls to 1023 294 if (cyl <= 1023) 295 print "g c" cyl " h" $4 " s" $3 296 else 297 print "g c" 1023 " h" $4 " s" $3 298 299 if ($7 > 0) { 300 # size of data partition in full cylinders 301 dsl = int (($7 + cs - 1) / cs) 302 } else { 303 dsl = 0; 304 } 305 306 # size of config partition in full cylinders 307 csl = int (($6 + cs - 1) / cs) 308 309 if ($5 == 0) { 310 # size of image partition(s) in full cylinders 311 isl = int ((cyl - dsl - csl) / $2) 312 } else { 313 isl = int (($5 + cs - 1) / cs) 314 } 315 316 # First image partition start at second track 317 print "p 1 165 " $3, isl * cs - $3 318 c = isl * cs; 319 320 # Second image partition (if any) also starts offset one 321 # track to keep them identical. 322 if ($2 > 1) { 323 print "p 2 165 " $3 + c, isl * cs - $3 324 c += isl * cs; 325 } 326 327 # Config partition starts at cylinder boundary. 328 print "p 3 165 " c, csl * cs 329 c += csl * cs 330 331 # Data partition (if any) starts at cylinder boundary. 332 if ($7 > 0) { 333 print "p 4 165 " c, dsl * cs 334 } else if ($7 < 0 && $1 > $c) { 335 print "p 4 165 " c, $1 - $c 336 } else if ($1 < c) { 337 print "Disk space overcommitted by", \ 338 c - $1, "sectors" > "/dev/stderr" 339 exit 2 340 } 341 } 342 ' > ${MAKEOBJDIRPREFIX}/_.fdisk 343 344 IMG=${MAKEOBJDIRPREFIX}/_.disk.full 345 MNT=${MAKEOBJDIRPREFIX}/_.mnt 346 mkdir -p ${MNT} 347 348 dd if=/dev/zero of=${IMG} bs=${NANO_SECTS}b \ 349 count=`expr ${NANO_MEDIASIZE} / ${NANO_SECTS}` 350 351 MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} -y ${NANO_HEADS}` 352 353 trap "df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT 354 355 fdisk -i -f ${MAKEOBJDIRPREFIX}/_.fdisk ${MD} 356 fdisk ${MD} 357 # XXX: params 358 # XXX: pick up cached boot* files, they may not be in image anymore. 359 boot0cfg -B -b ${NANO_WORLDDIR}/boot/boot0sio -o packet -s 1 -m 3 ${MD} 360 bsdlabel -w -B ${MD}s1 361 bsdlabel ${MD}s1 362 363 # Create first image 364 newfs ${NANO_NEWFS} /dev/${MD}s1a 365 mount /dev/${MD}s1a ${MNT} 366 df -i ${MNT} 367 ( cd ${NANO_WORLDDIR} && find . -print | cpio -dump ${MNT} ) 368 df -i ${MNT} 369 ( cd ${MNT} && mtree -c ) > ${MAKEOBJDIRPREFIX}/_.mtree 370 ( cd ${MNT} && du -k ) > ${MAKEOBJDIRPREFIX}/_.du 371 umount ${MNT} 372 373 if [ $NANO_IMAGES -gt 1 ] ; then 374 # Duplicate to second image (if present) 375 dd if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k 376 fi 377 378 # Create Config slice 379 newfs ${NANO_NEWFS} /dev/${MD}s3 380 # XXX: fill from where ? 381 382 # Create Data slice, if any. 383 if [ $NANO_DATASIZE -gt 0 ] ; then 384 newfs ${NANO_NEWFS} /dev/${MD}s4 385 # XXX: fill from where ? 386 fi 387 388 dd if=/dev/${MD}s1 of=${MAKEOBJDIRPREFIX}/_.disk.image bs=64k 389 mdconfig -d -u $MD 390 ) > ${MAKEOBJDIRPREFIX}/_.di 2>&1 391) 392 393last_orders () ( 394 # Redefine this function with any last orders you may have 395 # after the build completed, for instance to copy the finished 396 # image to a more convenient place: 397 # cp ${MAKEOBJDIRPREFIX}/_.disk.image /home/ftp/pub/nanobsd.disk 398) 399 400####################################################################### 401# 402# Optional convenience functions. 403# 404####################################################################### 405 406####################################################################### 407# Common Flash device geometries 408# 409 410FlashDevice () { 411 if [ -d ${NANO_TOOLS} ] ; then 412 . ${NANO_TOOLS}/FlashDevice.sub 413 else 414 . ${NANO_SRC}/${NANO_TOOLS}/FlashDevice.sub 415 fi 416 sub_FlashDevice $1 $2 417} 418 419 420####################################################################### 421# Setup serial console 422 423cust_comconsole () ( 424 # Enable getty on console 425 sed -i "" -e /ttyd0/s/off/on/ ${NANO_WORLDDIR}/etc/ttys 426 427 # Disable getty on syscons devices 428 sed -i "" -e '/^ttyv[0-8]/s/ on/ off/' ${NANO_WORLDDIR}/etc/ttys 429 430 # Tell loader to use serial console early. 431 echo " -h" > ${NANO_WORLDDIR}/boot.config 432) 433 434####################################################################### 435# Allow root login via ssh 436 437cust_allow_ssh_root () ( 438 sed -i "" -e '/PermitRootLogin/s/.*/PermitRootLogin yes/' \ 439 ${NANO_WORLDDIR}/etc/ssh/sshd_config 440) 441 442####################################################################### 443# Install the stuff under ./Files 444 445cust_install_files () ( 446 cd ${NANO_TOOLS}/Files 447 find . -print | grep -v /CVS | cpio -dumpv ${NANO_WORLDDIR} 448) 449 450####################################################################### 451# Convenience function: 452# Register $1 as customize function. 453 454customize_cmd () { 455 NANO_CUSTOMIZE="$NANO_CUSTOMIZE $1" 456} 457 458####################################################################### 459# 460# All set up to go... 461# 462####################################################################### 463 464usage () { 465 ( 466 echo "Usage: $0 [-b/-k/-w] [-c config_file]" 467 echo " -b suppress builds (both kernel and world)" 468 echo " -k suppress buildkernel" 469 echo " -w suppress buildworld" 470 echo " -c specify config file" 471 ) 1>&2 472 exit 2 473} 474 475####################################################################### 476# Parse arguments 477 478do_kernel=true 479do_world=true 480 481set +e 482args=`getopt bc:hkw $*` 483if [ $? -ne 0 ] ; then 484 usage 485 exit 2 486fi 487set -e 488 489set -- $args 490for i 491do 492 case "$i" 493 in 494 -b) 495 shift; 496 do_world=false 497 do_kernel=false 498 ;; 499 -k) 500 shift; 501 do_kernel=false 502 ;; 503 -c) 504 . "$2" 505 shift; 506 shift; 507 ;; 508 -h) 509 usage 510 ;; 511 -w) 512 shift; 513 do_world=false 514 ;; 515 --) 516 shift; 517 break; 518 esac 519done 520 521if [ $# -gt 0 ] ; then 522 echo "$0: Extraneous arguments supplied" 523 usage 524fi 525 526####################################################################### 527# Setup and Export Internal variables 528# 529if [ "x${NANO_OBJ}" = "x" ] ; then 530 MAKEOBJDIRPREFIX=/usr/obj/nanobsd.${NANO_NAME}/ 531 NANO_OBJ=${MAKEOBJDIRPREFIX} 532else 533 MAKEOBJDIRPREFIX=${NANO_OBJ} 534fi 535 536NANO_WORLDDIR=${MAKEOBJDIRPREFIX}/_.w 537NANO_MAKE_CONF=${MAKEOBJDIRPREFIX}/make.conf 538 539if [ -d ${NANO_TOOLS} ] ; then 540 true 541elif [ -d ${NANO_SRC}/${NANO_TOOLS} ] ; then 542 NANO_TOOLS=${NANO_SRC}/${NANO_TOOLS} 543else 544 echo "NANO_TOOLS directory does not exist" 1>&2 545 exit 1 546fi 547 548export MAKEOBJDIRPREFIX 549 550export NANO_ARCH 551export NANO_CODESIZE 552export NANO_CONFSIZE 553export NANO_CUSTOMIZE 554export NANO_DATASIZE 555export NANO_DRIVE 556export NANO_HEADS 557export NANO_IMAGES 558export NANO_MAKE_CONF 559export NANO_MEDIASIZE 560export NANO_NAME 561export NANO_NEWFS 562export NANO_OBJ 563export NANO_PMAKE 564export NANO_SECTS 565export NANO_SRC 566export NANO_TOOLS 567export NANO_WORLDDIR 568 569####################################################################### 570# And then it is as simple as that... 571 572if $do_world ; then 573 clean_build 574 make_conf_build 575 build_world 576else 577 echo "## Skipping buildworld (as instructed)" 578fi 579 580if $do_kernel ; then 581 build_kernel 582else 583 echo "## Skipping buildkernel (as instructed)" 584fi 585 586clean_world 587make_conf_install 588install_world 589install_etc 590install_kernel 591 592run_customize 593setup_nanobsd 594prune_usr 595create_${NANO_ARCH}_diskimage 596last_orders 597 598echo "# NanoBSD image completed" 599