1#!/bin/sh 2 3# $FreeBSD$ 4 5# 6# Installs/updates the necessary boot blocks for the desired boot environment 7# 8# Lightly tested.. Intended to be installed, but until it matures, it will just 9# be a boot tool for regression testing. 10 11# insert code here to guess what you have -- yikes! 12 13die() { 14 echo $* 15 exit 1 16} 17 18doit() { 19 echo $* 20 eval $* 21} 22 23find-part() { 24 dev=$1 25 part=$2 26 27 gpart show $dev | tail +2 | awk '$4 == "'$part'" { print $3; }' 28} 29 30make_esp() { 31 local dev dst mntpt 32 33 dev=$1 34 dst=$2 35 36 newfs_msdos -a 32 /dev/${dev} 37 mntpt=$(mktemp -d /tmp/stand-test.XXXXXX) 38 mount -t msdos /dev/${md} ${mntpt} 39 mkdir -p ${mntpt}/efi/boot 40 cp ${dst}/boot/loader.efi ${mntpt}/efi/boot/bootx64.efi 41 umount ${mntpt} 42 rmdir ${mntpt} 43} 44 45make_esp_mbr() { 46 dev=$1 47 dst=$2 48 49 s=$(find-part $dev "!239") 50 if [ -z "$s" ] ; then 51 die "No ESP slice found" 52 fi 53 make_esp /dev/${dev}s${s} ${dst} 54} 55 56make_esp_gpt() { 57 dev=$1 58 dst=$2 59 60 idx=$(find-part $dev "efi") 61 if [ -z "$idx" ] ; then 62 die "No ESP partition found" 63 fi 64 make_esp /dev/${dev}p${idx} ${dst} 65} 66 67boot_nogeli_gpt_ufs_legacy() { 68 dev=$1 69 dst=$2 70 71 idx=$(find-part $dev "freebsd-boot") 72 if [ -z "$idx" ] ; then 73 die "No freebsd-boot partition found" 74 fi 75 doit gpart bootcode -b ${gpt0} -p ${gpt2} -i $idx $dev 76} 77 78boot_nogeli_gpt_ufs_uefi() { 79 make_esp_gpt $1 $2 80} 81 82boot_nogeli_gpt_ufs_both() { 83 boot_nogeli_gpt_ufs_legacy $1 $2 $3 84 boot_nogeli_gpt_ufs_uefi $1 $2 $3 85} 86 87boot_nogeli_gpt_zfs_legacy() { 88 dev=$1 89 dst=$2 90 91 idx=$(find-part $dev "freebsd-boot") 92 if [ -z "$idx" ] ; then 93 die "No freebsd-boot partition found" 94 fi 95 doit gpart bootcode -b ${gpt0} -p ${gptzfs2} -i $idx $dev 96} 97 98boot_nogeli_gpt_zfs_uefi() { 99 make_esp_gpt $1 $2 100} 101 102boot_nogeli_gpt_zfs_both() { 103 boot_nogeli_gpt_zfs_legacy $1 $2 $3 104 boot_nogeli_gpt_zfs_uefi $1 $2 $3 105} 106 107boot_nogeli_mbr_ufs_legacy() { 108 dev=$1 109 dst=$2 110 111 doit gpart bootcode -b ${mbr0} ${dev} 112 s=$(find-part $dev "freebsd") 113 if [ -z "$s" ] ; then 114 die "No freebsd slice found" 115 fi 116 doit gpart bootcode -p ${mbr2} ${dev}s${s} 117} 118 119boot_nogeli_mbr_ufs_uefi() { 120 make_esp_mbr $1 $2 121} 122 123boot_nogeli_mbr_ufs_both() { 124 boot_nogeli_mbr_ufs_legacy $1 $2 $3 125 boot_nogeli_mbr_ufs_uefi $1 $2 $3 126} 127 128boot_nogeli_mbr_zfs_legacy() { 129 dev=$1 130 dst=$2 131 132 # search to find the BSD slice 133 s=$(find-part $dev "freebsd") 134 if [ -z "$s" ] ; then 135 die "No BSD slice found" 136 fi 137 idx=$(find-part ${dev}s${s} "freebsd-zfs") 138 if [ -z "$idx" ] ; then 139 die "No freebsd-zfs slice found" 140 fi 141 # search to find the freebsd-zfs partition within the slice 142 # Or just assume it is 'a' because it has to be since it fails otherwise 143 doit gpart bootcode -b ${dst}/boot/mbr ${dev} 144 dd if=${dst}/boot/zfsboot of=/tmp/zfsboot1 count=1 145 doit gpart bootcode -b /tmp/zfsboot1 ${dev}s${s} # Put boot1 into the start of part 146 sysctl kern.geom.debugflags=0x10 # Put boot2 into ZFS boot slot 147 doit dd if=${dst}/boot/zfsboot of=/dev/${dev}s${s}a skip=1 seek=1024 148 sysctl kern.geom.debugflags=0x0 149} 150 151boot_nogeli_mbr_zfs_uefi() { 152 make_eps_mbr $1 $2 153} 154 155boot_nogeli_mbr_zfs_both() { 156 boot_nogeli_mbr_zfs_legacy $1 $2 $3 157 boot_nogeli_mbr_zfs_uefi $1 $2 $3 158} 159 160boot_geli_gpt_ufs_legacy() { 161 boot_nogeli_gpt_ufs_legacy $1 $2 $3 162} 163 164boot_geli_gpt_ufs_uefi() { 165 boot_nogeli_gpt_ufs_uefi $1 $2 $3 166} 167 168boot_geli_gpt_ufs_both() { 169 boot_nogeli_gpt_ufs_both $1 $2 $3 170} 171 172boot_geli_gpt_zfs_legacy() { 173 boot_nogeli_gpt_zfs_legacy $1 $2 $3 174} 175 176boot_geli_gpt_zfs_uefi() { 177 boot_nogeli_gpt_zfs_uefi $1 $2 $3 178} 179 180boot_geli_gpt_zfs_both() { 181 boot_nogeli_gpt_zfs_both $1 $2 $3 182} 183 184# GELI+MBR is not a valid configuration 185boot_geli_mbr_ufs_legacy() { 186 exit 1 187} 188 189boot_geli_mbr_ufs_uefi() { 190 exit 1 191} 192 193boot_geli_mbr_ufs_both() { 194 exit 1 195} 196 197boot_geli_mbr_zfs_legacy() { 198 exit 1 199} 200 201boot_geli_mbr_zfs_uefi() { 202 exit 1 203} 204 205boot_geli_mbr_zfs_both() { 206 exit 1 207} 208 209boot_nogeli_vtoc8_ufs_ofw() { 210 dev=$1 211 dst=$2 212 213 # For non-native builds, ensure that geom_part(4) supports VTOC8. 214 kldload geom_part_vtoc8.ko 215 doit gpart bootcode -p ${vtoc8} ${dev} 216} 217 218DESTDIR=/ 219 220# Note: we really don't support geli boot in this script yet. 221geli=nogeli 222 223while getopts "b:d:f:g:o:s:" opt; do 224 case "$opt" in 225 b) 226 bios=${OPTARG} 227 ;; 228 d) 229 DESTDIR=${OPTARG} 230 ;; 231 f) 232 fs=${OPTARG} 233 ;; 234 g) 235 case ${OPTARG} in 236 [Yy][Ee][Ss]|geli) geli=geli ;; 237 *) geli=nogeli ;; 238 esac 239 ;; 240 o) 241 opts=${OPTARG} 242 ;; 243 s) 244 scheme=${OPTARG} 245 ;; 246 esac 247done 248 249shift $((OPTIND-1)) 250dev=$1 251 252# For gpt, we need to install pmbr as the primary boot loader 253# it knows about 254gpt0=${DESTDIR}/boot/pmbr 255gpt2=${DESTDIR}/boot/gptboot 256gptzfs2=${DESTDIR}/boot/gptzfsboot 257 258# For MBR, we have lots of choices, but select mbr, boot0 has issues with UEFI 259mbr0=${DESTDIR}/boot/mbr 260mbr2=${DESTDIR}/boot/boot 261 262# VTOC8 263vtoc8=${DESTDIR}/boot/boot1 264 265# sanity check here 266 267eval boot_${geli}_${scheme}_${fs}_${bios} $dev $DESTDIR $opts || echo "Unsupported boot env: ${geli}-${scheme}-${fs}-${bios}" 268