tinybsd revision 163017
1162485Sjulian#!/bin/sh - 2162485Sjulian# Copyright (c) 2006 Jean Milanez Melo <jmelo@freebsdbrasil.com.br> 3162485Sjulian# <jmelo@FreeBSD.org> 4162485Sjulian# Patrick Tracanelli <eksffa@freebsdbrasil.com.br> 5162485Sjulian# 6162485Sjulian# $FreeBSD: head/tools/tools/tinybsd/tinybsd 163017 2006-10-04 22:16:40Z julian $ 7162485Sjulian#set -xv 8162485SjulianCURRENTDIR=/usr/src/tools/tools/tinybsd 9162485SjulianWORKDIR=/usr/obj/tinybsdbuild 10162485SjulianKERNCONF=TINYBSD 11162485SjulianDEFINSTARGS="-o 0 -g 0 -m 555" 12162485SjulianTS="=====>" 13162485Sjulian 14163017Sjuliansplitarg1 () { 15163017Sjulian local IFS 16163017Sjulian IFS='=' 17163017Sjulian set $1 18163017Sjulian echo $1 19163017Sjulian} 20162485Sjulian 21163017Sjuliansplitarg2 () { 22163017Sjulian local IFS 23163017Sjulian IFS='=' 24163017Sjulian set $1 25163017Sjulian echo $2 26163017Sjulian} 27162485Sjulian 28163017Sjuliangetargs () { 29163017Sjulian ARGS="$*" 30163017Sjulian for arg in $* 31163017Sjulian do 32163017Sjulian ARG=`splitarg1 $arg` 33163017Sjulian VAL=`splitarg2 $arg` 34163017Sjulian case $ARG in 35163017Sjulian sectors) 36163017Sjulian SECTUNIT=$VAL 37163017Sjulian ;; 38163017Sjulian heads) 39163017Sjulian TRACKCYL=$VAL 40163017Sjulian ;; 41163017Sjulian spt) 42163017Sjulian SECTRACK=$VAL 43163017Sjulian ;; 44163017Sjulian conf) 45163017Sjulian CONF=$VAL 46163017Sjulian ;; 47163017Sjulian mfsroot) 48163017Sjulian MFSROOT=$VAL 49163017Sjulian ;; 50163017Sjulian image) 51163017Sjulian IMG=$VAL 52163017Sjulian ;; 53163017Sjulian batch) 54163017Sjulian NO_PROMPTS="YES" 55163017Sjulian ;; 56163017Sjulian new) 57163017Sjulian NO_READ="YES" 58163017Sjulian ;; 59163017Sjulian *) 60163017Sjulian usage 61163017Sjulian ;; 62163017Sjulian esac 63163017Sjulian done 64163017Sjulian} 65162485Sjulian 66163017Sjulianusage () { 67163017Sjulian echo "Woops 68163017Sjulian Usage: $0 sectors=<size of media> [80000] 69163017Sjulian heads=<heads according to firmware> [4] 70163017Sjulian spt=<sectors per track according to firmware> [32] 71163017Sjulian conf=<configuration name> (see conf/name) [default] 72163017Sjulian mfsroot[=<yes|no>] [no] 73163017Sjulian image=<tinybsd image name> [tinybsd.bin] 74163017Sjulian batch[=<anything>] (do not ask interactively) 75163017Sjulian new[=<anything>] (do not read previous values) 76162485Sjulian 77163017Sjulian Examples: 78163017Sjulian $0 sectors=65536 heads=8 spt=16 conf=wireless mfsroot=yes image=myimage.img batch 79162485Sjulian 80163017Sjulian Default values are set in the program. 81163017Sjulian Environment values override defaults. 82163017Sjulian Previous values override environment values but can be disabled. 83163017Sjulian Command arguments override previous values. 84163017Sjulian Interactive values override command arguments but can be disabled. 85163017Sjulian 86163017Sjulian Run diskinfo(8) -v against your CF device to get correct information 87163017Sjulian about your disk. USB keys do not need any specific geometry" 88163017Sjulian exit 1 89163017Sjulian} 90163017Sjulian 91163017Sjulian######## 92163017Sjulian# Load variables from stdin (could be a file) 93163017Sjulian# Look for lines that match foo=bar 94163017Sjulian# do not run the file.. that is asking for trouble 95163017Sjulian######## 96163017Sjulianloadvars () { 97163017Sjulian while : 98163017Sjulian do 99163017Sjulian OIFS=$IFS 100163017Sjulian IFS="=" 101163017Sjulian if read PART1 PART2 102163017Sjulian then 103163017Sjulian IFS="$OIFS" 104163017Sjulian case "$PART1" in 105163017Sjulian \#*) 106163017Sjulian echo "comment" 107163017Sjulian ;; 108163017Sjulian "") 109163017Sjulian ;; 110163017Sjulian *) 111163017Sjulian set "${PART1}" 112163017Sjulian if [ $# = "1" ] 113163017Sjulian then 114163017Sjulian eval "${PART1}='${PART2}'" 115163017Sjulian fi 116163017Sjulian ;; 117163017Sjulian esac 118163017Sjulian else 119163017Sjulian IFS="$OIFS" 120163017Sjulian return 0 121163017Sjulian fi 122163017Sjulian done 123163017Sjulian} 124163017Sjulian 125163017Sjulian######## 126163017Sjulian# get values from the user 127163017Sjulian######## 128163017Sjulianconfirm_action(){ 129163017Sjulian local ANSWER 130163017Sjulian local MESSAGE 131163017Sjulian ANSWER=$1 132163017Sjulian MESSAGE=$2 133163017Sjulian if [ "$NO_PROMPTS" != "YES" ] 134163017Sjulian then 135163017Sjulian echo -n "$MESSAGE [$ANSWER] use 'none' to clear ? " > /dev/tty 136163017Sjulian read result 137163017Sjulian [ "$result" != "" ] && ANSWER=$result 138163017Sjulian [ "$result" = "none" ] && ANSWER="" 139163017Sjulian fi 140163017Sjulian 141163017Sjulian ANSWER=`eval "echo $ANSWER"` 142163017Sjulian echo $ANSWER 143163017Sjulian} 144163017Sjulian 145163017Sjulian######## 146163017Sjulian# These are only used the VERY first time you run the program (on this machine) 147163017Sjulian######## 148163017Sjuliansetdefaults () { 149163017Sjulian NO_PROMPTS=${NO_PROMPTS:-NO} 150163017Sjulian NO_READ=${NO_READ:-NO} 151163017Sjulian SECTUNIT=${SECTUNIT:-80000}; export SECTUNIT 152163017Sjulian TRACKCYL=${TRACKCYL:-4}; export TRACKCYL 153163017Sjulian SECTRACK=${SECTRACK:-32}; export SECTRACK 154163017Sjulian CONF=${CONF:-default}; export CONF 155163017Sjulian MFSROOT=${MFSROOT:-NO}; export MFSROOT 156163017Sjulian IMG=${IMG:-tinybsd.bin}; export IMG 157163017Sjulian 158163017Sjulian} 159163017Sjulian 160163017Sjulian####### 161163017Sjulian# get ourselves set up. 162163017Sjulian# Partly by reading config files and partly from asking questions. 163163017Sjulian####### 164163017Sjulianloadconfig () { 165163017Sjulian if [ "${NO_READ}" = "YES" ] 166163017Sjulian then 167163017Sjulian return 168163017Sjulian fi 169163017Sjulian 170163017Sjulian HOSTNAME=`hostname` 171163017Sjulian HOSTPART=${HOSTNAME%%.*} 172163017Sjulian FILENAME=".tinybsd.${HOSTPART}.${USER}" 173163017Sjulian FULLFILENAME=$HOME/$FILENAME 174163017Sjulian 175163017Sjulian if [ -f ${FULLFILENAME} ] 176163017Sjulian then 177163017Sjulian loadvars <${FULLFILENAME} 178163017Sjulian fi 179163017Sjulian 180163017Sjulian SECTUNIT=`confirm_action "$SECTUNIT" "512 byte sectors per unit?"` 181163017Sjulian TRACKCYL=`confirm_action "$TRACKCYL" "Tracks per cylinder?"` 182163017Sjulian SECTRACK=`confirm_action "$SECTRACK" "Sectors per track?"` 183163017Sjulian CONF=`confirm_action "$CONF" "Configuration name?"` 184163017Sjulian MFSROOT=`confirm_action "$MFSROOT" "Use an MFSROOT?"` 185163017Sjulian IMG=`confirm_action "$IMG" "Image file to generate?"` 186163017Sjulian 187163017Sjulian# example of formatted value (NNN in this case) 188163017Sjulian# #condition and format the number 189163017Sjulian# if [ -z "${BUILDNUM}" ] 190163017Sjulian# then 191163017Sjulian# echo "Starting with build 001" 192163017Sjulian# BUILDNUM="001" 193163017Sjulian# else 194163017Sjulian# BUILDNUM=`printf "%03d\n" $(($BUILDNUM))` 195163017Sjulian# fi 196163017Sjulian 197163017Sjulian 198163017Sjulian} 199163017Sjulian 200163017Sjuliansaveconfig () { 201163017Sjulian HOSTNAME=`hostname` 202163017Sjulian HOSTPART=${HOSTNAME%%.*} 203163017Sjulian FILENAME=".tinybsd.${HOSTPART}.${USER}" 204163017Sjulian FULLFILENAME=$HOME/$FILENAME 205163017Sjulian ( 206163017Sjulian echo "# written by tinybsd" `date` 207163017Sjulian echo "SECTUNIT=${SECTUNIT}" 208163017Sjulian echo "TRACKCYL=${TRACKCYL}" 209163017Sjulian echo "SECTRACK=${SECTRACK}" 210163017Sjulian echo "CONF=${CONF}" 211163017Sjulian echo "MFSROOT=${MFSROOT:-NO}" 212163017Sjulian echo "IMG=${IMG}" 213163017Sjulian ) >${FULLFILENAME} 214163017Sjulian} 215163017Sjulian 216162485Sjuliancheck_conf() { 217163017Sjulian if [ ${CONF} = 'default' ] 218162485Sjulian then 219162485Sjulian echo "${TS} Alternative conf name not set; defaulting to 'default'" 220162485Sjulian fi 221162485Sjulian} 222162485Sjulian 223162485Sjuliancheck_alt_imgname() { 224163017Sjulian if [ ${IMG} = 'tinybsd.bin' ] 225162485Sjulian then 226162485Sjulian echo "${TS} Alternative image name not set; defaulting to 'tinybsd.bin'" 227162485Sjulian fi 228162485Sjulian} 229162485Sjulian 230162485Sjulianremove_workdir() { 231162485Sjulian chflags -R noschg ${WORKDIR} 232162485Sjulian echo "${TS} Removing "${WORKDIR} 233162485Sjulian rm -rf ${WORKDIR} 234162485Sjulian echo "${TS} Removing Build Kernel Directory" 235162485Sjulian rm -rf /usr/obj/usr/src/sys/${KERNCONF} 236162485Sjulian echo "${TS} done." 237162485Sjulian} 238162485Sjulian 239162485Sjulian 240162485Sjulianprework() { 241162485Sjulian remove_workdir 242162485Sjulian mkdir -p ${WORKDIR} 243162485Sjulian} 244162485Sjulian 245162485Sjulian 246162485Sjuliancreate_tree() { 247162485Sjulian echo "${TS} Creating directory hierarchy... " 248162485Sjulian mtree -deU -f /etc/mtree/BSD.root.dist -p ${WORKDIR} 249162485Sjulian mtree -deU -f /etc/mtree/BSD.usr.dist -p ${WORKDIR}/usr 250162485Sjulian mtree -deU -f /etc/mtree/BSD.var.dist -p ${WORKDIR}/var 251162485Sjulian} 252162485Sjulian 253162485Sjulian 254162485Sjuliancopy_binaries() { 255162485Sjulian#set -xv 256162485Sjulian for file in `cat ${CURRENTDIR}/conf/${CONF}/tinybsd.basefiles | grep -v "#" | \ 257162485Sjulian cut -f1 -d":" | sort | uniq` ; do 258162485Sjulian echo "${TS} Copying "/${file}" to "${WORKDIR}/${file} 259162485Sjulian cp -fp /${file} ${WORKDIR}/${file} ; 260162485Sjulian done 261162485Sjulian#set +xv 262162485Sjulian} 263162485Sjulian 264162485Sjulianmake_kernel() { 265162485Sjulian echo "${TS} Building customized tiny beastie kernel... " 266162485Sjulian cp -p ${CURRENTDIR}/conf/${CONF}/${KERNCONF} /usr/src/sys/i386/conf 267162485Sjulian cd /usr/src 268162485Sjulian make buildkernel KERNCONF=${KERNCONF} || exit 1 269162485Sjulian gzip -9 /usr/obj/usr/src/sys/${KERNCONF}/kernel 270162485Sjulian install ${DEFINSTARGS} /usr/obj/usr/src/sys/${KERNCONF}/kernel.gz ${WORKDIR}/boot/kernel/ 271162485Sjulian install ${DEFINSTARGS} \ 272162485Sjulian /usr/obj/usr/src/sys/${KERNCONF}/modules/usr/src/sys/modules/acpi/acpi/acpi.ko \ 273162485Sjulian ${WORKDIR}/boot/kernel 274162485Sjulian install -o 0 -g 0 -m 444 /sys/i386/conf/GENERIC.hints ${WORKDIR}/boot/device.hints 275162485Sjulian} 276162485Sjulian 277162485Sjulian 278162485Sjuliancopy_libraries() { 279162485Sjulian#set -xv 280162485Sjulian TDEPFILE="`mktemp -t deps`" 281162485Sjulian TDEPFILES="`mktemp -t depsymlnk`" 282162485Sjulian 283162485Sjulian cd ${CURRENTDIR}/conf/${CONF} 284162485Sjulian for file in `cat tinybsd.basefiles | grep -v "#" | cut -f1 -d":"`; do 285162485Sjulian ldd -f "%p\n" /${file} >> ${TDEPFILE} ; # don't worry on progs been "not dynamic" 286162485Sjulian done 287162485Sjulian 288162485Sjulian for libdeplib in `cat ${TDEPFILE} | sort | uniq`; do 289162485Sjulian ldd -f "%p\n" /${libdeplib} >> ${TDEPFILE} ; 290162485Sjulian done 291162485Sjulian 292162485Sjulian for pamdep in `ls -1 /usr/lib/pam*`; do 293162485Sjulian echo $pamdep >> ${TDEPFILE} ; 294162485Sjulian ldd -f "%p\n" /${pamdep} >> ${TDEPFILE} ; 295162485Sjulian done 296162485Sjulian 297162485Sjulian for lib in `cat ${TDEPFILE} | sort | uniq`; do 298162485Sjulian echo "${TS} Copying "${lib}" to "${WORKDIR}${lib} 299162485Sjulian cp -fp ${lib} ${WORKDIR}${lib} ; 300162485Sjulian done 301162485Sjulian 302162485Sjulian for depsymlink in `cat ${TDEPFILE}`; do 303162485Sjulian echo "${TS} Checking if ${depsymlink} is a symbolic link" 304162485Sjulian /bin/ls -l $depsymlink | grep "\->" | awk '{print $11":"$9}' >> ${TDEPFILES} 305162485Sjulian done 306162485Sjulian 307162485Sjulian for i in `cat ${TDEPFILES}`; do 308162485Sjulian SOURCE_FILE=`echo $i | awk -F ":" '{print $1}'` 309162485Sjulian TARGET_FILE=`echo $i | awk -F ":" '{print $2}'` 310162485Sjulian 311162485Sjulian echo "${TS} Unlinking ${WORKDIR}${TARGET_FILE}" 312162485Sjulian chroot ${WORKDIR} /bin/rm -f ${TARGET_FILE} 313162485Sjulian 314162485Sjulian echo "${TS} Symlinking ${SOURCE_FILE} to ${TARGET_FILE}" 315162485Sjulian chroot ${WORKDIR} /bin/ln -s ${SOURCE_FILE} ${TARGET_FILE} 316162485Sjulian done 317162485Sjulian 318162485Sjulian echo -n "${TS} Unlinking " 319162485Sjulian rm -fv ${TDEPFILE} ${TDEPFILES} 320162485Sjulian#set +xv 321162485Sjulian} 322162485Sjulian 323162485Sjulian 324162485Sjuliancreate_etc() { 325162485Sjulian cd /usr/src/etc/sendmail/ 326162485Sjulian make freebsd.cf freebsd.submit.cf 327162485Sjulian 328162485Sjulian cd /usr/src/etc/ 329162485Sjulian mkdir -p ${WORKDIR}/var/named/etc/namedb 330162485Sjulian make distribution DESTDIR=${WORKDIR} 331162485Sjulian} 332162485Sjulian 333163017Sjuliancreate_ssh_keys() { 334163017Sjulian echo "Creating ssh keys..." 335163017Sjulian ssh-keygen -t rsa1 -b 1024 -f ${WORKDIR}/etc/ssh/ssh_host_key -N '' 336163017Sjulian ssh-keygen -t dsa -f ${WORKDIR}/etc/ssh/ssh_host_dsa_key -N '' 337163017Sjulian ssh-keygen -t rsa -f ${WORKDIR}/etc/ssh/ssh_host_rsa_key -N '' 338163017Sjulian} 339163017Sjulian 340162485Sjulianpersonal_directories() { 341162485Sjulian echo "${TS} Copying your custom configuration on conf/ ..." 342162485Sjulian for custom in `find ${CURRENTDIR}/conf/${CONF}/ -type d -depth 1`; do 343162485Sjulian cp -Rp ${custom}/* ${WORKDIR}/${custom#${CURRENTDIR}/conf/${CONF}/}/ 344162485Sjulian done 345162485Sjulian} 346162485Sjulian 347162485Sjuliansymlinks() { 348162485Sjulian#set -xv 349162485Sjulian for i in `cat tinybsd.basefiles | grep -v "#" | grep ":"`; do 350162485Sjulian SOURCE_FILE=`echo $i | awk -F ":" {'print $1'}` 351162485Sjulian TARGET_FILE=`echo $i | awk -F ":" {'print $2'}` 352162485Sjulian chroot ${WORKDIR} /bin/ln -vs /${SOURCE_FILE} ${TARGET_FILE} 353162485Sjulian done 354162485Sjulian#set +xv 355162485Sjulian} 356162485Sjulian 357162485Sjulian 358162485Sjuliancreate_image() { 359162485Sjulian #set -ex 360162485Sjulian 361162485Sjulian VNODEFILE=`mktemp -t tinybsd` 362162485Sjulian IMGMNT=`mktemp -d -t tinybsd` 363162485Sjulian 364162485Sjulian dd if=/dev/zero of=${VNODEFILE} count=${SECTUNIT} 365162485Sjulian 366162485Sjulian MD=`mdconfig -a -t vnode -f ${VNODEFILE} -x ${SECTRACK} -y ${TRACKCYL}` 367162485Sjulian 368162485Sjulian diskinfo -v /dev/${MD} 369162485Sjulian 370162485Sjulian fdisk -I /dev/${MD} 371162485Sjulian fdisk /dev/${MD} 372162485Sjulian 373162485Sjulian cp -p /boot/boot0 ${WORKDIR}/boot/boot0 374162485Sjulian bsdlabel -w -B /dev/${MD} 375162485Sjulian newfs -O2 -U /dev/${MD}a 376162485Sjulian 377162485Sjulian mount /dev/${MD}a ${IMGMNT} 378162485Sjulian 379163017Sjulian if [ ${MFSROOT} = 'yes' ] 380163017Sjulian then 381163017Sjulian echo "${TS} Creating MFS root..." 382163017Sjulian # Update is not done yet 383163017Sjulian #mkdir -p ${WORKDIR}/usr/local/bin/ 384163017Sjulian #cp -p ${CURRENTDIR}/update/update ${WORKDIR}/usr/local/bin/ 385163017Sjulian rm ${WORKDIR}/etc/fstab 386163017Sjulian cd ${WORKDIR} && find . -print | sed '/kernel/ d' | cpio -dump ${IMGMNT} || true 387163017Sjulian umount ${IMGMNT} 388163017Sjulian dd if=/dev/${MD} of=${CURRENTDIR}/mfsroot.img 389163017Sjulian gzip -9 < ${CURRENTDIR}/mfsroot.img > ${CURRENTDIR}/mfsroot.gz 390163017Sjulian rm ${CURRENTDIR}/mfsroot.img 391163017Sjulian mount /dev/${MD}a ${IMGMNT} 392163017Sjulian rm -rf ${IMGMNT}/* 393163017Sjulian cp -rp ${WORKDIR}/boot ${IMGMNT} 394163017Sjulian rm ${IMGMNT}/boot/device.hints 395163017Sjulian ( \ 396163017Sjulian echo 'set vfs.root.mountfrom="ufs:/dev/md0a"' ; \ 397163017Sjulian echo 'set bootfile="/boot/kernel/kernel"' ; \ 398163017Sjulian sed -e '/^#/ d' -e 's/^/set /' < ${WORKDIR}/boot/device.hints ; \ 399163017Sjulian echo 'load /boot/kernel/kernel' ; \ 400163017Sjulian echo 'echo Loading mfsroot' ; \ 401163017Sjulian echo 'load -t mfs_root /mfsroot' ;\ 402163017Sjulian echo 'boot' ; \ 403163017Sjulian ) > ${IMGMNT}/boot/loader.rc 404163017Sjulian mv ${CURRENTDIR}/mfsroot.gz ${IMGMNT} 405163017Sjulian else 406163017Sjulian ( cd ${WORKDIR} && find . -print | cpio -dump ${IMGMNT} ) || true 407163017Sjulian fi 408162485Sjulian 409162485Sjulian df ${IMGMNT} 410163017Sjulian sleep 1 411162485Sjulian umount ${IMGMNT} 412162485Sjulian 413162485Sjulian dd if=/dev/${MD} of=${CURRENTDIR}/${IMG} bs=64k 414162485Sjulian 415162485Sjulian rm -vf ${VNODEFILE} 416162485Sjulian rm -rvf ${IMGMNT} 417162485Sjulian mdconfig -d -u ${MD} 418163017Sjulian echo "" 419163017Sjulian echo "${TS} Done!" 420163017Sjulian echo "${TS} Your configuration options were saved in ${FULLFILENAME}" 421163017Sjulian echo "${TS} You can see your build log in ${HOME}/tinybsd.log" 422163017Sjulian echo "${TS} Your final image is in ${CURRENTDIR}/${IMG}" 423163017Sjulian echo "${TS} Now use dd(1) to write it." 424163017Sjulian 425162485Sjulian} 426162485Sjulian 427162485Sjulian########################## 428162485Sjulian# run things 429163017Sjulian 430163017Sjulian########################################## 431163017Sjulian## The actual program 432163017Sjulian########################################## 433163017Sjuliangetargs $* 434163017Sjuliansetdefaults 435163017Sjulian# Load as many of the configuration options as we can 436163017Sjulianloadconfig 437163017Sjuliansaveconfig 438163017Sjulian 439163017Sjulian# Now start logging. 440163017Sjulian( 441163017Sjulian # Do the build 442163017Sjulian prework 443163017Sjulian check_conf 444163017Sjulian check_alt_imgname 445163017Sjulian create_tree 446163017Sjulian copy_binaries 447163017Sjulian make_kernel 448163017Sjulian copy_libraries 449163017Sjulian symlinks 450163017Sjulian create_etc 451163017Sjulian create_ssh_keys 452163017Sjulian personal_directories 453163017Sjulian create_image 454162485Sjulian#set +xv 455163017Sjulian) 2>&1 |tee -a ${HOME}/tinybsd.log 456162485Sjulian 457