2016-10-14 15:16:44 +00:00

1118 lines
32 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh -
#
# $FreeBSD$
# This file requires sysutils/makefs to run
#
# The PicoBSD build script. Invoked as
#
# picobsd [options] image_type [site_name]
#
# CWARNFLAGS can be used to pass -Wall or similar options
#export CWARNFLAGS=-D______________sxasxa__________________________
#export WARNS=2
# EFIABI... unused attributes ?
export NO_WERROR=1
#
# Where image_type is a directory with the picobsd config info,
# and ${image_type}/floppy.tree.${site_name} contains
# optional site-specific configuration.
#
# For Options, see the bottom of the file where the processing is
# done. The picobsd(8) manpage might be of some help, but code and docs
# tend to lose sync over time.
#
# This script depends on the following files:
#
# in ${PICO_TREE} :
# Makefile.conf Makefile used to build the kernel
# config shell variables, sourced here.
# mfs.mtree mtree config file
# floppy.tree/ files which go on the floppy
# mfs_tree/ files which go onto the mfs
#
# in ${MY_TREE} :
# PICOBSD kernel config file
# config shell variables, sourced here.
# crunch.conf crunchgen configuration
# mfs.mtree overrides ${PICO_TREE}/mfs.mtree
# floppy.tree.exclude files from floppy.tree/ which we do not need here.
# floppy.tree/ local additions to ${PICO_TREE}/mfs_free
# floppy.tree.${site}/ same as above, site specific.
# mfs_tree/ local additions to the mfs_free
# buildtree.mk optional Makefile to build an extension for floppy tree
# (generated in buildtree/ )
#
#--- The main entry point is at the end.
#
# There are two initialization functions:
#
# + set_defaults
# is run on entry to the script, and is used to set default values
# for all variables that do not depend on image type and source tree.
#
# + set_build_parameters
# is run after command line parsing
#
# VARIABLE NAMES:
# + variables that control operation (e.g. verbosity) and are generally
# set from the command line have o_ ("option") as a name prefix
#
# + variables that contain pathnames and values that should not change
# have c_ ("constant") as a name prefix
#
# + variables exported to Makefiles and subshells are CAPITAL
#
# + variables local to the script are lowercase, possibly with
# an l_ ("local") prefix.
#
# There are unfortunately exceptions:
# name, l_usrtree, l_objtree
# SRC points to your FreeBSD source tree.
# l_usrtree points to the /usr subdir for the source tree.
# Normally /usr or ${SRC}/../usr
# l_objtree points to the obj tree. Normally ${l_usrtree}/obj-pico-${o_arch}
# c_label is either bsdlabel or disklabel
# PICO_TREE is where standard picobsd stuff resides.
# Normally ${SRC}/release/picobsd
# You can set SRC with --src <directory>
# It is not recommended to override the other variables.
# MY_TREE (set later) is where this floppy type resides.
# BUILDDIR is the build directory
# log something on stdout if verbose.
o_verbose=0 # this needs to be here!
log() { # message
local foo
[ ${o_verbose} -gt 0 ] && printf "\n*** %s\n" "$*"
[ ${o_verbose} -gt 1 ] && read -p "=== Press enter to continue" foo
return 0
}
# unconditionally log and wait for input
logverbose() { # message
local foo
printf "\n*** %s\n" "$*" >&2
read -p "=== Press enter to continue" foo
return 0
}
# set some default values for variables.
# needs to be done as the first thing in the script.
set_defaults() { # no arguments
# EDITOR is the editor you use
# fd_size floppy size in KB (default to 1440). You can use 1480,
# 1720, 2880, etc. but beware that only 1440 and 1480 will boot
# from 1.44M floppy drives (1480 will not work on vmware).
EDITOR=${EDITOR:-vi}
fd_size=${fd_size:-1440}
o_all_in_mfs="yes" # put all files in mfs so you can boot
# and run the image via diskless boot.
o_clean="" # set if you want to clean prev.builds.
o_interactive="" # default is interactive
o_verbose=0 # verbose level, 0 is silent
o_tarv="" # tar verbose flag, "" or "v"
o_init_src="" # set to build libs and includes.
o_makeopts=${MAKEOPTS:--s} # make options, be silent by default
o_no_devfs= # default is use devfs.
# You should only set it when building 4.x images
o_do_modules="" # do not build modules
o_arch=`uname -m` # default to amd64 or i386 ...
SRC="/usr/src" # default location for sources
c_startdir=`pwd` # directory where we start
# used to lookup config and create BUILDDIR
# XXX 6.x/7.x have a single /boot/boot block, which is the concatenation
# of the old two. For the time being, we keep these, but this should
# be fixed at some point.
# blocks
c_boot1=/boot/boot1 # boot blocks (in case you want custom ones)
c_boot2=/boot/boot2
c_reply=${c_reply:-`mktemp "/tmp/reply.XXXXXXXXXX"`}
# file where User replies will be put
c_mnt=`mktemp -d "/tmp/picobsd.XXXXXXXXXX"`
# mountpoint used to build memory filesystems
c_fs=fs.PICOBSD # filename used for the memory filesystem
c_img=picobsd.bin # filename used for the picobsd image
c_iso=picobsd.iso # filename used for the ISO image
generate_iso="NO" # don't generate the iso image
# select the right disklabel program
case `uname -r` in
4.*)
c_label="disklabel"
;;
*)
c_label="bsdlabel"
;;
esac
set -e
trap fail 2
#trap fail 3
#trap fail 6
trap fail 15
}
# use the new build infrastructure to create libraries
# and also to build a specific target
create_includes_and_libraries2() { # opt_dir opt_target
local no
log "create_includes_and_libraries2() for ${SRC} $1"
no="-DNO_CLEAN -DMK_PROFILE=no -DNO_GAMES -DNO_LIBC_R" # WITHOUT_CDDL=1"
no="$no -DWITHOUT_CASPER"
no="$no -DMALLOC_PRODUCTION"
( cd ${SRC};
# make -DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R -DPICOBSD buildworld
if [ -d "$1" ] ; then
cd $1 ; ${BINMAKE} ${o_par} $2 # specific target, e.g. ld-elf.so
else
export MAKEOBJDIRPREFIX=${l_objtree}
make ${o_par} $no toolchain
# XXX do we need any of these ?
eval export `cd ${SRC}; ${BINMAKE} -f Makefile.inc1 -V WMAKEENV`
[ ${o_arch} != `uname -m` ] && \
(cd ${l_objtree}; ln -s . ${o_arch}.${o_arch} || true )
fi
)
}
# set_type <the_type> [the_site] looks in user or system directories
# for the directory named as the first argument, reads the configuration
# files and sets variables according to the config.
# Also sets MY_TREE and BUILDDIR and SITE
set_type() { # the_type the_site
local a i
log "set_type() : Type '$1' site '$2'"
THETYPE=$1
SITE=$2
a=$1
name="" # clear in case of errors
for i in ${c_startdir}/${a} ${PICO_TREE}/${a} ; do
log "set_type: checking $i"
[ -d $i -a -f $i/crunch.conf ] || continue
# look for a kernel config file, privilege arch-specific
l_kernconf=$i/PICOBSD.${o_arch}
[ -f $l_kernconf ] || l_kernconf=$i/PICOBSD
[ -f $l_kernconf ] || continue
set -- `cat $l_kernconf | \
awk '/^#PicoBSD/ {print $2, $3, $4, $5, $6}'`
[ x"$1" != "x" ] || continue
MFS_SIZE=$1
name=`(cd $i ; pwd) `
name=`basename $name`
MY_TREE=$i
BUILDDIR=${c_startdir}/build_dir-${name}-${o_arch}
log "Matching file $name in $i"
return ;
done
logverbose "Type $a NOT FOUND"
}
clean_tree() {
log "clean_tree()"
if [ -z "${name}" ] ; then
echo "---> Wrong floppy type"
exit 3
fi
rm -rf ${BUILDDIR}
}
# prepare a message to be printed in the dialog menus.
set_msgs() { # OK
log "set_msgs()"
MSG1="Type: ${THETYPE} name $name"
MSG="PicoBSD build -- Current parameters:\n\n\t1. ${MSG1}\n\
\t2. MFS size: ${MFS_SIZE} kB\n\
\t3. Site-info: ${SITE}\n\t4. Full-path: ${MY_TREE}\n"
}
# Main build procedure. Builds both the disk image and the ISO
build_image() {
log "build_image() <${name}>"
[ -n "${name}" ] || fail $? bad_type
clear
set_msgs
printf "${MSG}---> We'll use the sources living in ${SRC}\n\n"
# read config variables from a global and then a type-specific file
# basically STAND_LINKS and MY_DEVS, but can also override other
# variables.
#
. ${PICO_TREE}/build/config
[ -f "${MY_TREE}/config" ] && . ${MY_TREE}/config
[ -f "${o_additional_config}" ] && . ${o_additional_config}
# location of the object directory
PICO_OBJ=${l_objtree}/picobsd/${THETYPE}
log "PICO_OBJ is ${PICO_OBJ}"
# create build directory and subtree
mkdir -p ${BUILDDIR}/crunch
# remove any old stuff
rm -f ${BUILDDIR}/kernel.gz ${BUILDDIR}/${c_fs}
# invoke commands to build a kernel
do_kernel
# fill a subdirectory with things that go into the floppy
# (mostly /etc and similar stuff)
populate_floppy_fs
# populate it and produce a file with the MFS image
populate_mfs_tree # things which go into mfs
# create, mount and fill a filesystem with floppy image
fill_floppy_image # copies everything into the floppy
}
# Set build parameters interactively
main_dialog() {
local ans i l
log "main_dialog()"
while true ; do
set_msgs
rm ${c_reply}
dialog --menu "PicoBSD build menu -- (29 sep 2001)" 19 70 12 \
N "--> READY, build it <---" \
T "${MSG1}" \
K "edit Kernel config file" \
E "Edit crunch.conf file" \
S "MFS Size: ${MFS_SIZE}kB" \
F "Floppy size: ${fd_size}kB" \
$ "Site-info: ${SITE}" \
Q "Quit" \
2> ${c_reply}
ans=`cat ${c_reply}`
rm ${c_reply}
case ${ans} in
T)
l=""
for i in ${c_startdir} ${c_startdir}/* ${PICO_TREE}/* ; do
if [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ]; then
l="$l `basename $i` `basename $i`"
fi
done
log $l
{ dialog --menu "Setup the type of configuration" 12 70 5 $l \
2> ${c_reply} && set_type "`cat ${c_reply}`" ${SITE} ; } || true
;;
K) ${EDITOR} ${MY_TREE}/PICOBSD ;;
E) ${EDITOR} ${MY_TREE}/crunch.conf ;;
S)
{ dialog --title "MFS Size setup" --inputbox \
"MFS size depends on what you need to put on the MFS image. Typically \
ranges between 820kB (for very small bridge/router images) to \
as much as 2500kB kB for a densely packed image. \
Keep in mind that this memory is \
totally lost to other programs. Usually you want to keep \
this as small as possible. " 10 70 2> ${c_reply} \
&& MFS_SIZE=`cat ${c_reply}` ; } || true
;;
\$)
{ dialog --title "Site info setup" --inputbox \
"Please enter the full path to the directory \
containing site-specific setup. \
This directory tree must contain files that replace \
standard ones in floppy.tree/ and mfs.tree/ . " \
10 70 2> ${c_reply} && SITE=`cat ${c_reply}` ; } || true
;;
F)
{ dialog --menu "Set floppy size" 15 70 4 \
1440 "1.44MB" 1720 "1.72MB" 2880 "2.88MB" 4096 "4MB" \
2> ${c_reply} && fd_size=`cat ${c_reply}` ; } || true
;;
N) break 2
;;
Q) exit 0 ;;
*) echo "Unknown option \"${ans}\". Try again."
sleep 2
clear
;;
esac
done
}
# Call the build procedure
# Install image
do_install() {
log "do_install()"
if [ "${o_interactive}" = "NO" ] ; then
echo "+++ Build completed +++"
cat .build.reply || true
return
fi
dialog --title "Build ${THETYPE} completed" --inputbox \
"\nThe build process was completed successfully.\n\
`cat .build.reply` \n\n\
Now we are going to install the image on the floppy.\n\
Please insert a blank floppy in /dev/fd0.\\n
WARNING: the contents of the floppy will be permanently erased!\n\
\n\
Your options:\n\
* ^C or [Cancel] to abort,\n\
* Enter to install ${c_img},\n\
" 20 80 2> ${c_reply}
if [ "$?" = "0" ]; then
echo "Writing ${c_img}..."
dd if=${BUILDDIR}/${c_img} of=/dev/fd0.${fd_size}
else
echo "Ok, the image is in ${c_img}"
fi
echo "Done."
}
#-------------------------------------------------------------------
# invoke the picobsd Makefile to compile the kernel.
# if MODULES is set (value is irrelevant) the makefile will build modules.
do_kernel() { # OK
log "do_kernel() Preparing kernel \"$name\" in $MY_TREE"
(cd $MY_TREE; export name SRC BUILDDIR # used in this makefile ;
# export CONFIG
export WARNS CWARNFLAGS
[ "${o_do_modules}" = "yes" ] && export MODULES=""
# kernel build not parallelizable yet
${BINMAKE} KERNCONF=${l_kernconf} \
-f ${PICO_TREE}/build/Makefile.conf ) || \
fail $? missing_kernel
}
# Populate the variable part of the floppy filesystem. Must be done before
# the MFS because its content might need to be copied there as well.
#
# This involves fetching files from three subtrees, in this order:
#
# 1. a standard one, from which type-specific files are excluded;
# 2. a type-specific one;
# 3. a site-specific one.
#
# Files are first copied to a local tree and then compressed.
populate_floppy_fs() { # OK
local dst excl srcdir
log "populate_floppy_fs()"
dst=${BUILDDIR}/floppy.tree
log "pwd=`pwd` Populating floppy filesystem..."
rm -rf ${dst} || true # clean relics from old compilations.
mkdir ${dst} # create a clean tree
# compute exclude list for generic tree
excl=${MY_TREE}/floppy.tree.exclude
if [ -f ${excl} ] ; then
log "Files excluded from generic tree: `echo;cat ${excl}`"
excl="--exclude-from ${excl}"
else
excl=""
fi
# copy from the floppy trees into the destination
for FLOPPY_TREE in ${PICO_TREE}/floppy.tree ${MY_TREE}/floppy.tree \
${MY_TREE}/floppy.tree.${SITE} ; do
if [ -d ${FLOPPY_TREE} ] ; then
(cd ${FLOPPY_TREE} ; tar -cf - \
--exclude .svn ${excl} . ) | \
(cd ${dst} ; tar x${o_tarv}f - )
log "Copied from ${FLOPPY_TREE}"
fi
excl="" # reset the exclude list.
done
# add local manipulation
if [ -f ${MY_TREE}/buildtree.mk ] ; then
log "building local floppy tree"
${BINMAKE} -C ${dst} -f ${MY_TREE}/buildtree.mk floppy.tree
fi
# compress the files in etc/, just in case
# XXX this should be done in the makefile.
# gzip returns an error if it fails to compress some file
(cd $dst ; gzip -9 etc/*
log "Compressed files in etc/ `echo; ls -l etc`"
) || true
}
# Copy the specified files to the destination filesystem.
# Each file is specified as a pair "src dst", dst is assumed to be
# a directory (and created with mkdir -p) if it has a trailing /
# Be careful to escape metacharacters.
# You can use ${CROSS} to point to the root of the cross build
# (remember that it might be incomplete)
do_copyfiles() { # rootdir varname
log Copy files to $1
local root=$1
local srcs dst
local CROSS=${_SHLIBDIRPREFIX}
eval set "\${${2}}"
srcs=""
for dst in $* ; do
[ -z "$srcs" ] && srcs=$dst && continue
eval srcs="$srcs" # expand wildcard and vars
case x"$dst" in
*/ ) mkdir -p ${root}/${dst} ;;
# * ) mkdir -p `dirname ${root}/${dst}` ;;
esac
cp -p ${srcs} ${root}/${dst} || true
srcs=""
done
}
# do_links is a helper function to create links between programs
# in stand/
# This is done reading the names and destination from variable
# links in a config file, in the format
# : dst names
do_links() { # rootdir varname
local root=$1
local l i dst
eval l="\${${2}}"
dst=""
log "Create links for ${l}"
(cd ${root}/stand
for i in $l ; do
if [ "$dst" = ":" -o "$i" = ":" ] ; then
dst=$i
elif [ -n "${dst}" ] ; then
ln -s ${dst} ${i}
fi
done
)
}
# find_progs is a helper function to locate the named programs
# or libraries in ${o_objdir} or ${_SHLIBDIRPREFIX},
# and return the full pathnames.
# Called as "find_progs [[-L libpath] [-P binpath]] prog1 prog2 ... "
# On return it sets ${u_progs} to the list of programs, and ${u_libs}
# to the list of shared libraries used.
#
# '-L path' can be used to specify a search path for libraries
# (which searches in $path/lib:$path/usr/lib:$path/usr/local/lib
# '-P binpath' can be used to specify a search path for programs
# (which searches in a lot of places in the subtree)
# -L must be the first, followed by -P
#
# You can use it e.g. in a local confign file by writing
#
# do_copyfiles_user() {
# local dst=$1
# find_progs nvi sed less grep
# cp -p ${u_progs} ${dst}/bin
# cp -p ${u_libs} ${dst}/lib
# mkdir -p ${dst}/libexec
# find_progs ld-elf.so.1
# cp -p ${u_progs} ${dst}/libexec # ignore errors
# }
# find programs and required libraries. Accept -L libs -P path <progs>
# if no argument default to objdir/SHLIBDIRPREFIX for both
find_progs() { # programs
# logverbose "find_progs: called with $*"
# rev.284898 removed _SHLIBDIRPREFIX so we need to reconstruct
# its value in i1
local i1=${_SHLIBDIRPREFIX:-${l_objtree}/${SRC}/tmp}
local i=`realpath ${o_objdir:-${i1}/..}`
# default values for -L and -P
local dir="-P $i"
local ldir="-L $i"
while [ "$1" != "" ] ; do
if [ x"$1" = "x-L" -a -d "$2" ] ; then # set lib search path
ldir="-L $2"; shift; shift
elif [ x"$1" = "x-P" -a -d "$2" ] ; then # set prog search path
dir="-P $2"; shift; shift
else
break
fi
done
# Results are returned in global variables
u_libs=""
u_progs="`find_progs_helper $dir $*`"
[ -z "${u_progs}" ] && return 1 # not found, error
# use objdump to find libraries.
# Iterate to fetch recursive dependencies.
local tmp="${u_progs}"
local old_libs=""
local pass=1
while [ $pass -lt 10 ] ; do
pass=$(($pass + 1))
i="`objdump -x ${tmp} | \
awk '$1 == "NEEDED" { print $2 }' | sort | uniq | tr '\n' ' '`"
if [ "$old_libs" = "$i" ] ; then
# logverbose "find_progs: have `echo ${u_libs} | wc -w`/`echo ${i} | wc -w` libraries for: $my_progs ($u_progs)"
# logverbose "they are ($i) $u_libs"
return 0
else
# logverbose "old--- $old_libs --- new +++ $i +++"
fi
u_libs="`find_progs_helper $ldir $i`"
old_libs="$i"
tmp="$tmp $u_libs"
done
log "WARNING: Too many passes, giving up"
}
# prints to stdout files and libs in the search paths
find_progs_helper() { # first arg is either -P or -L
local ty=$1 dir=$2 ; shift; shift
local progs="`echo $* | tr ' ' '\n' | sort -u | tr '\n' ' '`"
# first, extract absolute pathnames or files in this directory
# accumulate others in $names
local names=""
local i
for i in $progs ; do
[ -f "$i" ] && echo `realpath $i` && continue
names="${names} $i"
done
# if nothing left, we are done
[ -z "${names}" ] && return 0
local depth p
local places="" # places to search
if [ x-P = "x$ty" ] ; then # search programs
depth=2
p=". local/bin local/sbin local/libexec \
bin sbin usr/bin usr/sbin libexec gnu/usr.bin \
secure/usr.bin secure/usr.sbin secure/libexec "
else
depth=3
p="lib usr/lib gnu/lib secure/lib"
fi
for i in $p ; do
i="${dir}/${i}"
[ -d "${i}" ] && places="${places} `realpath ${i}`"
done
# logverbose "--- looking into $places"
places=`echo ${places} | tr ' ' '\n' | sort -u`
for i in $names ; do
find ${places} -maxdepth $depth -type f -name ${i} | head -1
done
}
# Populate the memory filesystem with binaries and non-variable
# configuration files.
# First do an mtree pass, then create directory links and device entries,
# then run crunchgen etc. to build the binary and create links.
# Then copy the specific/generic mfs_tree.
# Finally, if required, make a copy of the floppy.tree onto /fd
populate_mfs_tree() {
local i j a dst MFS_TREE
log "populate_mfs_tree()"
dst=${BUILDDIR}/mfs.tree
rm -rf ${dst} || true # clean relics from old compilations.
mkdir ${dst} # create a fresh tree
log "pwd=`pwd`, Populating MFS tree..."
# use type-specific mfs.mtree, default to generic one.
a=${MY_TREE}/mfs.mtree
[ -f ${a} ] || a=${PICO_TREE}/build/mfs.mtree
log "Running mtree using $a..."
mtree -deU -f $a -p ${dst} > /dev/null || fail $? mtree
# Create symlinks using relative pathnames, so it is possible
# to follow them also when building the image.
# Note that names in STAND_LINKS should not have a leading /
for i in ${STAND_LINKS}; do
j=`echo $i | sed -E 's:^[^/]+::;s:/[^/]+:../:g'`
ln -s ${j}stand ${dst}/$i
done
ln -s ../../dev/null ${dst}/var/run/log
ln -s ../../../etc/termcap ${dst}/usr/share/misc/termcap
### now build the crunched binaries ###
(
cd ${BUILDDIR}/crunch
log "Making and installing crunch1 from `pwd` src ${SRC}..."
a=${BUILDDIR}/crunch1.conf
( export BUILDDIR SRC MY_TREE PICO_OBJ ;
${BINMAKE} \
-f ${PICO_TREE}/build/Makefile.conf ${BUILDDIR}/crunch.mk )
log "Libs are ${LIBS} "
export SRC # used by crunch.mk
# export LIBS CFLAGS
log "Now make -f crunch.mk"
${BINMAKE} ${o_makeopts} -f ${BUILDDIR}/crunch.mk
strip --remove-section=.note --remove-section=.comment crunch1
mv crunch1 ${dst}/stand/crunch
chmod 555 ${dst}/stand/crunch
log "Making links for binaries..."
for i in `crunchgen -l $a` ; do
ln ${dst}/stand/crunch ${dst}/stand/${i};
done
# rm $a # do not remove!
) || fail $? crunch
log "Setting up host key for sshd:"
for K in rsa dsa ; do
if [ $K = rsa1 ] ; then
i=ssh_host_key
else
i=ssh_host_${K}_key
fi
if [ -f ${BUILDDIR}/floppy.tree/etc/$i.gz ] ; then
log "Using existing host key $i"
else
log "Generating new host key $i"
ssh-keygen -t $K -f ${BUILDDIR}/floppy.tree/etc/$i \
-N "" -C "root@picobsd"
gzip -9 ${BUILDDIR}/floppy.tree/etc/${i}* || true
fi
done
log "Copy generic and site-specific MFS tree..."
for MFS_TREE in ${PICO_TREE}/mfs_tree ${MY_TREE}/mfs_tree ; do
if [ -d ${MFS_TREE} ] ; then
log "Copy ${MFS_TREE} ..."
(cd ${MFS_TREE} ; tar -cf - --exclude .svn . ) | \
(cd ${dst} ; tar x${o_tarv}f - )
fi
done
if [ -f ${MY_TREE}/buildtree.mk ] ; then
log "building local floppy tree"
${BINMAKE} -C ${dst} -f ${MY_TREE}/buildtree.mk mfs.tree
fi
if [ "${o_all_in_mfs}" = "yes" ]; then
log "Copy generic floppy_tree into MFS..."
# ignore failure in case the floppy is empty
cp -Rp ${BUILDDIR}/floppy.tree/* ${dst}/fd || true
fi
# 4.x compatibility - create device nodes
if [ -n "${o_no_devfs}" ] ; then
# create device entries using MAKEDEV
(cd ${dst}/dev
ln -s ${SRC}/etc/MAKEDEV ; chmod 555 MAKEDEV
# log `pwd`
sh ./MAKEDEV ${MY_DEVS}
rm MAKEDEV
)
fi
if [ "`id -u`" = "0" ] ; then
log "Fixing permissions"
(cd ${dst}; chown -R root . )
fi
log "for a shared 'crunch' take libraries and dynamic loader as well"
# /stand/crunch is our main binary, we extract its libs
find_progs ${dst}/stand/crunch
if [ -n "${u_libs}" ] ; then
mkdir -p ${dst}/lib && (cp -p ${u_libs} ${dst}/lib || log "copy libs ${u_libs} failed" )
mkdir -p ${dst}/libexec
create_includes_and_libraries2 libexec/rtld-elf
find_progs ld-elf.so.1 && ( cp -p ${u_progs} ${dst}/libexec || log "copy ${u_progs} failed" )
fi
[ -n "${copy_files}" ] && do_copyfiles ${dst} copy_files
do_copyfiles_user ${dst} || true
[ -n "${links}" ] && do_links ${dst} links
strip ${dst}/libexec/* ${dst}/lib/* 2> /dev/null || true
# strip ${dst}/stand/* 2> /dev/null || true
# The 'import_files' mechanism is deprecated, as it requires
# root permissions to follow the symlinks, and also does
# not let you rename the entries.
if [ -n "${import_files}" ] ; then
log "importing ${import_files} into mfs"
# We do it in a chroot environment on the target so
# symlinks are followed correctly.
# Make sure we have a statically linked tar there.
mkdir -p ${dst}/rescue
cp /rescue/tar ${dst}/rescue
(cd ${l_usrtree}/.. ; tar cf - ${import_files} ) | \
(chroot ${dst} /rescue/tar xPf - )
rm -rf ${dst}/rescue
fi
# final step -- build the mfs image
(cd ${BUILDDIR}
# override the owner
echo "/set uid=0 gid=0" > mtree.out
mtree -ic -p ${dst} -k "" >> mtree.out
log "mtree.out at ${BUILDDIR}/mtree.out size ${MFS_SIZE}k"
makefs -t ffs -o bsize=4096 -o fsize=512 \
-s ${MFS_SIZE}k -f 1000 -F mtree.out ${c_fs} ${dst}
ls -l ${c_fs} )
log "done mfs image"
}
final_cleanup() {
log "final_cleanup()"
rm -rf ${c_mnt} ${c_reply} 2> /dev/null || true
}
# fail errno errcode
# This function is used to trap errors and print msgs
#
fail() {
local errno errocode where
errno=$1
errcode=$2
where=$3
echo "---> fail: Error <${errno}> error code <${errcode}> in <${where}>"
case ${errcode} in
mtree)
echo "Error while making hierarchy in ${c_mnt}"
;;
crunch)
echo "Error while building ${name}."
;;
missing_kernel)
echo "Error: you must build PICOBSD${suffix} kernel first"
;;
includes)
echo "Error: failed while making includes"
;;
libraries)
echo "Error: failed while making libraries"
;;
bad_type)
echo "Error: unknown floppy type ${name}"
;;
no_space)
echo "Error: no space left on device (${where})"
;;
no_mfs)
echo "Error: while writing MFS into the kernel."
;;
"")
echo "User break"
errcode="userbreak"
;;
*)
echo "unknown error, maybe user break: $errno $errcode"
;;
esac
echo "---> Aborting $0"
# try to cleanup the vnode.
final_cleanup
exit 2
}
fill_floppy_image() {
local blocks dst mfs_start mfs_end mfs_size img_size
log "fill_floppy_image()"
dst=${c_mnt} # where to create the image
log "Preparing ${fd_size}kB floppy filesystem..."
# correct blocks according to size.
blocks=${fd_size};
if [ "${blocks}" = "1720" ]; then
blocks=1722
elif [ "${blocks}" = "1480" ]; then
blocks=1476
fi
log "Labeling floppy image"
dst=${BUILDDIR}/image.tree
rm -rf ${dst}
mkdir -p ${dst}
(
cd ${BUILDDIR}
# old style mfs lookup, find markers in kernel
set 0 0 # reset variables
# $1 takes the offset of the MFS filesystem
set `strings -at d kernel | grep "MFS Filesystem goes here"`
mfs_start=$1
set 0 0 # reset variables
set `strings -at d kernel | grep "MFS Filesystem had better"`
mfs_end=$1
mfs_size="$((${mfs_end} - ${mfs_start}))"
if [ ${mfs_start} = 0 -o ${mfs_end} = 0 ] ; then
# similar to sys/tools/embed_mfs.sh
local x="`objdump -h kernel | grep oldmfs`"
mfs_size=`echo ${x} | awk '{printf("%d", "0x" $3)}' 2> /dev/null`
mfs_start=`echo ${x} | awk '{printf("%d", "0x" $6)}' 2> /dev/null`
if [ ${mfs_start} = 0 -o ${mfs_size} = 0 ] ; then
log "-- old style mfs location not found, have"
logverbose "$x"
fi
fi
set -- `ls -l ${c_fs}`; imgsize="$5"
if [ ${mfs_start} -gt 0 -a ${mfs_size} -ge ${imgsize} ] ; then
mfs_ofs=$((${mfs_start} + 8192))
log "Preload kernel with file ${c_fs} at ${mfs_ofs}"
log "`ls -l ${c_fs}` to fit in ${mfs_size}"
dd if=${c_fs} ibs=8192 iseek=1 of=kernel obs=${mfs_ofs} \
oseek=1 conv=notrunc # 2> /dev/null
else
log "not loading mfs, size ${mfs_size} img ${imgsize}"
fi
log "Compress with gzip and copy to floppy image"
mkdir -p ${dst}/boot/kernel
# XXX loader.conf does not work unless we also load the .4th files
# echo "hint.acpi.0.disabled=\"1\"" > ${dst}/boot/loader.conf
# echo "console=\"comconsole\"" >> ${dst}/boot/loader.conf
local blf="loader* *.4th" # loader.rc loader.4th support.4th"
(cd /boot; cp -p loader ${dst}/boot) || fail $? no_space "copying bootloader"
cp ${MY_TREE}/floppy.tree/boot/loader.conf ${dst}/boot || true
gzip -c kernel > ${dst}/boot/kernel/kernel.gz || fail $? no_space "copying kernel"
# now transfer the floppy tree. If it is already in mfs, dont bother.
if [ "${o_all_in_mfs}" != "yes" ] ; then
log "Now transfer floppy tree if not already in MFS image"
cp -Rp floppy.tree/* ${dst} || \
fail $? no_space "copying floppy tree"
fi
)
# add local manipulation to the image
if [ -f ${MY_TREE}/buildtree.mk ] ; then
${BINMAKE} -C ${dst} -f ${MY_TREE}/buildtree.mk image.tree
fi
log "image used `du -s ${dst}` of ${blocks}k"
if [ "${generate_iso}" = "YES" ]; then
logverbose "generate_iso ${generate_iso}"
# build_iso_image # XXX not implemented yet
(cd ${BUILDDIR}
cp -p /boot/cdboot ${dst}/boot || fail $? no_space "copying cdboot"
mkisofs -b boot/cdboot -no-emul-boot -J -r -ldots -l -L \
-o ${c_iso} ${dst}
)
fi
(cd ${BUILDDIR}
makefs -t ffs -o bsize=4096 -o fsize=512 \
-s ${blocks}k -f 50 ${c_img} ${dst}
${c_label} -w -f `pwd`/${c_img} auto # write in a label
# copy partition c: into a: with some sed magic
${c_label} -f `pwd`/${c_img} | sed -e '/ c:/{p;s/c:/a:/;}' | \
${c_label} -R -f `pwd`/${c_img} /dev/stdin
${c_label} -f `pwd`/${c_img}
ls -l ${c_img}
${c_label} -f `pwd`/${c_img}
log "after disklabel"
)
echo "BUILDDIR ${BUILDDIR}"
# dump the primary and secondary boot
# XXX primary is 512 bytes
dd if=${c_boot1} of=${BUILDDIR}/${c_img} conv=notrunc 2>/dev/null
# XXX secondary starts after the 0x114 = dec 276 bytes of the label
# so we skip 276 from the source, and 276+512=788 from dst
# the old style blocks used 512 and 1024 respectively
dd if=${c_boot2} iseek=1 ibs=276 2> /dev/null | \
dd of=${BUILDDIR}/${c_img} oseek=1 obs=788 conv=notrunc 2>/dev/null
log "done disk image"
# XXX (log "Fixing permissions"; cd ${dst}; chown -R root *)
df -ik ${dst} | colrm 70 > .build.reply
# leave build stuff if verbose
[ ${o_verbose} -gt 0 ] && return
rm -rf ${BUILDDIR}/floppy.tree || true # cleanup
rm -rf ${dst}
rm ${BUILDDIR}/${c_fs}
# rm ${BUILDDIR}/kernel.gz
}
# This function creates variables which depend on the source tree in use:
# SRC, l_usrtree, l_objtree
# Optionally creates libraries, includes and the like (for cross compiles,
# needs to be done once).
set_build_parameters() {
if [ "${SRC}" = "/usr/src" ] ; then
l_usrtree=${USR:-/usr}
else
l_usrtree=${USR:-${SRC}/../usr}
fi
l_objtree=${l_usrtree}/obj-pico-${o_arch}
PICO_TREE=${PICO_TREE:-${SRC}/release/picobsd}
set `grep "#define[\t ]__FreeBSD_version" ${SRC}/sys/sys/param.h`
OSVERSION=$3
log "OSVERSION is ${OSVERSION}"
export MAKEOBJDIRPREFIX=${l_objtree}
export TARGET_ARCH=${o_arch} TARGET=${o_arch}
# XXX 20131001 see if CLANG fixes the build
if true; then
echo "--- build with clang"
export WITHOUT_CLANG=yes
export WITHOUT_CLANG_BOOTSTRAP=yes
# export WITH_CLANG_BOOTSTRAP=yes
else
export WITHOUT_CLANG_IS_CC=yes
export WITHOUT_CLANG_BOOTSTRAP=yes
export WITH_GCC=yes
export WITH_GCC_BOOTSTRAP=yes
export WITH_GNUCXX=yes
export WITHOUT_CLANG=yes
export WITHOUT_ICONV=yes
export WITHOUT_TESTS=yes
fi
# XXX why change machine_arch ?
#-- export MACHINE_ARCH=`uname -m` MACHINE=`uname -m`
# export CWARNFLAGS="-Wextra -Wno-sign-compare -Wno-missing-field-initializers"
# XXX BINMAKE does not really exist anymore
eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V BINMAKE`\""
[ "$BINMAKE" = "" ] && \
eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V SUB_MAKE`\""
if [ "${o_init_src}" != "" ] ; then
create_includes_and_libraries2
else
eval export `cd ${SRC}; ${BINMAKE} -f Makefile.inc1 -V WMAKEENV`
fi
# if we have o_objdir, find where bin/ is
if [ ! -z "${o_objdir}" ] ; then
if [ -d ${o_objdir}/bin ] ; then
# fine
elif [ -d "${o_objdir}${SRC}/bin" ] ; then
o_objdir="${o_objdir}${SRC}"
log "Changing objdir to ${o_objdir}"
else
log "Cannot find objdir in ${o_objdir}, sorry"
o_objdir=""
fi
fi
}
#-------------------------------------------------------------------
# Main entry of the script. Initialize variables, parse command line
# arguments.
set_defaults
while [ true ]; do
log "Parsing $1"
case $1 in
-j)
o_par="-j $2"
shift
;;
--par)
o_par="-j 8" # watch out, this might be too large
;;
--src) # set the source path instead of /usr/src
SRC=`realpath $2`
shift
;;
--init) # run a partial buildworld on the source tree
o_init_src="YES"
;;
--arch) # override the target architecture
o_arch=$2
shift
;;
--floppy_size) # image size
fd_size=$2
shift
;;
--all_in_mfs)
o_all_in_mfs="yes"
;;
--no_all_in_mfs)
o_all_in_mfs="no"
;;
--modules) # also build kernel modules
o_do_modules="yes"
;;
-n)
o_interactive="NO"
;;
-clear|-clean|-c) # clean
o_clean="YES"
o_interactive="NO"
;;
-v) # need -v -v to wait for user input
o_verbose=$((${o_verbose}+1)) # verbose level
o_tarv="v" # tar verbose flag
o_makeopts="-d l" # be verbose
;;
--iso) # generate iso image
generate_iso="YES"
;;
--cfg) # read additional config from this file
o_additional_config=`realpath $2`
shift
;;
--objdir) # Place with results of a previous buildworld
# useful if you want to copy shared binaries and libs
o_objdir=`realpath $2`
shift
;;
*)
break
;;
esac
shift
done
set_build_parameters # things that depend on ${SRC}
set_type $1 $2 # type and site, respectively
[ "${o_interactive}" != "NO" ] && main_dialog
if [ "${o_clean}" = "YES" ] ; then
clean_tree
else
build_image
do_install
fi
final_cleanup
exit 0