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