1#!/bin/sh 2# 3# Copyright (c) 2005 Poul-Henning Kamp All rights reserved. 4# Copyright (c) 2016 M. Warner Losh <imp@FreeBSD.org> 5# 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28# $FreeBSD$ 29# 30 31# Media geometry, only relevant if bios doesn't understand LBA. 32[ -n "$NANO_SECTS" ] || NANO_SECTS=63 33[ -n "$NANO_HEADS" ] || NANO_HEADS=16 34 35# Functions and variable definitions used by the legacy nanobsd 36# image building system. 37 38calculate_partitioning ( ) ( 39 echo $NANO_MEDIASIZE $NANO_IMAGES \ 40 $NANO_SECTS $NANO_HEADS \ 41 $NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE | 42 awk ' 43 { 44 # size of cylinder in sectors 45 cs = $3 * $4 46 47 # number of full cylinders on media 48 cyl = int ($1 / cs) 49 50 if ($7 > 0) { 51 # size of data partition in full cylinders 52 dsl = int (($7 + cs - 1) / cs) 53 } else { 54 dsl = 0; 55 } 56 57 # size of config partition in full cylinders 58 csl = int (($6 + cs - 1) / cs) 59 60 # size of image partition(s) in full cylinders 61 if ($5 == 0) { 62 isl = int ((cyl - dsl - csl) / $2) 63 } else { 64 isl = int (($5 + cs - 1) / cs) 65 } 66 67 # First image partition start at second track 68 print $3, isl * cs - $3 69 c = isl * cs; 70 71 # Second image partition (if any) also starts offset one 72 # track to keep them identical. 73 if ($2 > 1) { 74 print $3 + c, isl * cs - $3 75 c += isl * cs; 76 } 77 78 # Config partition starts at cylinder boundary. 79 print c, csl * cs 80 c += csl * cs 81 82 # Data partition (if any) starts at cylinder boundary. 83 if ($7 > 0) { 84 print c, dsl * cs 85 } else if ($7 < 0 && $1 > c) { 86 print c, $1 - c 87 } else if ($1 < c) { 88 print "Disk space overcommitted by", \ 89 c - $1, "sectors" > "/dev/stderr" 90 exit 2 91 } 92 93 } 94 ' > ${NANO_LOG}/_.partitioning 95) 96 97create_code_slice ( ) ( 98 pprint 2 "build code slice" 99 pprint 3 "log: ${NANO_OBJ}/_.cs" 100 101 ( 102 IMG=${NANO_DISKIMGDIR}/_.disk.image 103 MNT=${NANO_OBJ}/_.mnt 104 mkdir -p ${MNT} 105 CODE_SIZE=`head -n 1 ${NANO_LOG}/_.partitioning | awk '{ print $2 }'` 106 107 if [ "${NANO_MD_BACKING}" = "swap" ] ; then 108 MD=`mdconfig -a -t swap -s ${CODE_SIZE} -x ${NANO_SECTS} \ 109 -y ${NANO_HEADS}` 110 else 111 echo "Creating md backing file..." 112 rm -f ${IMG} 113 dd if=/dev/zero of=${IMG} seek=${CODE_SIZE} count=0 114 MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \ 115 -y ${NANO_HEADS}` 116 fi 117 118 trap "echo 'Running exit trap code' ; df -i ${MNT} ; umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT 119 120 bsdlabel -w ${MD} 121 if [ -f ${NANO_WORLDDIR}/boot/boot ]; then 122 echo "Making bootable partition" 123 gpart bootcode -b ${NANO_WORLDDIR}/boot/boot ${MD} 124 else 125 echo "Partition will not be bootable" 126 fi 127 bsdlabel ${MD} 128 129 # Create first image 130 populate_slice /dev/${MD}${NANO_PARTITION_ROOT} ${NANO_WORLDDIR} ${MNT} "${NANO_ROOT}" 131 mount /dev/${MD}a ${MNT} 132 echo "Generating mtree..." 133 ( cd ${MNT} && mtree -c ) > ${NANO_OBJ}/_.mtree 134 ( cd ${MNT} && du -k ) > ${NANO_OBJ}/_.du 135 nano_umount ${MNT} 136 137 if [ "${NANO_MD_BACKING}" = "swap" ] ; then 138 echo "Writing out _.disk.image..." 139 dd conv=sparse if=/dev/${MD} of=${NANO_DISKIMGDIR}/_.disk.image bs=64k 140 fi 141 mdconfig -d -u $MD 142 143 trap - 1 2 15 EXIT 144 145 ) > ${NANO_OBJ}/_.cs 2>&1 146) 147 148 149create_diskimage ( ) ( 150 pprint 2 "build diskimage" 151 pprint 3 "log: ${NANO_OBJ}/_.di" 152 153 ( 154 155 IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME} 156 MNT=${NANO_OBJ}/_.mnt 157 mkdir -p ${MNT} 158 159 if [ "${NANO_MD_BACKING}" = "swap" ] ; then 160 MD=`mdconfig -a -t swap -s ${NANO_MEDIASIZE} -x ${NANO_SECTS} \ 161 -y ${NANO_HEADS}` 162 else 163 echo "Creating md backing file..." 164 rm -f ${IMG} 165 dd if=/dev/zero of=${IMG} seek=${NANO_MEDIASIZE} count=0 166 MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \ 167 -y ${NANO_HEADS}` 168 fi 169 170 awk ' 171 BEGIN { 172 # Create MBR partition table 173 print "gpart create -s mbr $1" 174 } 175 { 176 # Make partition 177 print "gpart add -t freebsd -b ", $1, " -s ", $2, " $1" 178 } 179 END { 180 # Force slice 1 to be marked active. This is necessary 181 # for booting the image from a USB device to work. 182 print "gpart set -a active -i 1 $1" 183 } 184 ' ${NANO_LOG}/_.partitioning > ${NANO_OBJ}/_.gpart 185 186 trap "echo 'Running exit trap code' ; df -i ${MNT} ; nano_umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT 187 188 sh ${NANO_OBJ}/_.gpart ${MD} 189 gpart show ${MD} 190 # XXX: params 191 # XXX: pick up cached boot* files, they may not be in image anymore. 192 if [ -f ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ]; then 193 gpart bootcode -b ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ${NANO_BOOTFLAGS} ${MD} 194 fi 195 196 echo "Writing code image..." 197 dd conv=sparse if=${NANO_DISKIMGDIR}/_.disk.image of=/dev/${MD}${NANO_SLICE_ROOT} bs=64k 198 199 if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then 200 # Duplicate to second image (if present) 201 echo "Duplicating to second image..." 202 dd conv=sparse if=/dev/${MD}${NANO_SLICE_ROOT} of=/dev/${MD}${NANO_SLICE_ALTROOT} bs=64k 203 mount /dev/${MD}${NANO_ALTROOT} ${MNT} 204 for f in ${MNT}/etc/fstab ${MNT}/conf/base/etc/fstab 205 do 206 sed -i "" "s=${NANO_DRIVE}${NANO_SLICE_ROOT}=${NANO_DRIVE}${NANO_SLICE_ALTROOT}=g" $f 207 done 208 nano_umount ${MNT} 209 # Override the label from the first partition so we 210 # don't confuse glabel with duplicates. 211 if [ -n "${NANO_LABEL}" ]; then 212 tunefs -L ${NANO_LABEL}"${NANO_ALTROOT}" /dev/${MD}${NANO_ALTROOT} 213 fi 214 fi 215 216 # Create Config slice 217 populate_cfg_slice /dev/${MD}${NANO_SLICE_CFG} "${NANO_CFGDIR}" ${MNT} "${NANO_SLICE_CFG}" 218 219 # Create Data slice, if any. 220 if [ -n "$NANO_SLICE_DATA" -a "$NANO_SLICE_CFG" = "$NANO_SLICE_DATA" -a \ 221 "$NANO_DATASIZE" -ne 0 ]; then 222 pprint 2 "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix." 223 exit 2 224 fi 225 if [ $NANO_DATASIZE -ne 0 -a -n "$NANO_SLICE_DATA" ] ; then 226 populate_data_slice /dev/${MD}${NANO_SLICE_DATA} "${NANO_DATADIR}" ${MNT} "${NANO_SLICE_DATA}" 227 fi 228 229 if [ "${NANO_MD_BACKING}" = "swap" ] ; then 230 if [ ${NANO_IMAGE_MBRONLY} ]; then 231 echo "Writing out _.disk.mbr..." 232 dd if=/dev/${MD} of=${NANO_DISKIMGDIR}/_.disk.mbr bs=512 count=1 233 else 234 echo "Writing out ${NANO_IMGNAME}..." 235 dd if=/dev/${MD} of=${IMG} bs=64k 236 fi 237 238 echo "Writing out ${NANO_IMGNAME}..." 239 dd conv=sparse if=/dev/${MD} of=${IMG} bs=64k 240 fi 241 242 mdconfig -d -u $MD 243 244 trap - 1 2 15 EXIT 245 246 ) > ${NANO_LOG}/_.di 2>&1 247) 248