2 # Copyright (c) 2006 Jean Milanez Melo <jmelo@freebsdbrasil.com.br>
4 # Patrick Tracanelli <eksffa@freebsdbrasil.com.br>
8 CURRENTDIR=/usr/src/tools/tools/tinybsd
9 if [ ! -d $CURRENTDIR ]
15 WORKDIR=/usr/obj/tinybsdbuild
17 BASEFILE="tinybsd.basefiles"
18 PORTSFILE="tinybsd.ports"
21 PKGFILES=/tmp/pkg.files
22 DEFINSTARGS="-o 0 -g 0 -m 555"
79 Usage: $0 sectors=<size of media> [80000]
80 heads=<heads according to firmware> [4]
81 spt=<sectors per track according to firmware> [32]
82 conf=<configuration name> (see conf/name) [default]
83 mfsroot[=<yes|no>] [no]
84 image=<tinybsd image name> [tinybsd.bin]
85 batch[=<anything>] (do not ask interactively)
86 new[=<anything>] (do not read previous values)
89 $0 sectors=65536 heads=8 spt=16 conf=wireless mfsroot=yes image=myimage.img batch
91 Default values are set in the program.
92 Environment values override defaults.
93 Previous values override environment values but can be disabled.
94 Command arguments override previous values.
95 Interactive values override command arguments but can be disabled.
97 Run diskinfo(8) -v against your CF device to get correct information
98 about your disk. USB keys do not need any specific geometry"
103 # Load variables from stdin (could be a file)
104 # Look for lines that match foo=bar
105 # do not run the file.. that is asking for trouble
124 eval "${PART1}='${PART2}'"
136 # get values from the user
143 if [ "$NO_PROMPTS" != "YES" ]
145 echo -n "$MESSAGE [$ANSWER] " > /dev/tty
147 [ "$result" != "" ] && ANSWER=$result
150 ANSWER=`eval "echo $ANSWER"`
155 # These are only used the VERY first time you run the program (on this machine)
158 NO_PROMPTS=${NO_PROMPTS:-NO}
159 NO_READ=${NO_READ:-NO}
160 SECTUNIT=${SECTUNIT:-80000}; export SECTUNIT
161 TRACKCYL=${TRACKCYL:-4}; export TRACKCYL
162 SECTRACK=${SECTRACK:-32}; export SECTRACK
163 CONF=${CONF:-default}; export CONF
164 MFSROOT=${MFSROOT:-NO}; export MFSROOT
165 IMG=${IMG:-tinybsd.bin}; export IMG
170 # get ourselves set up.
171 # Partly by reading config files and partly from asking questions.
174 if [ "${NO_READ}" = "YES" ]
180 HOSTPART=${HOSTNAME%%.*}
181 FILENAME=".tinybsd.${HOSTPART}.${USER}"
182 FULLFILENAME=$HOME/$FILENAME
184 if [ -f ${FULLFILENAME} ]
186 loadvars <${FULLFILENAME}
189 SECTUNIT=`confirm_action "$SECTUNIT" "512 byte sectors per unit?"`
190 TRACKCYL=`confirm_action "$TRACKCYL" "Tracks per cylinder?"`
191 SECTRACK=`confirm_action "$SECTRACK" "Sectors per track?"`
194 echo "The following configurations exist:"
195 ls -l conf|awk '/^d/{print " ",$9}'|grep -v CVS
196 CONF=`confirm_action "$CONF" "Configuration name?"`
197 if [ ! -d "${CURRENTDIR}/conf/$CONF" ]
199 echo "${TS} Error: Could not find config (${CONF})"
200 if [ "$NO_PROMPTS" = "YES" ]
208 MFSROOT=`confirm_action "$MFSROOT" "Use an MFSROOT? (YES/NO)"`
209 IMG=`confirm_action "$IMG" "Image file to generate?"`
211 # example of formatted value (NNN in this case)
212 # #condition and format the number
213 # if [ -z "${BUILDNUM}" ]
215 # echo "Starting with build 001"
218 # BUILDNUM=`printf "%03d\n" $(($BUILDNUM))`
226 HOSTPART=${HOSTNAME%%.*}
227 FILENAME=".tinybsd.${HOSTPART}.${USER}"
228 FULLFILENAME=$HOME/$FILENAME
230 echo "# written by tinybsd" `date`
231 echo "SECTUNIT=${SECTUNIT}"
232 echo "TRACKCYL=${TRACKCYL}"
233 echo "SECTRACK=${SECTRACK}"
235 echo "MFSROOT=${MFSROOT:-NO}"
240 check_alt_imgname() {
241 if [ ${IMG} = 'tinybsd.bin' ]
243 echo "${TS} Alternative image name not set; defaulting to 'tinybsd.bin'"
248 mv -f ${HOME}/tinybsd.log ${HOME}/tinybsd.log.old
252 chflags -R noschg ${WORKDIR}
253 echo "${TS} Removing "${WORKDIR}
255 echo "${TS} Removing Build Kernel Directory"
256 rm -rf /usr/obj/usr/src/sys/${KERNCONF}
268 echo "${TS} Creating directory hierarchy... "
269 mtree -deU -f /etc/mtree/BSD.root.dist -p ${WORKDIR}
270 mtree -deU -f /etc/mtree/BSD.usr.dist -p ${WORKDIR}/usr
271 mtree -deU -f /etc/mtree/BSD.local.dist -p ${WORKDIR}/usr/local
272 mtree -deU -f /etc/mtree/BSD.var.dist -p ${WORKDIR}/var
276 cd ${CURRENTDIR}/conf/${CONF}
278 for file in `cat ${BASEFILE} | grep -v "#" | \
279 cut -f1 -d":" | sort | uniq` ; do
280 echo "${TS} Copying "/${file}" to "${WORKDIR}/${file}
281 cp -fp /${file} ${WORKDIR}/${file} ;
286 for portname in `cat ${PORTSFILE} | grep -v '#'` ; do
287 cd ${PORTSDIR}/${portname}
288 pkgname=`make -V PKGNAME`
289 pkg_info -VQ ${pkgname}
291 if [ ${install} -eq 0 ] ; then
292 echo "$portname is already installed..."
303 create_missingdir() {
304 pkg_info -L ${pkgname} | egrep -v '(Information|Files|www|share|doc|man|include)' | sort | uniq >> ${PKGDIRS}
305 for dir in `cat ${PKGDIRS}`; do
306 if [ ! -d `dirname ${WORKDIR}/${dir}` ] ; then
307 mkdir -p `dirname ${WORKDIR}/${dir}`
314 pkg_info -L ${pkgname} | egrep -v '(Information|Files|www|share|doc|man|include)' >> ${PKGFILES}
315 for port in `cat ${PKGFILES}` ; do
316 echo "${TS} Copying "${port}" to "${WORKDIR}${port}
317 cp -fp ${port} ${WORKDIR}${port} ;
322 echo "${TS} Building customized tiny beastie kernel... "
323 cp -p ${CURRENTDIR}/conf/${CONF}/${KERNCONF} /usr/src/sys/i386/conf
325 make buildkernel KERNCONF=${KERNCONF} || exit 1
326 gzip -9 /usr/obj/usr/src/sys/${KERNCONF}/kernel
327 install ${DEFINSTARGS} /usr/obj/usr/src/sys/${KERNCONF}/kernel.gz ${WORKDIR}/boot/kernel/
328 install ${DEFINSTARGS} \
329 /usr/obj/usr/src/sys/${KERNCONF}/modules/usr/src/sys/modules/acpi/acpi/acpi.ko \
330 ${WORKDIR}/boot/kernel
331 install -o 0 -g 0 -m 444 /sys/i386/conf/GENERIC.hints ${WORKDIR}/boot/device.hints
335 TDEPFILE="`mktemp -t deps`"
336 TDEPFILES="`mktemp -t depsymlnk`"
338 cd ${CURRENTDIR}/conf/${CONF}
339 for file in `cat ${BASEFILE} ${PKGFILES} | grep -v "#" | cut -f1 -d":"`; do
340 ldd -f "%p\n" /${file} >> ${TDEPFILE} ; # don't worry on progs been "not dynamic"
345 for libdeplib in `cat ${TDEPFILE} | sort | uniq`; do
346 ldd -f "%p\n" /${libdeplib} >> ${TDEPFILE} ;
349 for pamdep in `ls -1 /usr/lib/pam*`; do
350 echo $pamdep >> ${TDEPFILE} ;
351 ldd -f "%p\n" /${pamdep} >> ${TDEPFILE} ;
354 for lib in `cat ${TDEPFILE} | sort | uniq`; do
355 echo "${TS} Copying "${lib}" to "${WORKDIR}${lib}
356 cp -fp ${lib} ${WORKDIR}${lib} ;
359 for depsymlink in `cat ${TDEPFILE}`; do
360 echo "${TS} Checking if ${depsymlink} is a symbolic link"
361 /bin/ls -l $depsymlink | grep "\->" | awk '{print $11":"$9}' >> ${TDEPFILES}
364 for i in `cat ${TDEPFILES}`; do
365 SOURCE_FILE=`echo $i | awk -F ":" '{print $1}'`
366 TARGET_FILE=`echo $i | awk -F ":" '{print $2}'`
368 echo "${TS} Unlinking ${WORKDIR}${TARGET_FILE}"
369 chroot ${WORKDIR} /bin/chflags 0 ${TARGET_FILE}
370 chroot ${WORKDIR} /bin/rm -f ${TARGET_FILE}
372 echo "${TS} Symlinking ${SOURCE_FILE} to ${TARGET_FILE}"
373 chroot ${WORKDIR} /bin/ln -s ${SOURCE_FILE} ${TARGET_FILE}
376 echo -n "${TS} Unlinking "
377 rm -fv ${TDEPFILE} ${TDEPFILES}
381 for portname in `cat ${PORTSFILE} | grep -v '#'` ; do
382 cd ${PORTSDIR}/${portname}
383 if [ $? -ne ${install} ] ; then
390 cd /usr/src/etc/sendmail/
391 make freebsd.cf freebsd.submit.cf
394 mkdir -p ${WORKDIR}/var/named/etc/namedb
395 make distribution DESTDIR=${WORKDIR}
399 echo "Creating ssh keys..."
400 ssh-keygen -t rsa1 -b 1024 -f ${WORKDIR}/etc/ssh/ssh_host_key -N ''
401 ssh-keygen -t dsa -f ${WORKDIR}/etc/ssh/ssh_host_dsa_key -N ''
402 ssh-keygen -t rsa -f ${WORKDIR}/etc/ssh/ssh_host_rsa_key -N ''
406 echo "${TS} Copying your custom configuration on conf/ ..."
407 for custom in `find ${CURRENTDIR}/conf/${CONF}/ -type d -depth 1 \! -name CVS`; do
408 cp -Rp ${custom}/* ${WORKDIR}/${custom#${CURRENTDIR}/conf/${CONF}/}/
411 if [ -f ${CURRENTDIR}/conf/${CONF}/boot.config ]; then
412 cp ${CURRENTDIR}/conf/${CONF}/boot.config ${WORKDIR}/boot.config
418 for i in `cat ${BASEFILE} ${PORTSFILE} | grep -v "#" | grep ":"`; do
419 SOURCE_FILE=`echo $i | awk -F ":" {'print $1'}`
420 TARGET_FILE=`echo $i | awk -F ":" {'print $2'}`
421 chroot ${WORKDIR} /bin/ln -vs /${SOURCE_FILE} ${TARGET_FILE}
428 VNODEFILE=`mktemp -t tinybsd`
429 IMGMNT=`mktemp -d -t tinybsd`
431 dd if=/dev/zero of=${VNODEFILE} count=${SECTUNIT}
433 MD=`mdconfig -a -t vnode -f ${VNODEFILE} -x ${SECTRACK} -y ${TRACKCYL}`
435 diskinfo -v /dev/${MD}
440 cp -p /boot/boot0 ${WORKDIR}/boot/boot0
441 bsdlabel -w -B /dev/${MD}
442 newfs -O2 -U /dev/${MD}a
444 mount /dev/${MD}a ${IMGMNT}
446 if [ ${MFSROOT} = 'yes' ]
448 echo "${TS} Creating MFS root..."
449 # Update is not done yet
450 #mkdir -p ${WORKDIR}/usr/local/bin/
451 #cp -p ${CURRENTDIR}/update/update ${WORKDIR}/usr/local/bin/
452 rm ${WORKDIR}/etc/fstab
453 cd ${WORKDIR} && find . -print | sed '/kernel/ d' | cpio -dump ${IMGMNT} || true
455 dd if=/dev/${MD} of=${CURRENTDIR}/mfsroot.img
456 gzip -9 < ${CURRENTDIR}/mfsroot.img > ${CURRENTDIR}/mfsroot.gz
457 rm ${CURRENTDIR}/mfsroot.img
458 mount /dev/${MD}a ${IMGMNT}
460 cp -rp ${WORKDIR}/boot ${IMGMNT}
461 rm ${IMGMNT}/boot/device.hints
463 echo 'set vfs.root.mountfrom="ufs:/dev/md0a"' ; \
464 echo 'set bootfile="/boot/kernel/kernel"' ; \
465 sed -e '/^#/ d' -e 's/^/set /' < ${WORKDIR}/boot/device.hints ; \
466 echo 'load /boot/kernel/kernel' ; \
467 echo 'echo Loading mfsroot' ; \
468 echo 'load -t mfs_root /mfsroot' ;\
470 ) > ${IMGMNT}/boot/loader.rc
471 mv ${CURRENTDIR}/mfsroot.gz ${IMGMNT}
473 ( cd ${WORKDIR} && find . -print | cpio -dump ${IMGMNT} ) || true
480 dd if=/dev/${MD} of=${CURRENTDIR}/${IMG} bs=64k
487 echo "${TS} Your configuration options were saved in ${FULLFILENAME}"
488 echo "${TS} You can see your build log in ${HOME}/tinybsd.log"
489 echo "${TS} Your final image is in ${CURRENTDIR}/${IMG}"
490 echo "${TS} Now use dd(1) to write it."
494 ##########################
497 ##########################################
498 ## The actual program
499 ##########################################
502 # Load as many of the configuration options as we can
526 ) 2>&1 |tee -a ${HOME}/tinybsd.log