nanobsd.sh revision 150343
1#!/bin/sh 2# Copyright (c) 2005 Poul-Henning Kamp. 3# 4# See /usr/share/examples/etc/bsd-style-copyright for license terms. 5# 6# $FreeBSD: head/tools/tools/nanobsd/nanobsd.sh 150343 2005-09-19 20:55:44Z phk $ 7# 8 9set -e 10 11# Name of this NanoBSD build. (Used to construct workdir names) 12NANO_NAME=full 13 14# Source tree directory 15NANO_SRC=/usr/src 16 17# Object tree directory 18# default is subdir of /usr/obj 19# XXX: MAKEOBJDIRPREFIX handling... ? 20#NANO_OBJ="" 21 22# Parallel Make 23NANO_PMAKE="make -j 3" 24 25# Options to put in make.conf during buildworld only 26CONF_BUILD=' ' 27 28# Options to put in make.conf during installworld only 29CONF_INSTALL=' ' 30 31# Options to put in make.conf during both build- & installworld. 32CONF_WORLD=' ' 33 34# Kernel config file to use 35NANO_KERNEL=GENERIC 36 37# Customize commands. 38NANO_CUSTOMIZE="" 39 40# Newfs paramters to use 41NANO_NEWFS="-b 4096 -f 512 -i 8192 -O1 -U" 42 43# The drive name of the media at runtime 44NANO_DRIVE=ad0 45 46# Target media size in 512 bytes sectors 47NANO_MEDIASIZE=1048576 48 49# Number of code images on media (1 or 2) 50NANO_IMAGES=2 51 52# Size of code file system in 512 bytes sectors 53# If zero, size will be as large as possible. 54NANO_CODESIZE=0 55 56# Size of configuration file system in 512 bytes sectors 57# Cannot be zero. 58NANO_CONFSIZE=2048 59 60# Size of data file system in 512 bytes sectors 61# If zero: no partition configured. 62# If negative: max size possible 63NANO_DATASIZE=0 64 65# Media geometry, only relevant if bios doesn't understand LBA. 66NANO_SECTS=32 67NANO_HEADS=16 68 69####################################################################### 70# Not a variable at this time 71 72NANO_ARCH=i386 73 74####################################################################### 75# Functions which can be overridden in configs. 76 77clean_build ( ) ( 78 echo "## Clean and create object directory (${MAKEOBJDIRPREFIX})" 79 80 if rm -rf ${MAKEOBJDIRPREFIX} > /dev/null 2>&1 ; then 81 true 82 else 83 chflags -R noschg ${MAKEOBJDIRPREFIX} 84 rm -rf ${MAKEOBJDIRPREFIX} 85 fi 86 mkdir -p ${MAKEOBJDIRPREFIX} 87 printenv > ${MAKEOBJDIRPREFIX}/_.env 88) 89 90make_conf_build ( ) ( 91 echo "## Construct build make.conf ($NANO_MAKE_CONF)" 92 93 echo "${CONF_WORLD}" > ${NANO_MAKE_CONF} 94 echo "${CONF_BUILD}" >> ${NANO_MAKE_CONF} 95) 96 97build_world ( ) ( 98 echo "## run buildworld" 99 echo "### log: ${MAKEOBJDIRPREFIX}/_.bw" 100 101 cd ${NANO_SRC} 102 ${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF} buildworld \ 103 > ${MAKEOBJDIRPREFIX}/_.bw 2>&1 104) 105 106build_kernel ( ) ( 107 echo "## build kernel ($NANO_KERNEL)" 108 echo "### log: ${MAKEOBJDIRPREFIX}/_.bk" 109 110 if [ -f ${NANO_KERNEL} ] ; then 111 cp ${NANO_KERNEL} ${NANO_SRC}/sys/${NANO_ARCH}/conf 112 fi 113 114 cd ${NANO_SRC} 115 ${NANO_PMAKE} buildkernel \ 116 __MAKE_CONF=${NANO_MAKE_CONF} KERNCONF=${NANO_KERNEL} \ 117 > ${MAKEOBJDIRPREFIX}/_.bk 2>&1 118) 119 120clean_world ( ) ( 121 echo "## Clean and create world directory (${NANO_WORLDDIR})" 122 if rm -rf ${NANO_WORLDDIR}/ > /dev/null 2>&1 ; then 123 true 124 else 125 chflags -R noschg ${NANO_WORLDDIR}/ 126 rm -rf ${NANO_WORLDDIR}/ 127 fi 128 mkdir -p ${NANO_WORLDDIR}/ 129) 130 131make_conf_install ( ) ( 132 echo "## Construct install make.conf ($NANO_MAKE_CONF)" 133 134 echo "${CONF_WORLD}" > ${NANO_MAKE_CONF} 135 echo "${CONF_INSTALL}" >> ${NANO_MAKE_CONF} 136) 137 138install_world ( ) ( 139 echo "## installworld" 140 echo "### log: ${MAKEOBJDIRPREFIX}/_.iw" 141 142 cd ${NANO_SRC} 143 ${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF} installworld \ 144 DESTDIR=${NANO_WORLDDIR} \ 145 > ${MAKEOBJDIRPREFIX}/_.iw 2>&1 146 chflags -R noschg ${NANO_WORLDDIR} 147) 148 149install_etc ( ) ( 150 151 echo "## install /etc" 152 echo "### log: ${MAKEOBJDIRPREFIX}/_.etc" 153 154 cd ${NANO_SRC}/etc 155 ${NANO_PMAKE} __MAKE_CONF=${NANO_MAKE_CONF} distribution \ 156 DESTDIR=${NANO_WORLDDIR} \ 157 > ${MAKEOBJDIRPREFIX}/_.etc 2>&1 158) 159 160install_kernel ( ) ( 161 echo "## install kernel" 162 echo "### log: ${MAKEOBJDIRPREFIX}/_.ik" 163 164 cd ${NANO_SRC} 165 ${NANO_PMAKE} installkernel \ 166 DESTDIR=${NANO_WORLDDIR} \ 167 __MAKE_CONF=${NANO_MAKE_CONF} KERNCONF=${NANO_KERNEL} \ 168 > ${MAKEOBJDIRPREFIX}/_.ik 2>&1 169) 170 171setup_diskless ( ) ( 172 echo "## configure diskless setup" 173 echo "### log: ${MAKEOBJDIRPREFIX}/_.dl" 174 175 ( 176 cd ${NANO_WORLDDIR} 177 178 # create diskless marker file 179 touch etc/diskless 180 181 echo "/dev/${NANO_DRIVE}s1a / ufs ro 1 1" > etc/fstab 182 183 for d in var etc 184 do 185 # link /$d under /conf 186 # we use hard links so we have them both places. 187 # the files in /$d will be hidden by the mount. 188 # XXX: configure /$d ramdisk size 189 mkdir -p conf/base/$d conf/default/$d 190 find $d -print | cpio -dumpl conf/base/ 191 done 192 193 # pick up config files from the special partition 194 echo "mount -o ro /dev/${NANO_DRIVE}s3" > conf/default/etc/remount 195 196 # Put /tmp on the /var ramdisk (could be symlink already) 197 rmdir tmp || true 198 rm tmp || true 199 ln -s var/tmp tmp 200 201 ) > ${MAKEOBJDIRPREFIX}/_.dl 2>&1 202) 203 204run_customize() ( 205 206 echo "## run customize scripts" 207 for c in $NANO_CUSTOMIZE 208 do 209 echo "## customize \"$c\"" 210 echo "### log: ${MAKEOBJDIRPREFIX}/_.cust.$c" 211 echo "### `type $c`" 212 ( $c ) 2>&1 | tee ${MAKEOBJDIRPREFIX}/_.cust.$c 213 done 214) 215 216prune_usr() ( 217 218 # Remove all empty directories in /usr 219 find ${NANO_WORLDDIR}/usr -type d -depth -print | 220 while read d 221 do 222 rmdir $d > /dev/null 2>&1 || true 223 done 224) 225 226create_i386_diskimage ( ) ( 227 echo "## build diskimage" 228 echo "### log: ${MAKEOBJDIRPREFIX}/_.di" 229 230 ( 231 echo $NANO_MEDIASIZE $NANO_IMAGES \ 232 $NANO_SECTS $NANO_HEADS \ 233 $NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE | 234 awk ' 235 { 236 printf "# %s\n", $0 237 238 # size of cylinder in sectors 239 cs = $3 * $4 240 241 # number of full cylinders on media 242 cyl = int ($1 / cs) 243 244 # output fdisk geometry spec, truncate cyls to 1023 245 if (cyl <= 1023) 246 print "g c" cyl " h" $4 " s" $3 247 else 248 print "g c" 1023 " h" $4 " s" $3 249 250 if ($7 > 0) { 251 # size of data partition in full cylinders 252 dsl = int (($7 + cs - 1) / cs) 253 } else { 254 dsl = 0; 255 } 256 257 # size of config partition in full cylinders 258 csl = int (($6 + cs - 1) / cs) 259 260 if ($3 == 5) { 261 # size of image partition(s) in full cylinders 262 isl = int ((cyl - dsl - csl) / $2) 263 } else { 264 isl = int (($5 + cs - 1) / cs) 265 } 266 267 # First image partition start at second track 268 print "p 1 165 " $3, isl * cs - $3 269 c = isl * cs; 270 271 # Second image partition (if any) also starts offset one 272 # track to keep them identical. 273 if ($2 > 1) { 274 print "p 2 165 " $3 + c, isl * cs - $3 275 c += isl * cs; 276 } 277 278 # Config partition starts at cylinder boundary. 279 print "p 3 165 " c, csl * cs 280 c += csl * cs 281 282 # Data partition (if any) starts at cylinder boundary. 283 if ($7 > 0) { 284 print "p 4 165 " c, dsl * cs 285 } else if ($7 < 0 && $1 > $c) { 286 print "p 4 165 " c, $1 - $c 287 } 288 } 289 ' > ${MAKEOBJDIRPREFIX}/_.fdisk 290 291 IMG=${MAKEOBJDIRPREFIX}/_.disk.full 292 MNT=${MAKEOBJDIRPREFIX}/_.mnt 293 mkdir -p ${MNT} 294 295 dd if=/dev/zero of=${IMG} bs=${NANO_SECTS}b \ 296 count=`expr ${NANO_MEDIASIZE} / ${NANO_SECTS}` 297 298 MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} -y ${NANO_HEADS}` 299 300 trap "df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT 301 302 fdisk -i -f ${MAKEOBJDIRPREFIX}/_.fdisk ${MD} 303 fdisk ${MD} 304 # XXX: params 305 # XXX: pick up cached boot* files, they may not be in image anymore. 306 boot0cfg -B -b ${NANO_WORLDDIR}/boot/boot0sio -o packet -s 1 -m 3 ${MD} 307 bsdlabel -w -B ${MD}s1 308 bsdlabel ${MD}s1 309 310 # Create first image 311 newfs ${NANO_NEWFS} /dev/${MD}s1a 312 mount /dev/${MD}s1a ${MNT} 313 df -i ${MNT} 314 ( cd ${NANO_WORLDDIR} && find . -print | cpio -dump ${MNT} ) 315 df -i ${MNT} 316 ( cd ${MNT} && mtree -c ) > ${MAKEOBJDIRPREFIX}/_.mtree 317 ( cd ${MNT} && du -k ) > ${MAKEOBJDIRPREFIX}/_.du 318 umount ${MNT} 319 320 if [ $NANO_IMAGES -gt 1 ] ; then 321 # Duplicate to second image (if present) 322 dd if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k 323 fi 324 325 # Create Config slice 326 newfs ${NANO_NEWFS} /dev/${MD}s3 327 # XXX: fill from where ? 328 329 # Create Data slice, if any. 330 if [ $NANO_DATASIZE -gt 0 ] ; then 331 newfs ${NANO_NEWFS} /dev/${MD}s4 332 # XXX: fill from where ? 333 fi 334 335 dd if=/dev/${MD}s1 of=${MAKEOBJDIRPREFIX}/_.disk.image bs=64k 336 mdconfig -d -u $MD 337 ) > ${MAKEOBJDIRPREFIX}/_.di 2>&1 338) 339 340 341####################################################################### 342# 343# Heavy wizardry ahead, no user serviceable parts below. 344# 345####################################################################### 346 347####################################################################### 348 349customize_cmd () { 350 NANO_CUSTOMIZE="$NANO_CUSTOMIZE $1" 351} 352 353####################################################################### 354# Parse arguments 355 356args=`getopt c: $*` 357if [ $? -ne 0 ] ; then 358 echo "Usage: $0 [-c config file]" 1>&2 359 exit 2 360fi 361 362set -- $args 363for i 364do 365 case "$i" 366 in 367 -c) 368 . "$2" 369 shift; 370 shift; 371 ;; 372 --) 373 shift; 374 break; 375 esac 376done 377 378####################################################################### 379# Internal variables 380if [ "x${NANO_OBJ}" = "x" ] ; then 381 MAKEOBJDIRPREFIX=/usr/obj/nanobsd.${NANO_NAME}/ 382 NANO_OBJ=${MAKEOBJDIRPREFIX} 383else 384 MAKEOBJDIRPREFIX=${NANO_OBJ} 385fi 386 387NANO_WORLDDIR=${MAKEOBJDIRPREFIX}/_.w 388NANO_MAKE_CONF=${MAKEOBJDIRPREFIX}/make.conf 389 390####################################################################### 391# 392export MAKEOBJDIRPREFIX 393 394export NANO_ARCH 395export NANO_CODESIZE 396export NANO_CONFSIZE 397export NANO_CUSTOMIZE 398export NANO_DATASIZE 399export NANO_DRIVE 400export NANO_HEADS 401export NANO_IMAGES 402export NANO_MAKE_CONF 403export NANO_MEDIASIZE 404export NANO_NAME 405export NANO_NEWFS 406export NANO_OBJ 407export NANO_PMAKE 408export NANO_SECTS 409export NANO_SRC 410export NANO_WORLDDIR 411 412####################################################################### 413# As simple as that... 414 415clean_build 416make_conf_build 417build_world 418build_kernel 419 420clean_world 421make_conf_install 422install_world 423install_etc 424install_kernel 425 426run_customize 427setup_diskless 428prune_usr 429create_${NANO_ARCH}_diskimage 430 431echo "# NanoBSD image completed" 432