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