diff options
Diffstat (limited to 'tools/tools/tinybsd/tinybsd')
-rwxr-xr-x | tools/tools/tinybsd/tinybsd | 526 |
1 files changed, 526 insertions, 0 deletions
diff --git a/tools/tools/tinybsd/tinybsd b/tools/tools/tinybsd/tinybsd new file mode 100755 index 000000000000..27216d4d2e3a --- /dev/null +++ b/tools/tools/tinybsd/tinybsd @@ -0,0 +1,526 @@ +#!/bin/sh - +# Copyright (c) 2006 Jean Milanez Melo <jmelo@freebsdbrasil.com.br> +# <jmelo@FreeBSD.org> +# Patrick Tracanelli <eksffa@freebsdbrasil.com.br> +# +# $FreeBSD$ +#set -xv +CURRENTDIR=/usr/src/tools/tools/tinybsd +if [ ! -d $CURRENTDIR ] +then + CURRENTDIR=`pwd` +else + cd $CURRENTDIR +fi + +WORKDIR=/usr/obj/tinybsdbuild +KERNCONF=TINYBSD +BASEFILE="tinybsd.basefiles" +PORTSFILE="tinybsd.ports" +PORTSDIR=/usr/ports +DEFINSTARGS="-o 0 -g 0 -m 555" +TINYARCH=$(uname -p) + +TS="=====>" + +splitarg1 () { + local IFS + IFS='=' + set $1 + echo $1 +} + +splitarg2 () { + local IFS + IFS='=' + set $1 + echo $2 +} + +getargs () { + ARGS="$*" + for arg in $* + do + ARG=`splitarg1 $arg` + VAL=`splitarg2 $arg` + case $ARG in + sectors) + SECTUNIT=$VAL + ;; + heads) + TRACKCYL=$VAL + ;; + spt) + SECTRACK=$VAL + ;; + conf) + CONF=$VAL + ;; + mfsroot) + MFSROOT=$VAL + ;; + image) + IMG=$VAL + ;; + batch) + NO_PROMPTS="YES" + ;; + new) + NO_READ="YES" + ;; + *) + usage + ;; + esac + done +} + +usage () { + echo "Woops + Usage: $0 sectors=<size of media> [80000] + heads=<heads according to firmware> [4] + spt=<sectors per track according to firmware> [32] + conf=<configuration name> (see conf/name) [default] + mfsroot[=<yes|no>] [no] + image=<tinybsd image name> [tinybsd.bin] + batch[=<anything>] (do not ask interactively) + new[=<anything>] (do not read previous values) + + Examples: + $0 sectors=65536 heads=8 spt=16 conf=wireless mfsroot=yes image=myimage.img batch + + Default values are set in the program. + Environment values override defaults. + Previous values override environment values but can be disabled. + Command arguments override previous values. + Interactive values override command arguments but can be disabled. + + Run diskinfo(8) -v against your CF device to get correct information + about your disk. USB keys do not need any specific geometry" + exit 1 +} + +######## +# Load variables from stdin (could be a file) +# Look for lines that match foo=bar +# do not run the file.. that is asking for trouble +######## +loadvars () { + while : + do + OIFS=$IFS + IFS="=" + if read PART1 PART2 + then + IFS="$OIFS" + case "$PART1" in + \#*) + ;; + "") + ;; + *) + set "${PART1}" + if [ $# = "1" ] + then + eval "${PART1}='${PART2}'" + fi + ;; + esac + else + IFS="$OIFS" + return 0 + fi + done +} + +######## +# get values from the user +######## +confirm_action(){ + local ANSWER + local MESSAGE + ANSWER=$1 + MESSAGE=$2 + if [ "$NO_PROMPTS" != "YES" ] + then + echo -n "$MESSAGE [$ANSWER] " > /dev/tty + read result + [ "$result" != "" ] && ANSWER=$result + fi + + ANSWER=`eval "echo $ANSWER"` + echo $ANSWER +} + +######## +# These are only used the VERY first time you run the program (on this machine) +######## +setdefaults () { + NO_PROMPTS=${NO_PROMPTS:-NO} + NO_READ=${NO_READ:-NO} + SECTUNIT=${SECTUNIT:-80000}; export SECTUNIT + TRACKCYL=${TRACKCYL:-4}; export TRACKCYL + SECTRACK=${SECTRACK:-32}; export SECTRACK + CONF=${CONF:-default}; export CONF + MFSROOT=${MFSROOT:-NO}; export MFSROOT + IMG=${IMG:-tinybsd.bin}; export IMG + +} + +####### +# get ourselves set up. +# Partly by reading config files and partly from asking questions. +####### +loadconfig () { + if [ "${NO_READ}" = "YES" ] + then + return + fi + + HOSTNAME=`hostname` + HOSTPART=${HOSTNAME%%.*} + FILENAME=".tinybsd.${HOSTPART}.${USER}" + FULLFILENAME=$HOME/$FILENAME + + if [ -f ${FULLFILENAME} ] + then + loadvars <${FULLFILENAME} + fi + + SECTUNIT=`confirm_action "$SECTUNIT" "512 byte sectors per unit?"` + TRACKCYL=`confirm_action "$TRACKCYL" "Tracks per cylinder?"` + SECTRACK=`confirm_action "$SECTRACK" "Sectors per track?"` + while : + do + echo "The following configurations exist:" + ls -l conf|awk '/^d/{print " ",$9}'|grep -v CVS + CONF=`confirm_action "$CONF" "Configuration name?"` + if [ ! -d "${CURRENTDIR}/conf/$CONF" ] + then + echo "${TS} Error: Could not find config (${CONF})" + if [ "$NO_PROMPTS" = "YES" ] + then + exit 1 + fi + else + break + fi + done + MFSROOT=`confirm_action "$MFSROOT" "Use an MFSROOT? (YES/NO)"` + IMG=`confirm_action "$IMG" "Image file to generate?"` + +# example of formatted value (NNN in this case) +# #condition and format the number +# if [ -z "${BUILDNUM}" ] +# then +# echo "Starting with build 001" +# BUILDNUM="001" +# else +# BUILDNUM=`printf "%03d\n" $(($BUILDNUM))` +# fi + + +} + +saveconfig () { + HOSTNAME=`hostname` + HOSTPART=${HOSTNAME%%.*} + FILENAME=".tinybsd.${HOSTPART}.${USER}" + FULLFILENAME=$HOME/$FILENAME + ( + echo "# written by tinybsd" `date` + echo "SECTUNIT=${SECTUNIT}" + echo "TRACKCYL=${TRACKCYL}" + echo "SECTRACK=${SECTRACK}" + echo "CONF=${CONF}" + echo "MFSROOT=${MFSROOT:-NO}" + echo "IMG=${IMG}" + ) >${FULLFILENAME} +} + +check_alt_imgname() { + if [ ${IMG} = 'tinybsd.bin' ] + then + echo "${TS} Alternative image name not set; defaulting to 'tinybsd.bin'" + fi +} + +rotate_buidlog() { + mv -f ${HOME}/tinybsd.log ${HOME}/tinybsd.log.old +} + +remove_workdir() { + # Before removing check if there is not a mount under $WORKDIR anymore + MOUNT_CHECK=`mount|egrep "on ${WORKDIR}"` + + if [ ! -z "${MOUNT_CHECK}" ]; then + echo "There are mounts under the workdir (${WORKDIR}). Please umount them before running this script" + exit 1 + else + chflags -R noschg ${WORKDIR} + echo "${TS} Removing "${WORKDIR} + rm -rf ${WORKDIR} + echo "${TS} Removing Build Kernel Directory" + rm -rf /usr/obj/usr/src/sys/${KERNCONF} + echo "${TS} done." + fi +} + + +prework() { + remove_workdir + mkdir -p ${WORKDIR} +} + + +create_tree() { + echo "${TS} Creating directory hierarchy... " + mtree -deU -f /etc/mtree/BSD.root.dist -p ${WORKDIR} + mtree -deU -f /etc/mtree/BIND.chroot.dist -p ${WORKDIR} + mtree -deU -f /etc/mtree/BSD.usr.dist -p ${WORKDIR}/usr + mtree -deU -f /etc/mtree/BSD.local.dist -p ${WORKDIR}/usr/local + mtree -deU -f /etc/mtree/BSD.var.dist -p ${WORKDIR}/var +} + +copy_binaries() { + cd ${CURRENTDIR}/conf/${CONF} + + for file in `cat ${CURRENTDIR}/conf/${CONF}/${BASEFILE} | grep -v "#" | \ + cut -f1 -d":" | sort | uniq` ; do + echo "${TS} Copying "/${file}" to "${WORKDIR}/${file} + cp -fp /${file} ${WORKDIR}/${file} ; + done +} + +install_ports() { + for portname in `cat ${CURRENTDIR}/conf/${CONF}/${PORTSFILE} | grep -v '#'` ; do + if [ ! -d "${WORKDIR}/usr/ports" ]; then + mkdir -p "${WORKDIR}/usr/ports" + fi + + PNAME=`/usr/bin/basename "${portname}"` + PORT_OPTION_FILE="/var/db/ports/${PNAME}/options" + + if [ -f "${PORT_OPTION_FILE}" ]; then + mkdir -p "${WORKDIR}/var/db/ports/${PNAME}" + cp "${PORT_OPTION_FILE}" "${WORKDIR}/var/db/ports/${PNAME}/" + fi + + mount_nullfs /lib "${WORKDIR}/lib" + mount_nullfs /usr/bin "${WORKDIR}/usr/bin" + mount_nullfs /usr/sbin "${WORKDIR}/usr/sbin" + mount_nullfs /usr/ports "${WORKDIR}/usr/ports" + mount_nullfs /usr/share "${WORKDIR}/usr/share" + mount_nullfs /usr/libexec "${WORKDIR}/usr/libexec" + mount_nullfs /usr/lib "${WORKDIR}/usr/lib" + mount_nullfs /usr/include "${WORKDIR}/usr/include" + + cd ${PORTSDIR}/${portname} + make fetch-recursive + make DESTDIR_ENV_LIST=PATH DESTDIR="${WORKDIR}" install + make clean + + umount "${WORKDIR}/lib" + umount "${WORKDIR}/usr/ports" + umount "${WORKDIR}/usr/bin" + umount "${WORKDIR}/usr/sbin" + umount "${WORKDIR}/usr/share" + umount "${WORKDIR}/usr/libexec" + umount "${WORKDIR}/usr/lib" + umount "${WORKDIR}/usr/include" + done +} + +make_kernel() { + echo "${TS} Building customized tiny beastie kernel... " + cp -p ${CURRENTDIR}/conf/${CONF}/${KERNCONF} /usr/src/sys/${TINYARCH}/conf + cd /usr/src + make buildkernel KERNCONF=${KERNCONF} || exit 1 + gzip -9 /usr/obj/usr/src/sys/${KERNCONF}/kernel + install ${DEFINSTARGS} /usr/obj/usr/src/sys/${KERNCONF}/kernel.gz ${WORKDIR}/boot/kernel/ + install ${DEFINSTARGS} \ + /usr/obj/usr/src/sys/${KERNCONF}/modules/usr/src/sys/modules/acpi/acpi/acpi.ko \ + ${WORKDIR}/boot/kernel + install -o 0 -g 0 -m 444 /sys/${TINYARCH}/conf/GENERIC.hints ${WORKDIR}/boot/device.hints +} + +copy_libraries() { + TDEPFILE="`mktemp -t deps`" + TDEPFILES="`mktemp -t depsymlnk`" + + find "${WORKDIR}" -type f |while read file; do + ldd -f "%p\n" ${file} >> ${TDEPFILE} ; # don't worry on progs been "not dynamic" + done + + for libdeplib in `cat ${TDEPFILE} | sort | uniq`; do + ldd -f "%p\n" /${libdeplib} >> ${TDEPFILE} ; + done + + for pamdep in `ls -1 /usr/lib/pam*`; do + echo $pamdep >> ${TDEPFILE} ; + ldd -f "%p\n" /${pamdep} >> ${TDEPFILE} ; + done + + for lib in `cat ${TDEPFILE} | sort | uniq`; do + echo "${TS} Copying "${lib}" to "${WORKDIR}${lib} + cp -fp ${lib} ${WORKDIR}${lib} ; + done + + for depsymlink in `cat ${TDEPFILE}`; do + echo "${TS} Checking if ${depsymlink} is a symbolic link" + /bin/ls -l $depsymlink | grep "\->" | awk '{print $11":"$9}' >> ${TDEPFILES} + done + + for i in `cat ${TDEPFILES}`; do + SOURCE_FILE=`echo $i | awk -F ":" '{print $1}'` + TARGET_FILE=`echo $i | awk -F ":" '{print $2}'` + + echo "${TS} Unlinking ${WORKDIR}${TARGET_FILE}" + chroot ${WORKDIR} /bin/chflags 0 ${TARGET_FILE} + chroot ${WORKDIR} /bin/rm -f ${TARGET_FILE} + + echo "${TS} Symlinking ${SOURCE_FILE} to ${TARGET_FILE}" + chroot ${WORKDIR} /bin/ln -s ${SOURCE_FILE} ${TARGET_FILE} + done + + echo -n "${TS} Unlinking " + rm -fv ${TDEPFILE} ${TDEPFILES} +} + +create_etc() { + cd /usr/src/etc/sendmail/ + make freebsd.cf freebsd.submit.cf + + cd /usr/src/etc/ + mkdir -p ${WORKDIR}/var/named/etc/namedb + make distribution DESTDIR=${WORKDIR} || exit 1 +} + +create_ssh_keys() { + echo "Creating ssh keys..." + ssh-keygen -t rsa1 -b 1024 -f ${WORKDIR}/etc/ssh/ssh_host_key -N '' + ssh-keygen -t dsa -f ${WORKDIR}/etc/ssh/ssh_host_dsa_key -N '' + ssh-keygen -t rsa -f ${WORKDIR}/etc/ssh/ssh_host_rsa_key -N '' +} + +personal_conf() { + echo "${TS} Copying your custom configuration on conf/ ..." + for custom in `find ${CURRENTDIR}/conf/${CONF}/ -type d -depth 1 \! -name CVS`; do + cp -Rp ${custom}/* ${WORKDIR}/${custom#${CURRENTDIR}/conf/${CONF}/}/ + done + + if [ -f ${CURRENTDIR}/conf/${CONF}/boot.config ]; then + cp ${CURRENTDIR}/conf/${CONF}/boot.config ${WORKDIR}/boot.config + fi +} + +symlinks() { +#set -xv + for i in `cat ${CURRENTDIR}/conf/${CONF}/${BASEFILE}| grep -v "#" | grep ":"`; do + SOURCE_FILE=`echo $i | awk -F ":" {'print $1'}` + TARGET_FILE=`echo $i | awk -F ":" {'print $2'}` + chroot ${WORKDIR} /bin/ln -vs /${SOURCE_FILE} ${TARGET_FILE} + done +#set +xv +} + + +create_image() { + VNODEFILE=`mktemp -t tinybsd` + IMGMNT=`mktemp -d -t tinybsd` + + dd if=/dev/zero of=${VNODEFILE} count=${SECTUNIT} + + MD=`mdconfig -a -t vnode -f ${VNODEFILE} -x ${SECTRACK} -y ${TRACKCYL}` + + diskinfo -v /dev/${MD} + + fdisk -I /dev/${MD} + fdisk /dev/${MD} + + cp -p /boot/boot0 ${WORKDIR}/boot/boot0 + bsdlabel -w -B /dev/${MD} + newfs -O2 -U /dev/${MD}a + + mount /dev/${MD}a ${IMGMNT} + + if [ ${MFSROOT} = 'yes' ] + then + echo "${TS} Creating MFS root..." + # Update is not done yet + #mkdir -p ${WORKDIR}/usr/local/bin/ + #cp -p ${CURRENTDIR}/update/update ${WORKDIR}/usr/local/bin/ + rm ${WORKDIR}/etc/fstab + cd ${WORKDIR} && find . -print | sed '/kernel/ d' | cpio -dump ${IMGMNT} || true + umount ${IMGMNT} + dd if=/dev/${MD} of=${CURRENTDIR}/mfsroot.img + gzip -9 < ${CURRENTDIR}/mfsroot.img > ${CURRENTDIR}/mfsroot.gz + rm ${CURRENTDIR}/mfsroot.img + mount /dev/${MD}a ${IMGMNT} + rm -rf ${IMGMNT}/* + cp -rp ${WORKDIR}/boot ${IMGMNT} + rm ${IMGMNT}/boot/device.hints + ( \ + echo 'set vfs.root.mountfrom="ufs:/dev/md0a"' ; \ + echo 'set bootfile="/boot/kernel/kernel"' ; \ + sed -e '/^#/ d' -e 's/^/set /' < ${WORKDIR}/boot/device.hints ; \ + echo 'load /boot/kernel/kernel' ; \ + echo 'echo Loading mfsroot' ; \ + echo 'load -t mfs_root /mfsroot' ;\ + echo 'boot' ; \ + ) > ${IMGMNT}/boot/loader.rc + mv ${CURRENTDIR}/mfsroot.gz ${IMGMNT} + else + ( cd ${WORKDIR} && find . -print | cpio -dump ${IMGMNT} ) || true + fi + + df ${IMGMNT} + sleep 1 + umount ${IMGMNT} + + dd if=/dev/${MD} of=${CURRENTDIR}/${IMG} bs=64k + + rm -vf ${VNODEFILE} + rm -rvf ${IMGMNT} + mdconfig -d -u ${MD} + echo "" + echo "${TS} Done!" + echo "${TS} Your configuration options were saved in ${FULLFILENAME}" + echo "${TS} You can see your build log in ${HOME}/tinybsd.log" + echo "${TS} Your final image is in ${CURRENTDIR}/${IMG}" + echo "${TS} Now use dd(1) to write it." +} + +########################## +# run things + +########################################## +## The actual program +########################################## +getargs $* +setdefaults +# Load as many of the configuration options as we can +loadconfig +saveconfig + +# Rotate build log +rotate_buidlog + +# Now start logging. +( + # Do the build + prework + check_alt_imgname + create_tree + copy_binaries + create_etc + install_ports + make_kernel + copy_libraries + symlinks + create_ssh_keys + personal_conf + create_image +#set +xv +) 2>&1 |tee -a ${HOME}/tinybsd.log + |