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