1#!/bin/sh 2#- 3# Copyright (c) 2015-2017 The FreeBSD Foundation 4# 5# Portions of this software were developed by Glen Barber 6# under sponsorship from the FreeBSD Foundation. 7# 8# Redistribution and use in source and binary forms, with or without 9# modification, are permitted provided that the following conditions 10# are met: 11# 1. Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27# SUCH DAMAGE. 28# 29# Common subroutines used to build arm, arm64, or RISC-V SD card images. 30# 31# 32 33cleanup() { 34 if [ -c "${DESTDIR}/dev/null" ]; then 35 umount_loop ${DESTDIR}/dev 2>/dev/null 36 fi 37 umount_loop ${DESTDIR} 38 if [ ! -z "${mddev}" ]; then 39 mdconfig -d -u ${mddev} 40 fi 41 42 return 0 43} 44 45umount_loop() { 46 DIR=$1 47 i=0 48 sync 49 while ! umount ${DIR}; do 50 i=$(( $i + 1 )) 51 if [ $i -ge 10 ]; then 52 # This should never happen. But, it has happened. 53 echo "Cannot umount(8) ${DIR}" 54 echo "Something has gone horribly wrong." 55 return 1 56 fi 57 sleep 1 58 done 59 60 return 0 61} 62 63arm_create_disk() { 64 if [ $(sysctl -n kern.geom.part.mbr.enforce_chs) != 0 ]; then 65 return 1 66 fi 67 68 # Create the target raw file and temporary work directory. 69 chroot ${CHROOTDIR} gpart create -s ${PART_SCHEME} ${mddev} 70 71 arm_create_partitions 72 73 if [ "${PART_SCHEME}" = "GPT" ]; then 74 chroot ${CHROOTDIR} gpart add -t efi -l efi -a 512k -s ${FAT_SIZE} ${mddev} 75 chroot ${CHROOTDIR} gpart add -t freebsd-ufs -l rootfs -a 64k ${mddev} 76 fi 77 if [ "${PART_SCHEME}" = "MBR" ]; then 78 chroot ${CHROOTDIR} gpart add -t '!12' -a 512k -s ${FAT_SIZE} ${mddev} 79 chroot ${CHROOTDIR} gpart set -a active -i 1 ${mddev} 80 chroot ${CHROOTDIR} gpart add -t freebsd ${mddev} 81 chroot ${CHROOTDIR} gpart create -s bsd ${mddev}${BSDLABEL_SUFFIX} 82 chroot ${CHROOTDIR} gpart add -t freebsd-ufs -a 64k -b 64k ${mddev}${BSDLABEL_SUFFIX} 83 fi 84 85 # Create the EFI and UFS filesystems 86 chroot ${CHROOTDIR} newfs_msdos -L efi -F ${FAT_TYPE} /dev/${mddev}${EFIPART_SUFFIX} 87 chroot ${CHROOTDIR} newfs -U -L rootfs /dev/${mddev}${ROOTFSPART_SUFFIX} 88 89 return 0 90} 91 92arm_create_user() { 93 # Create a default user account 'freebsd' with the password 'freebsd', 94 # and set the default password for the 'root' user to 'root'. 95 chroot ${CHROOTDIR} /usr/sbin/pw -R ${DESTDIR} \ 96 groupadd freebsd -g 1001 97 chroot ${CHROOTDIR} mkdir -p ${DESTDIR}/home/freebsd 98 chroot ${CHROOTDIR} /usr/sbin/pw -R ${DESTDIR} \ 99 useradd freebsd \ 100 -m -M 0755 -w yes -n freebsd -u 1001 -g 1001 -G 0 \ 101 -c 'FreeBSD User' -d '/home/freebsd' -s '/bin/csh' 102 chroot ${CHROOTDIR} /usr/sbin/pw -R ${DESTDIR} \ 103 usermod root -w yes 104 105 return 0 106} 107 108arm_setup_usb_otg() { 109 # Set up virtual serial port over USB OTG / device mode. 110 echo >> ${CHROOTDIR}/${DESTDIR}/etc/devd.conf 111 echo '# Required for USB OTG virtual serial port.' \ 112 >> ${CHROOTDIR}/${DESTDIR}/etc/devd.conf 113 echo 'notify 100 {' \ 114 >> ${CHROOTDIR}/${DESTDIR}/etc/devd.conf 115 echo ' match "system" "DEVFS";' \ 116 >> ${CHROOTDIR}/${DESTDIR}/etc/devd.conf 117 echo ' match "subsystem" "CDEV";' \ 118 >> ${CHROOTDIR}/${DESTDIR}/etc/devd.conf 119 echo ' match "type" "CREATE";' \ 120 >> ${CHROOTDIR}/${DESTDIR}/etc/devd.conf 121 echo ' match "cdev" "ttyU[0-9]+";' \ 122 >> ${CHROOTDIR}/${DESTDIR}/etc/devd.conf 123 echo ' action "/sbin/init q";' \ 124 >> ${CHROOTDIR}/${DESTDIR}/etc/devd.conf 125 echo '};' \ 126 >> ${CHROOTDIR}/${DESTDIR}/etc/devd.conf 127 128 echo '# USB OTG virtual serial port' \ 129 >> ${CHROOTDIR}/${DESTDIR}/etc/ttys 130 echo 'ttyU0 "/usr/libexec/getty 3wire" vt100 onifconsole secure' \ 131 >> ${CHROOTDIR}/${DESTDIR}/etc/ttys 132 echo 'ttyU1 "/usr/libexec/getty 3wire" vt100 onifconsole secure' \ 133 >> ${CHROOTDIR}/${DESTDIR}/etc/ttys 134 135 echo '# Configure USB OTG; see usb_template(4).' \ 136 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 137 echo 'hw.usb.template=3' \ 138 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 139 echo 'umodem_load="YES"' \ 140 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 141} 142 143arm64_setup_multicons() { 144 if [ "${EMBEDDED_TARGET_ARCH}" != "aarch64" ]; then 145 return 146 fi 147 148 echo '# Multiple console (serial+efi gop) enabled.' \ 149 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 150 echo 'boot_multicons="YES"' \ 151 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 152 echo 'boot_serial="YES"' \ 153 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 154} 155 156arm_setup_fdt_overlays() { 157 if [ -z "${FDT_OVERLAYS}" ]; then 158 return 159 fi 160 161 echo '# DTB OVERLAYS' \ 162 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 163 echo "fdt_overlays=\"${FDT_OVERLAYS}\"" \ 164 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 165} 166 167arm_setup_minimal_loader() { 168 echo '# Disable the beastie menu and color' \ 169 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 170 echo 'beastie_disable="YES"' \ 171 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 172 echo 'loader_color="NO"' \ 173 >> ${CHROOTDIR}/${DESTDIR}/boot/loader.conf 174} 175 176arm_install_base() { 177 chroot ${CHROOTDIR} mount /dev/${mddev}${ROOTFSPART_SUFFIX} ${DESTDIR} 178 _OSVERSION=$(chroot ${CHROOTDIR} /usr/bin/uname -U) 179 REVISION=$(chroot ${CHROOTDIR} make -C /usr/src/release -V REVISION) 180 BRANCH=$(chroot ${CHROOTDIR} make -C /usr/src/release -V BRANCH) 181 export UNAME_r=${REVISION}-${BRANCH} 182 eval chroot ${CHROOTDIR} make -C ${WORLDDIR} \ 183 TARGET=${EMBEDDED_TARGET} \ 184 TARGET_ARCH=${EMBEDDED_TARGET_ARCH} \ 185 DESTDIR=${DESTDIR} KERNCONF=${KERNEL} \ 186 ${CONF_FILES} installworld installkernel distribution 187 chroot ${CHROOTDIR} mkdir -p ${DESTDIR}/boot/efi 188 # Compatibility symlink to /boot/msdos for 13.1 and earlier 189 chroot ${CHROOTDIR} ln -s efi ${DESTDIR}/boot/msdos 190 191 arm_create_user 192 arm_setup_usb_otg 193 arm64_setup_multicons 194 arm_setup_fdt_overlays 195 arm_setup_minimal_loader 196 arm_do_quirk 197 198 echo '# Custom /etc/fstab for FreeBSD embedded images' \ 199 > ${CHROOTDIR}/${DESTDIR}/etc/fstab 200 echo "/dev/ufs/rootfs / ufs rw 1 1" \ 201 >> ${CHROOTDIR}/${DESTDIR}/etc/fstab 202 echo "/dev/msdosfs/EFI /boot/efi msdosfs rw,noatime 0 0" \ 203 >> ${CHROOTDIR}/${DESTDIR}/etc/fstab 204 echo "tmpfs /tmp tmpfs rw,mode=1777 0 0" \ 205 >> ${CHROOTDIR}/${DESTDIR}/etc/fstab 206 207 local hostname 208 hostname="$(echo ${KERNEL} | tr '[:upper:]' '[:lower:]')" 209 echo "hostname=\"${hostname}\"" > ${CHROOTDIR}/${DESTDIR}/etc/rc.conf 210 echo 'ifconfig_DEFAULT="DHCP inet6 accept_rtadv"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf 211 echo 'sshd_enable="YES"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf 212 echo 'sendmail_enable="NONE"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf 213 echo 'sendmail_submit_enable="NO"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf 214 echo 'sendmail_outbound_enable="NO"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf 215 echo 'sendmail_msp_queue_enable="NO"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf 216 echo 'growfs_enable="YES"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf 217 if [ -n "${CONFIG_POWERD_ENABLE}" ]; then 218 echo 'powerd_enable="YES"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf 219 fi 220 221 sync 222 umount_loop ${CHROOTDIR}/${DESTDIR} 223 224 return 0 225} 226 227arm_install_boot() { 228 FATMOUNT="${DESTDIR%${KERNEL}}/fat" 229 UFSMOUNT="${DESTDIR%${KERNEL}}/ufs" 230 chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}" 231 dospart="/dev/${mddev}${EFIPART_SUFFIX}" 232 ufspart="/dev/${mddev}${ROOTFSPART_SUFFIX}" 233 234 chroot ${CHROOTDIR} mount_msdosfs ${dospart} ${FATMOUNT} 235 chroot ${CHROOTDIR} mount ${ufspart} ${UFSMOUNT} 236 237 BOOTFILES="$(chroot ${CHROOTDIR} \ 238 env TARGET=${EMBEDDED_TARGET} TARGET_ARCH=${EMBEDDED_TARGET_ARCH} \ 239 WITH_UNIFIED_OBJDIR=yes \ 240 make -C ${WORLDDIR}/stand -V .OBJDIR)" 241 BOOTFILES="$(chroot ${CHROOTDIR} realpath ${BOOTFILES})" 242 243 chroot ${CHROOTDIR} mkdir -p ${FATMOUNT}/EFI/BOOT 244 chroot ${CHROOTDIR} cp -p ${BOOTFILES}/efi/loader_lua/loader_lua.efi \ 245 ${FATMOUNT}/EFI/BOOT/$(efi_boot_name ${EMBEDDED_TARGET}) 246 247 chroot ${CHROOTDIR} cp -R ${UFSMOUNT}/boot/dtb ${FATMOUNT} 248 249 chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot 250 sync 251 umount_loop ${CHROOTDIR}/${FATMOUNT} 252 umount_loop ${CHROOTDIR}/${UFSMOUNT} 253 chroot ${CHROOTDIR} rmdir ${FATMOUNT} 254 chroot ${CHROOTDIR} rmdir ${UFSMOUNT} 255} 256 257arm_install_uboot() { 258 # Override in the ${EMBEDDED_TARGET}/${BOARDNAME}.conf file. 259 260 return 0 261} 262 263arm_do_quirk() { 264 # Override in the ${EMBEDDED_TARGET}/${BOARDNAME}.conf file. 265} 266 267arm_create_partitions() { 268 # Override in the ${EMBEDDED_TARGET}/${BOARDNAME}.conf file. 269 270 # Set defaults for EFIPART_SUFFIX, ROOTFSPART_SUFFIX, and 271 # BSDLABEL_SUFFIX (MBR only), needed elsewhere. 272 273 if [ "${PART_SCHEME}" = "GPT" ]; then 274 export EFIPART_SUFFIX=p1 275 export ROOTFSPART_SUFFIX=p2 276 fi 277 if [ "${PART_SCHEME}" = "MBR" ]; then 278 export EFIPART_SUFFIX=s1 279 export BSDLABEL_SUFFIX=s2 280 export ROOTFSPART_SUFFIX=s2a 281 fi 282} 283