mkimage revision 1.75
11.31Sjmcneill#!/bin/sh 21.75Sjmcneill# $NetBSD: mkimage,v 1.75 2020/07/17 15:16:34 jmcneill Exp $ 31.13Schristos# 41.45Schristos# Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. 51.1Sagc# All rights reserved. 61.1Sagc# 71.17Schristos# This code is derived from software contributed to The NetBSD Foundation 81.17Schristos# by Christos Zoulas. 91.17Schristos# 101.1Sagc# Redistribution and use in source and binary forms, with or without 111.1Sagc# modification, are permitted provided that the following conditions 121.1Sagc# are met: 131.1Sagc# 1. Redistributions of source code must retain the above copyright 141.1Sagc# notice, this list of conditions and the following disclaimer. 151.1Sagc# 2. Redistributions in binary form must reproduce the above copyright 161.1Sagc# notice, this list of conditions and the following disclaimer in the 171.1Sagc# documentation and/or other materials provided with the distribution. 181.17Schristos# 3. Neither the name of The NetBSD Foundation nor the names of its 191.17Schristos# contributors may be used to endorse or promote products derived 201.17Schristos# from this software without specific prior written permission. 211.17Schristos# 221.17Schristos# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 231.17Schristos# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 241.17Schristos# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 251.17Schristos# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 261.17Schristos# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 271.17Schristos# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 281.17Schristos# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 291.17Schristos# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 301.17Schristos# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 311.17Schristos# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 321.17Schristos# POSSIBILITY OF SUCH DAMAGE. 331.1Sagc# 341.1Sagc 351.58Shubertf# 361.58Shubertf# Makes a bootable image for the host architecture given. 371.58Shubertf# The host specific functions are pulled in from a /bin/sh script in the 381.58Shubertf# "conf" directory, and is expected to provide the following shell 391.58Shubertf# functions, which are called in the following order: 401.58Shubertf# 411.58Shubertf# - make_fstab: Creates the host's /etc/fstab with / on ${rootdev}. 421.58Shubertf# If -m is given, a number of directories are put on a tmpfs RAM disk 431.58Shubertf# - customize: After unpacking the sets, this gets the system to 441.58Shubertf# a working state, e. g. by setting up /etc/rc.conf and /dev 451.58Shubertf# - populate: Add common goods like kernel and bootloader 461.58Shubertf# - make_label: Prints disklabel to stdout 471.58Shubertf# 481.58Shubertf 491.33Sjmcneillset -e 501.33Sjmcneill 511.17SchristosDIR="$(cd "$(dirname "$0")" && pwd)" 521.17SchristosPROG="$(basename "$0")" 531.17Schristos 541.66SjmcneillMAKE=${TOOL_MAKE:-make} 551.21SchristosDISKLABEL=${TOOL_DISKLABEL:-disklabel} 561.24SchristosFDISK=${TOOL_FDISK:-fdisk} 571.73SjmcneillGPT=${TOOL_GPT:-gpt} 581.21SchristosMAKEFS=${TOOL_MAKEFS:-makefs} 591.25SjmcneillMTREE=${TOOL_MTREE:-mtree} 601.45SchristosINSTALLBOOT=${TOOL_INSTALLBOOT:-installboot} 611.59SchristosMKUBOOTIMAGE=${TOOL_MKUBOOTIMAGE:-mkubootimage} 621.44SastGZIP_CMD=${TOOL_GZIP:-gzip} # ${GZIP} is special to gzip(1) 631.21Schristos 641.17Schristossrc="/usr/src" 651.70Smayasets="base comp etc games man misc modules rescue tests text" 661.17Schristosxsets="xbase xcomp xetc xfont xserver" 671.17Schristosminfree="10%" 681.17Schristosbar="===" 691.17Schristos 701.67Skretmp="$(mktemp -d "${TMPDIR:-/tmp}/$PROG.XXXXXX")" 711.17Schristosmnt="${tmp}/mnt" 721.46Schristosmkdir -p "${mnt}/etc" "${mnt}/dev" 731.23Schristos 741.17Schristostrap "cleanup" 0 1 2 3 15 751.17Schristos 761.17Schristoscleanup() { 771.17Schristos case "$tmp" in 781.68Skre "${TMPDIR:-/tmp}/$PROG."*) rm -fr "$tmp";; 791.17Schristos esac 801.17Schristos} 811.1Sagc 821.69Skrefail() { 831.69Skre IFS=' ' 841.69Skre echo >&2 "${PROG}: $*" 851.69Skre exit 1 861.69Skre} 871.69Skre 881.17Schristosgetsize() { 891.17Schristos set -- $(ls -l $1) 901.17Schristos echo $5 911.1Sagc} 921.1Sagc 931.63Sjmcneillgetsectors() { 941.63Sjmcneill case "$1" in 951.63Sjmcneill *g) 961.63Sjmcneill m=1073741824 971.63Sjmcneill v=${1%g} 981.63Sjmcneill ;; 991.63Sjmcneill *m) 1001.63Sjmcneill m=1048576 1011.63Sjmcneill v=${1%m} 1021.63Sjmcneill ;; 1031.63Sjmcneill *k) 1041.63Sjmcneill m=1024 1051.63Sjmcneill v=${1%k} 1061.63Sjmcneill ;; 1071.63Sjmcneill *[0-9b]) 1081.63Sjmcneill m=1 1091.63Sjmcneill v=${1%b} 1101.63Sjmcneill ;; 1111.63Sjmcneill esac 1121.63Sjmcneill echo $((m * v / 512)) 1131.63Sjmcneill} 1141.63Sjmcneill 1151.12Schristosusage() { 1161.12Schristos cat << EOF 1>&2 1171.60SmartinUsage: $PROG -h <host-arch> [-bdmx] [-B <byte-order>] [-K <kerneldir>] [-S <srcdir>] [-D <destdir>] [-c <custom-files-dir>] [-s <Mb size>] [<image>] 1181.39Schristos 1191.39Schristos-b Boot only, no sets loaded 1201.47Schristos-r root device kind (sd, wd, ld) 1211.39Schristos-d Add the debug sets 1221.43Schristos-m Optimize the OS installation to mimimize disk writes for SSDs 1231.57Shubertf-x Load the X sets too, not just the base ones 1241.12SchristosEOF 1251.13Schristos exit 1 1261.12Schristos} 1271.12Schristos 1281.32Sjmcneill# First pass for options to get the host and src directories 1291.60SmartinOPTS="B:D:K:S:bc:dh:mr:s:x" 1301.4Schristoswhile getopts "$OPTS" f 1311.4Schristosdo 1321.4Schristos case $f in 1331.4Schristos h) h="$OPTARG";; 1341.32Sjmcneill S) src="$OPTARG";; 1351.4Schristos *) ;; 1361.4Schristos esac 1371.4Schristosdone 1381.4Schristos 1391.4Schristosif [ -z "$h" ] 1401.4Schristosthen 1411.4Schristos usage 1421.4Schristosfi 1431.4Schristos 1441.5Schristosif [ ! -f "${DIR}/conf/${h}.conf" ] 1451.4Schristosthen 1461.5Schristos echo $PROG: ${DIR}/conf/${h}.conf is not present 1>&2 1471.4Schristos exit 1 1481.4Schristosfi 1491.4Schristos 1501.56Sjmcneillresize=false 1511.73Sjmcneillgpt=false 1521.74Sjmcneillgpt_hybrid=false 1531.56Sjmcneill 1541.5Schristos. "${DIR}/conf/${h}.conf" 1551.45Schristosrelease="/usr/obj/${MACHINE}/release" 1561.4Schristos 1571.17Schristosselected_sets="$sets" 1581.50Sskrlldsets_p=false 1591.50Sskrllxsets_p=false 1601.39Schristosminwrites=false 1611.47Schristosrootdev=ld 1621.60Smartinendian= 1631.17Schristos 1641.4SchristosOPTIND=1 1651.4Schristoswhile getopts "$OPTS" f 1661.4Schristosdo 1671.4Schristos case $f in 1681.60Smartin B) endian="-B $OPTARG";; 1691.18Schristos D) release="$OPTARG";; 1701.18Schristos K) kernel="$OPTARG";; 1711.32Sjmcneill S) ;; 1721.41Schristos b) bootonly=true;; 1731.50Sskrll d) dsets_p=true 1741.39Schristos selected_sets="$selected_sets debug" 1751.50Sskrll if $xsets_p; then 1761.39Schristos selected_sets="$selected_sets xdebug" 1771.39Schristos fi 1781.39Schristos ;; 1791.4Schristos c) custom="$OPTARG";; 1801.4Schristos h) ;; 1811.39Schristos m) minwrites=true;; 1821.47Schristos r) rootdev="$OPTARG";; 1831.4Schristos s) size="$OPTARG";; 1841.50Sskrll x) xsets_p=true 1851.39Schristos selected_sets="$selected_sets $xsets" 1861.50Sskrll if $dsets_p; then 1871.39Schristos selected_sets="$selected_sets xdebug" 1881.39Schristos fi 1891.39Schristos ;; 1901.6Schristos *) usage;; 1911.1Sagc esac 1921.1Sagcdone 1931.1Sagc 1941.20Sjmcneillshift $(( $OPTIND - 1 )) 1951.4Schristosif [ -n "$1" ]; then 1961.1Sagc # take the next argument as being the image name 1971.1Sagc image="$1" 1981.1Sagc shift 1991.1Sagcfi 2001.1Sagc 2011.22Schristoscase "$image" in 2021.22Schristos*.gz) compress=true; image="${image%.gz}";; 2031.22Schristos*) compress=false;; 2041.22Schristosesac 2051.22Schristos 2061.45Schristosif [ -z "${bootonly}" ]; then 2071.36Sgarbled echo ${bar} configuring sets ${bar} 2081.51Sskrll (cat "${release}/etc/mtree/NetBSD.dist" 2091.36Sgarbled for i in $selected_sets; do 2101.36Sgarbled s="${release}/etc/mtree/set.$i" 2111.36Sgarbled if [ -f "$s" ]; then 2121.36Sgarbled cat "$s" 2131.36Sgarbled fi 2141.36Sgarbled done) > "$tmp/selected_sets" 2151.36Sgarbledfi 2161.1Sagc 2171.4Schristosmake_fstab 2181.17Schristoscustomize 2191.17Schristospopulate 2201.1Sagc 2211.72Sjmcneillif [ ! "${MKDTB}" = "no" ]; then 2221.72Sjmcneill # 2231.72Sjmcneill # Part of the dtb set resides on the FAT partition (/boot/dtb/*), and 2241.72Sjmcneill # the rest on FFS. Split it up here. 2251.72Sjmcneill # 2261.72Sjmcneill echo ${bar} Installing devicetree blobs ${bar} 2271.72Sjmcneill mkdir -p "${mnt}/boot" 2281.72Sjmcneill cp -r "${release}/boot/dtb" "${mnt}/boot/dtb" 2291.72Sjmcneill 2301.72Sjmcneill mkdir -p "${mnt}/etc/mtree" 2311.72Sjmcneill cp "${release}/etc/mtree/set.dtb" "${mnt}/etc/mtree/set.dtb" 2321.72Sjmcneill echo "./etc/mtree/set.dtb type=file uname=root gname=wheel mode=0444" >> "$tmp/selected_sets" 2331.72Sjmcneill 2341.72Sjmcneill mkdir -p "${mnt}/var/db/obsolete" 2351.72Sjmcneill cp "${release}/var/db/obsolete/dtb" "${mnt}/var/db/obsolete/dtb" 2361.72Sjmcneill echo "./var/db/obsolete/dtb type=file uname=root gname=wheel mode=0644" >>"$tmp/selected_sets" 2371.72Sjmcneillfi 2381.72Sjmcneill 2391.45Schristosif [ -n "${msdosid}" ]; then 2401.17Schristos echo ${bar} Populating msdos filesystem ${bar} 2411.72Sjmcneill 2421.71Smartin case $(( ${msdosid} )) in 2431.71Smartin 1) fat_opt=",fat_type=12";; 2441.71Smartin 4|6|14) fat_opt=",fat_type=16";; 2451.71Smartin 11|12) fat_opt=",fat_type=32";; 2461.71Smartin *) fat_opt=;; 2471.71Smartin esac 2481.71Smartin ${MAKEFS} -N ${release}/etc -t msdos \ 2491.71Smartin -o "volume_label=NETBSD${fat_opt}" \ 2501.63Sjmcneill -O $((${init} / 2))m -s $((${boot} / 2))m \ 2511.41Schristos ${image} ${mnt}/boot 2521.1Sagcfi 2531.1Sagc 2541.45Schristosif [ -z "${bootonly}" ]; then 2551.36Sgarbled echo ${bar} Populating ffs filesystem ${bar} 2561.60Smartin ${MAKEFS} -rx ${endian} -N ${release}/etc -t ffs \ 2571.46Schristos -O ${ffsoffset} \ 2581.61Sjmcneill -o d=4096,f=8192,b=65536 -b $((${extra}))m \ 2591.36Sgarbled -F "$tmp/selected_sets" ${image} "${release}" "${mnt}" 2601.36Sgarbledfi 2611.1Sagc 2621.23Schristosif [ "${size}" = 0 ]; then 2631.23Schristos size="$(getsize "${image}")" 2641.17Schristosfi 2651.23Schristosnewsize=$((${size} / 2 / 1024)) 2661.49Schristoscompare=$((${newsize} * 2 * 1024)) 2671.49Schristoswhile [ "${compare}" != "${size}" ] 2681.49Schristosdo 2691.49Schristos size="$((size + size - compare))" 2701.49Schristos newsize="$((${size} / 2 / 1024))" 2711.49Schristos compare="$((${newsize} * 2 * 1024))" 2721.49Schristosdone 2731.1Sagc 2741.73Sjmcneillif $gpt; then 2751.74Sjmcneill if $gpt_hybrid; then 2761.74Sjmcneill gpt_flags="-H" 2771.74Sjmcneill fi 2781.30Sjmcneill initsecs=$((${init} * 1024)) 2791.30Sjmcneill bootsecs=$((${boot} * 1024)) 2801.73Sjmcneill ffsstart="$(getsectors ${ffsoffset})" 2811.73Sjmcneill 2821.73Sjmcneill echo ${bar} Clearing existing partitions ${bar} 2831.74Sjmcneill ${GPT} ${gpt_flags} ${image} destroy || true 2841.73Sjmcneill 2851.73Sjmcneill echo ${bar} Creating partitions ${bar} 2861.74Sjmcneill ${GPT} ${gpt_flags} ${image} create ${gpt_create_flags} 2871.75Sjmcneill ${GPT} ${gpt_flags} ${image} add -b ${initsecs} -s ${bootsecs} -l ${gpt_label_boot:-EFI} -t ${gpt_boot_type:-efi} 2881.74Sjmcneill ${GPT} ${gpt_flags} ${image} set -a required -i 1 2891.74Sjmcneill ${GPT} ${gpt_flags} ${image} add -a 4m -b ${ffsstart} -l ${gpt_label_ffs:-netbsd-root} -t ffs 2901.74Sjmcneill ${GPT} ${gpt_flags} ${image} show 2911.74Sjmcneill if $gpt_hybrid; then 2921.74Sjmcneill echo ${bar} Creating hybrid MBR ${bar} 2931.74Sjmcneill ${FDISK} -f -g -u -0 -a -s ${msdosid}/${initsecs}/${bootsecs} -F ${image} 2941.74Sjmcneill ${FDISK} -f -g -u -3 -s 238/1/$((${initsecs} - 1)) -F ${image} 2951.74Sjmcneill ${FDISK} -F ${image} 2961.74Sjmcneill fi 2971.73Sjmcneillelse 2981.73Sjmcneill if [ -n "${msdosid}" ]; then 2991.73Sjmcneill echo ${bar} Running fdisk ${bar} 3001.73Sjmcneill initsecs=$((${init} * 1024)) 3011.73Sjmcneill bootsecs=$((${boot} * 1024)) 3021.73Sjmcneill ${FDISK} -f -i ${image} 3031.73Sjmcneill ${FDISK} -f -a -u -0 -s ${msdosid}/${initsecs}/${bootsecs} -F ${image} 3041.73Sjmcneill if [ -z "${bootonly}" ]; then 3051.73Sjmcneill ffsstart="$(getsectors ${ffsoffset})" 3061.73Sjmcneill imagesize="$(getsize "${image}")" 3071.73Sjmcneill imagesecs="$(getsectors ${imagesize})" 3081.73Sjmcneill ffssize="$(expr ${imagesecs} - ${ffsstart})" 3091.73Sjmcneill ${FDISK} -f -u -1 -s 169/${ffsstart}/${ffssize} -F ${image} 3101.73Sjmcneill fi 3111.73Sjmcneill 3121.73Sjmcneill echo ${bar} Adding label ${bar} 3131.73Sjmcneill make_label > ${tmp}/label 3141.73Sjmcneill ${DISKLABEL} -R -F ${image} ${tmp}/label 3151.73Sjmcneill elif [ -n "${netbsdid}" ]; then 3161.73Sjmcneill echo ${bar} Adding label ${bar} 3171.73Sjmcneill make_label > ${tmp}/label 3181.73Sjmcneill ${DISKLABEL} -R -F ${image} ${tmp}/label 3191.73Sjmcneill 3201.73Sjmcneill echo ${bar} Running fdisk ${bar} 3211.73Sjmcneill ${FDISK} -f -i ${image} 3221.73Sjmcneill ${FDISK} -f -a -u -0 -s 169/${init} ${image} 3231.73Sjmcneill ${INSTALLBOOT} -f -v ${image} ${release}/usr/mdec/bootxx_ffsv1 3241.63Sjmcneill fi 3251.2Sagcfi 3261.22Schristos 3271.22Schristosif $compress; then 3281.22Schristos echo ${bar} Compressing image ${bar} 3291.23Schristos rm -f "${image}.gz" 3301.44Sast ${GZIP_CMD} -9 ${image} 3311.22Schristos image="${image}.gz" 3321.22Schristosfi 3331.22Schristos 3341.17Schristosecho ${bar} Image is ${image} ${bar} 335