#!/bin/sh # $NetBSD: mkimage,v 1.69.6.1 2019/11/17 07:04:36 martin Exp $ # # Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation # by Christos Zoulas. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of The NetBSD Foundation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # # Makes a bootable image for the host architecture given. # The host specific functions are pulled in from a /bin/sh script in the # "conf" directory, and is expected to provide the following shell # functions, which are called in the following order: # # - make_fstab: Creates the host's /etc/fstab with / on ${rootdev}. # If -m is given, a number of directories are put on a tmpfs RAM disk # - customize: After unpacking the sets, this gets the system to # a working state, e. g. by setting up /etc/rc.conf and /dev # - populate: Add common goods like kernel and bootloader # - make_label: Prints disklabel to stdout # set -e DIR="$(cd "$(dirname "$0")" && pwd)" PROG="$(basename "$0")" MAKE=${TOOL_MAKE:-make} DISKLABEL=${TOOL_DISKLABEL:-disklabel} FDISK=${TOOL_FDISK:-fdisk} MAKEFS=${TOOL_MAKEFS:-makefs} MTREE=${TOOL_MTREE:-mtree} INSTALLBOOT=${TOOL_INSTALLBOOT:-installboot} MKUBOOTIMAGE=${TOOL_MKUBOOTIMAGE:-mkubootimage} GZIP_CMD=${TOOL_GZIP:-gzip} # ${GZIP} is special to gzip(1) src="/usr/src" sets="base comp etc games man misc modules rescue tests text" xsets="xbase xcomp xetc xfont xserver" minfree="10%" bar="===" tmp="$(mktemp -d "${TMPDIR:-/tmp}/$PROG.XXXXXX")" mnt="${tmp}/mnt" mkdir -p "${mnt}/etc" "${mnt}/dev" trap "cleanup" 0 1 2 3 15 cleanup() { case "$tmp" in "${TMPDIR:-/tmp}/$PROG."*) rm -fr "$tmp";; esac } fail() { IFS=' ' echo >&2 "${PROG}: $*" exit 1 } getsize() { set -- $(ls -l $1) echo $5 } getsectors() { case "$1" in *g) m=1073741824 v=${1%g} ;; *m) m=1048576 v=${1%m} ;; *k) m=1024 v=${1%k} ;; *[0-9b]) m=1 v=${1%b} ;; esac echo $((m * v / 512)) } usage() { cat << EOF 1>&2 Usage: $PROG -h [-bdmx] [-B ] [-K ] [-S ] [-D ] [-c ] [-s ] [] -b Boot only, no sets loaded -r root device kind (sd, wd, ld) -d Add the debug sets -m Optimize the OS installation to mimimize disk writes for SSDs -x Load the X sets too, not just the base ones EOF exit 1 } # First pass for options to get the host and src directories OPTS="B:D:K:S:bc:dh:mr:s:x" while getopts "$OPTS" f do case $f in h) h="$OPTARG";; S) src="$OPTARG";; *) ;; esac done if [ -z "$h" ] then usage fi if [ ! -f "${DIR}/conf/${h}.conf" ] then echo $PROG: ${DIR}/conf/${h}.conf is not present 1>&2 exit 1 fi resize=false . "${DIR}/conf/${h}.conf" release="/usr/obj/${MACHINE}/release" selected_sets="$sets" dsets_p=false xsets_p=false minwrites=false rootdev=ld endian= OPTIND=1 while getopts "$OPTS" f do case $f in B) endian="-B $OPTARG";; D) release="$OPTARG";; K) kernel="$OPTARG";; S) ;; b) bootonly=true;; d) dsets_p=true selected_sets="$selected_sets debug" if $xsets_p; then selected_sets="$selected_sets xdebug" fi ;; c) custom="$OPTARG";; h) ;; m) minwrites=true;; r) rootdev="$OPTARG";; s) size="$OPTARG";; x) xsets_p=true selected_sets="$selected_sets $xsets" if $dsets_p; then selected_sets="$selected_sets xdebug" fi ;; *) usage;; esac done shift $(( $OPTIND - 1 )) if [ -n "$1" ]; then # take the next argument as being the image name image="$1" shift fi case "$image" in *.gz) compress=true; image="${image%.gz}";; *) compress=false;; esac if [ -z "${bootonly}" ]; then echo ${bar} configuring sets ${bar} (cat "${release}/etc/mtree/NetBSD.dist" for i in $selected_sets; do s="${release}/etc/mtree/set.$i" if [ -f "$s" ]; then cat "$s" fi done) > "$tmp/selected_sets" fi make_fstab customize populate if [ -n "${msdosid}" ]; then echo ${bar} Populating msdos filesystem ${bar} ${MAKEFS} -N ${release}/etc -t msdos -o volume_label=NETBSD \ -O $((${init} / 2))m -s $((${boot} / 2))m \ ${image} ${mnt}/boot fi if [ -z "${bootonly}" ]; then echo ${bar} Populating ffs filesystem ${bar} ${MAKEFS} -rx ${endian} -N ${release}/etc -t ffs \ -O ${ffsoffset} \ -o d=4096,f=8192,b=65536 -b $((${extra}))m \ -F "$tmp/selected_sets" ${image} "${release}" "${mnt}" fi if [ "${size}" = 0 ]; then size="$(getsize "${image}")" fi newsize=$((${size} / 2 / 1024)) compare=$((${newsize} * 2 * 1024)) while [ "${compare}" != "${size}" ] do size="$((size + size - compare))" newsize="$((${size} / 2 / 1024))" compare="$((${newsize} * 2 * 1024))" done if [ -n "${msdosid}" ]; then echo ${bar} Running fdisk ${bar} initsecs=$((${init} * 1024)) bootsecs=$((${boot} * 1024)) ${FDISK} -f -i ${image} ${FDISK} -f -a -u -0 -s ${msdosid}/${initsecs}/${bootsecs} -F ${image} if [ -z "${bootonly}" ]; then ffsstart="$(getsectors ${ffsoffset})" imagesize="$(getsize "${image}")" imagesecs="$(getsectors ${imagesize})" ffssize="$(expr ${imagesecs} - ${ffsstart})" ${FDISK} -f -u -1 -s 169/${ffsstart}/${ffssize} -F ${image} fi echo ${bar} Adding label ${bar} make_label > ${tmp}/label ${DISKLABEL} -R -F ${image} ${tmp}/label elif [ -n "${netbsdid}" ]; then echo ${bar} Adding label ${bar} make_label > ${tmp}/label ${DISKLABEL} -R -F ${image} ${tmp}/label echo ${bar} Running fdisk ${bar} ${FDISK} -f -i ${image} ${FDISK} -f -a -u -0 -s 169/${init} ${image} ${INSTALLBOOT} -f -v ${image} ${release}/usr/mdec/bootxx_ffsv1 fi if $compress; then echo ${bar} Compressing image ${bar} rm -f "${image}.gz" ${GZIP_CMD} -9 ${image} image="${image}.gz" fi echo ${bar} Image is ${image} ${bar}