xref: /freebsd/tools/boot/install-boot.sh (revision 599273f942b8dc6f957487bb28f36694dab9dad2)
1cfc94828SWarner Losh#!/bin/sh
2cfc94828SWarner Losh
3cfc94828SWarner Losh#
4cfc94828SWarner Losh# Installs/updates the necessary boot blocks for the desired boot environment
5cfc94828SWarner Losh#
6cfc94828SWarner Losh# Lightly tested.. Intended to be installed, but until it matures, it will just
7cfc94828SWarner Losh# be a boot tool for regression testing.
8cfc94828SWarner Losh
9cfc94828SWarner Losh# insert code here to guess what you have -- yikes!
10cfc94828SWarner Losh
11db8b5613SRebecca Cran# Minimum size of FAT filesystems, in KB.
12db8b5613SRebecca Cranfat32min=33292
13db8b5613SRebecca Cranfat16min=2100
14db8b5613SRebecca Cran
15cfc94828SWarner Loshdie() {
16cfc94828SWarner Losh    echo $*
17cfc94828SWarner Losh    exit 1
18cfc94828SWarner Losh}
19cfc94828SWarner Losh
209b544478SWarner Loshdoit() {
219b544478SWarner Losh    echo $*
229b544478SWarner Losh    eval $*
239b544478SWarner Losh}
249b544478SWarner Losh
2517160f21SJessica Clarkefind_part() {
26cfc94828SWarner Losh    dev=$1
27cfc94828SWarner Losh    part=$2
28cfc94828SWarner Losh
29cfc94828SWarner Losh    gpart show $dev | tail +2 | awk '$4 == "'$part'" { print $3; }'
30cfc94828SWarner Losh}
31cfc94828SWarner Losh
32db8b5613SRebecca Cranget_uefi_bootname() {
33c89deb8fSWarner Losh
34db8b5613SRebecca Cran    case ${TARGET:-$(uname -m)} in
35db8b5613SRebecca Cran        amd64) echo bootx64 ;;
36db8b5613SRebecca Cran        arm64) echo bootaa64 ;;
37db8b5613SRebecca Cran        i386) echo bootia32 ;;
38db8b5613SRebecca Cran        arm) echo bootarm ;;
39d46a2a00SMitchell Horne        riscv) echo bootriscv64 ;;
40db8b5613SRebecca Cran        *) die "machine type $(uname -m) doesn't support UEFI" ;;
41db8b5613SRebecca Cran    esac
42db8b5613SRebecca Cran}
43c89deb8fSWarner Losh
44db8b5613SRebecca Cranmake_esp_file() {
45*599273f9SAhmad Khalifa    local file sizekb device stagedir fatbits efibootname
46db8b5613SRebecca Cran
47db8b5613SRebecca Cran    file=$1
48db8b5613SRebecca Cran    sizekb=$2
49db8b5613SRebecca Cran
50db8b5613SRebecca Cran    if [ "$sizekb" -ge "$fat32min" ]; then
51db8b5613SRebecca Cran        fatbits=32
52db8b5613SRebecca Cran    elif [ "$sizekb" -ge "$fat16min" ]; then
53db8b5613SRebecca Cran        fatbits=16
54db8b5613SRebecca Cran    else
55db8b5613SRebecca Cran        fatbits=12
56db8b5613SRebecca Cran    fi
57db8b5613SRebecca Cran
5814113f12SMatt Macy    stagedir=$(mktemp -d /tmp/stand-test.XXXXXX)
5914113f12SMatt Macy    mkdir -p "${stagedir}/EFI/BOOT"
60*599273f9SAhmad Khalifa
61*599273f9SAhmad Khalifa    # Allow multiple files to be copied.
62*599273f9SAhmad Khalifa    # We do this in pairs, e.g:
63*599273f9SAhmad Khalifa    # make_esp_file ... loader1.efi bootx64 loader2.efi bootia32
64*599273f9SAhmad Khalifa    #
65*599273f9SAhmad Khalifa    # If the second argument is left out,
66*599273f9SAhmad Khalifa    # determine it automatically.
67*599273f9SAhmad Khalifa    shift; shift # Skip $file and $sizekb
68*599273f9SAhmad Khalifa    while [ ! -z $1 ]; do
69*599273f9SAhmad Khalifa        if [ ! -z $2 ]; then
70*599273f9SAhmad Khalifa            efibootname=$2
71*599273f9SAhmad Khalifa        else
72db8b5613SRebecca Cran            efibootname=$(get_uefi_bootname)
73*599273f9SAhmad Khalifa        fi
74*599273f9SAhmad Khalifa        cp "$1" "${stagedir}/EFI/BOOT/${efibootname}.efi"
75*599273f9SAhmad Khalifa
76*599273f9SAhmad Khalifa        shift; shift || : # Ignore failure to shift
77*599273f9SAhmad Khalifa    done
78*599273f9SAhmad Khalifa
7914113f12SMatt Macy    makefs -t msdos \
8014113f12SMatt Macy	-o fat_type=${fatbits} \
8114113f12SMatt Macy	-o sectors_per_cluster=1 \
8214113f12SMatt Macy	-o volume_label=EFISYS \
8314113f12SMatt Macy	-s ${sizekb}k \
8414113f12SMatt Macy	"${file}" "${stagedir}"
8514113f12SMatt Macy    rm -rf "${stagedir}"
86db8b5613SRebecca Cran}
87db8b5613SRebecca Cran
88db8b5613SRebecca Cranmake_esp_device() {
89*599273f9SAhmad Khalifa    local dev file dst mntpt fstype efibootname kbfree loadersize efibootfile
90db8b5613SRebecca Cran    local isboot1 existingbootentryloaderfile bootorder bootentry
91db8b5613SRebecca Cran
92db8b5613SRebecca Cran    # ESP device node
93db8b5613SRebecca Cran    dev=$1
94db8b5613SRebecca Cran    file=$2
95*599273f9SAhmad Khalifa    # Allow caller to override the default
96*599273f9SAhmad Khalifa    if [ ! -z $3 ]; then
97*599273f9SAhmad Khalifa	    efibootname=$3
98*599273f9SAhmad Khalifa    else
99*599273f9SAhmad Khalifa	    efibootname=$(get_uefi_bootname)
100*599273f9SAhmad Khalifa    fi
101db8b5613SRebecca Cran
102*599273f9SAhmad Khalifa    dst=$(basename ${file%.efi})
103db8b5613SRebecca Cran    mntpt=$(mktemp -d /tmp/stand-test.XXXXXX)
104db8b5613SRebecca Cran
105db8b5613SRebecca Cran    # See if we're using an existing (formatted) ESP
106db8b5613SRebecca Cran    fstype=$(fstyp "${dev}")
107db8b5613SRebecca Cran
108db8b5613SRebecca Cran    if [ "${fstype}" != "msdosfs" ]; then
109db8b5613SRebecca Cran        newfs_msdos -F 32 -c 1 -L EFISYS "${dev}" > /dev/null 2>&1
110db8b5613SRebecca Cran    fi
111db8b5613SRebecca Cran
112db8b5613SRebecca Cran    mount -t msdosfs "${dev}" "${mntpt}"
113db8b5613SRebecca Cran    if [ $? -ne 0 ]; then
114db8b5613SRebecca Cran        die "Failed to mount ${dev} as an msdosfs filesystem"
115db8b5613SRebecca Cran    fi
116db8b5613SRebecca Cran
117db8b5613SRebecca Cran    echo "Mounted ESP ${dev} on ${mntpt}"
118db8b5613SRebecca Cran
119db8b5613SRebecca Cran    kbfree=$(df -k "${mntpt}" | tail -1 | cut -w -f 4)
120db8b5613SRebecca Cran    loadersize=$(stat -f %z "${file}")
121db8b5613SRebecca Cran    loadersize=$((loadersize / 1024))
122db8b5613SRebecca Cran
123db8b5613SRebecca Cran    # Check if /EFI/BOOT/BOOTxx.EFI is the FreeBSD boot1.efi
124db8b5613SRebecca Cran    # If it is, remove it to avoid leaving stale files around
125db8b5613SRebecca Cran    efibootfile="${mntpt}/EFI/BOOT/${efibootname}.efi"
126db8b5613SRebecca Cran    if [ -f "${efibootfile}" ]; then
127db8b5613SRebecca Cran        isboot1=$(strings "${efibootfile}" | grep "FreeBSD EFI boot block")
128db8b5613SRebecca Cran
129db8b5613SRebecca Cran        if [ -n "${isboot1}" ] && [ "$kbfree" -lt "${loadersize}" ]; then
130db8b5613SRebecca Cran            echo "Only ${kbfree}KB space remaining: removing old FreeBSD boot1.efi file /EFI/BOOT/${efibootname}.efi"
131db8b5613SRebecca Cran            rm "${efibootfile}"
132db8b5613SRebecca Cran            rmdir "${mntpt}/EFI/BOOT"
133db8b5613SRebecca Cran        else
134db8b5613SRebecca Cran            echo "${kbfree}KB space remaining on ESP: renaming old boot1.efi file /EFI/BOOT/${efibootname}.efi /EFI/BOOT/${efibootname}-old.efi"
135db8b5613SRebecca Cran            mv "${efibootfile}" "${mntpt}/EFI/BOOT/${efibootname}-old.efi"
136db8b5613SRebecca Cran        fi
137db8b5613SRebecca Cran    fi
138db8b5613SRebecca Cran
139*599273f9SAhmad Khalifa    if [ ! -f "${mntpt}/EFI/freebsd/${dst}.efi" ] && [ "$kbfree" -lt "$loadersize" ]; then
140db8b5613SRebecca Cran        umount "${mntpt}"
141db8b5613SRebecca Cran	rmdir "${mntpt}"
142db8b5613SRebecca Cran        echo "Failed to update the EFI System Partition ${dev}"
143db8b5613SRebecca Cran        echo "Insufficient space remaining for ${file}"
144db8b5613SRebecca Cran        echo "Run e.g \"mount -t msdosfs ${dev} /mnt\" to inspect it for files that can be removed."
145db8b5613SRebecca Cran        die
146db8b5613SRebecca Cran    fi
147db8b5613SRebecca Cran
148db8b5613SRebecca Cran    mkdir -p "${mntpt}/EFI/freebsd"
149db8b5613SRebecca Cran
150db8b5613SRebecca Cran    # Keep a copy of the existing loader.efi in case there's a problem with the new one
151*599273f9SAhmad Khalifa    if [ -f "${mntpt}/EFI/freebsd/${dst}.efi" ] && [ "$kbfree" -gt "$((loadersize * 2))" ]; then
152*599273f9SAhmad Khalifa        cp "${mntpt}/EFI/freebsd/${dst}.efi" "${mntpt}/EFI/freebsd/${dst}-old.efi"
153db8b5613SRebecca Cran    fi
154db8b5613SRebecca Cran
155db8b5613SRebecca Cran    echo "Copying loader to /EFI/freebsd on ESP"
156*599273f9SAhmad Khalifa    cp "${file}" "${mntpt}/EFI/freebsd/${dst}.efi"
157db8b5613SRebecca Cran
158*599273f9SAhmad Khalifa    # efibootmgr won't work on systems with ia32 UEFI firmware
159*599273f9SAhmad Khalifa    # since we only use it to boot the 64-bit kernel
160*599273f9SAhmad Khalifa    if [ -n "${updatesystem}" ] && [ ${efibootname} != "bootia32" ]; then
161*599273f9SAhmad Khalifa        existingbootentryloaderfile=$(efibootmgr -v | grep "${mntpt}//EFI/freebsd/${dst}.efi")
162db8b5613SRebecca Cran
163db8b5613SRebecca Cran        if [ -z "$existingbootentryloaderfile" ]; then
164db8b5613SRebecca Cran            # Try again without the double forward-slash in the path
165*599273f9SAhmad Khalifa            existingbootentryloaderfile=$(efibootmgr -v | grep "${mntpt}/EFI/freebsd/${dst}.efi")
166db8b5613SRebecca Cran        fi
167db8b5613SRebecca Cran
168db8b5613SRebecca Cran        if [ -z "$existingbootentryloaderfile" ]; then
169db8b5613SRebecca Cran            echo "Creating UEFI boot entry for FreeBSD"
170*599273f9SAhmad Khalifa            efibootmgr --create --label FreeBSD --loader "${mntpt}/EFI/freebsd/${dst}.efi" > /dev/null
171db8b5613SRebecca Cran            if [ $? -ne 0 ]; then
172db8b5613SRebecca Cran                die "Failed to create new boot entry"
173db8b5613SRebecca Cran            fi
174db8b5613SRebecca Cran
175db8b5613SRebecca Cran            # When creating new entries, efibootmgr doesn't mark them active, so we need to
176db8b5613SRebecca Cran            # do so. It doesn't make it easy to find which entry it just added, so rely on
177db8b5613SRebecca Cran            # the fact that it places the new entry first in BootOrder.
178db8b5613SRebecca Cran            bootorder=$(efivar --name 8be4df61-93ca-11d2-aa0d-00e098032b8c-BootOrder --print --no-name --hex | head -1)
179db8b5613SRebecca Cran            bootentry=$(echo "${bootorder}" | cut -w -f 3)$(echo "${bootorder}" | cut -w -f 2)
180db8b5613SRebecca Cran            echo "Marking UEFI boot entry ${bootentry} active"
181db8b5613SRebecca Cran            efibootmgr --activate "${bootentry}" > /dev/null
182db8b5613SRebecca Cran        else
183db8b5613SRebecca Cran            echo "Existing UEFI FreeBSD boot entry found: not creating a new one"
184db8b5613SRebecca Cran        fi
1850661cd79SRebecca Cran    else
1860661cd79SRebecca Cran	# Configure for booting from removable media
1870661cd79SRebecca Cran	if [ ! -d "${mntpt}/EFI/BOOT" ]; then
1880661cd79SRebecca Cran		mkdir -p "${mntpt}/EFI/BOOT"
1890661cd79SRebecca Cran	fi
1900661cd79SRebecca Cran	cp "${file}" "${mntpt}/EFI/BOOT/${efibootname}.efi"
1910661cd79SRebecca Cran    fi
192db8b5613SRebecca Cran
193db8b5613SRebecca Cran    umount "${mntpt}"
194db8b5613SRebecca Cran    rmdir "${mntpt}"
195db8b5613SRebecca Cran    echo "Finished updating ESP"
196db8b5613SRebecca Cran}
197db8b5613SRebecca Cran
198db8b5613SRebecca Cranmake_esp() {
199db8b5613SRebecca Cran    local file loaderfile
200db8b5613SRebecca Cran
201db8b5613SRebecca Cran    file=$1
202db8b5613SRebecca Cran    loaderfile=$2
203db8b5613SRebecca Cran
204db8b5613SRebecca Cran    if [ -f "$file" ]; then
205db8b5613SRebecca Cran        make_esp_file ${file} ${fat32min} ${loaderfile}
206db8b5613SRebecca Cran    else
207db8b5613SRebecca Cran        make_esp_device ${file} ${loaderfile}
208db8b5613SRebecca Cran    fi
209c89deb8fSWarner Losh}
210c89deb8fSWarner Losh
211c89deb8fSWarner Loshmake_esp_mbr() {
212c89deb8fSWarner Losh    dev=$1
213c89deb8fSWarner Losh    dst=$2
214c89deb8fSWarner Losh
21517160f21SJessica Clarke    s=$(find_part $dev "!239")
216c89deb8fSWarner Losh    if [ -z "$s" ] ; then
21717160f21SJessica Clarke	s=$(find_part $dev "efi")
218394641cfSIan Lepore	if [ -z "$s" ] ; then
219c89deb8fSWarner Losh	    die "No ESP slice found"
220c89deb8fSWarner Losh    	fi
221394641cfSIan Lepore    fi
222db8b5613SRebecca Cran    make_esp /dev/${dev}s${s} ${dst}/boot/loader.efi
223c89deb8fSWarner Losh}
224c89deb8fSWarner Losh
225c89deb8fSWarner Loshmake_esp_gpt() {
226c89deb8fSWarner Losh    dev=$1
227c89deb8fSWarner Losh    dst=$2
228c89deb8fSWarner Losh
22917160f21SJessica Clarke    idx=$(find_part $dev "efi")
230c89deb8fSWarner Losh    if [ -z "$idx" ] ; then
231c89deb8fSWarner Losh	die "No ESP partition found"
232c89deb8fSWarner Losh    fi
233db8b5613SRebecca Cran    make_esp /dev/${dev}p${idx} ${dst}/boot/loader.efi
234c89deb8fSWarner Losh}
235c89deb8fSWarner Losh
236cfc94828SWarner Loshboot_nogeli_gpt_ufs_legacy() {
237cfc94828SWarner Losh    dev=$1
238cfc94828SWarner Losh    dst=$2
239cfc94828SWarner Losh
24017160f21SJessica Clarke    idx=$(find_part $dev "freebsd-boot")
241cfc94828SWarner Losh    if [ -z "$idx" ] ; then
242cfc94828SWarner Losh	die "No freebsd-boot partition found"
243cfc94828SWarner Losh    fi
2449b544478SWarner Losh    doit gpart bootcode -b ${gpt0} -p ${gpt2} -i $idx $dev
245f438a143SAllan Jude}
246f438a143SAllan Jude
247f438a143SAllan Judeboot_nogeli_gpt_ufs_uefi() {
248c89deb8fSWarner Losh    make_esp_gpt $1 $2
249f438a143SAllan Jude}
250f438a143SAllan Jude
251f438a143SAllan Judeboot_nogeli_gpt_ufs_both() {
252f438a143SAllan Jude    boot_nogeli_gpt_ufs_legacy $1 $2 $3
253f438a143SAllan Jude    boot_nogeli_gpt_ufs_uefi $1 $2 $3
254f438a143SAllan Jude}
255f438a143SAllan Jude
256f438a143SAllan Judeboot_nogeli_gpt_zfs_legacy() {
257f438a143SAllan Jude    dev=$1
258f438a143SAllan Jude    dst=$2
259f438a143SAllan Jude
26017160f21SJessica Clarke    idx=$(find_part $dev "freebsd-boot")
261f438a143SAllan Jude    if [ -z "$idx" ] ; then
262f438a143SAllan Jude	die "No freebsd-boot partition found"
263f438a143SAllan Jude    fi
264f438a143SAllan Jude    doit gpart bootcode -b ${gpt0} -p ${gptzfs2} -i $idx $dev
265cfc94828SWarner Losh}
266cfc94828SWarner Losh
267712b4ca9SAllan Judeboot_nogeli_gpt_zfs_uefi() {
268c89deb8fSWarner Losh    make_esp_gpt $1 $2
269712b4ca9SAllan Jude}
270712b4ca9SAllan Jude
271712b4ca9SAllan Judeboot_nogeli_gpt_zfs_both() {
272f438a143SAllan Jude    boot_nogeli_gpt_zfs_legacy $1 $2 $3
273f438a143SAllan Jude    boot_nogeli_gpt_zfs_uefi $1 $2 $3
274cfc94828SWarner Losh}
275cfc94828SWarner Losh
276cfc94828SWarner Loshboot_nogeli_mbr_ufs_legacy() {
277cfc94828SWarner Losh    dev=$1
278cfc94828SWarner Losh    dst=$2
279cfc94828SWarner Losh
2809b544478SWarner Losh    doit gpart bootcode -b ${mbr0} ${dev}
28117160f21SJessica Clarke    s=$(find_part $dev "freebsd")
282cfc94828SWarner Losh    if [ -z "$s" ] ; then
283f438a143SAllan Jude	die "No freebsd slice found"
284cfc94828SWarner Losh    fi
2859b544478SWarner Losh    doit gpart bootcode -p ${mbr2} ${dev}s${s}
286f438a143SAllan Jude}
287f438a143SAllan Jude
288f438a143SAllan Judeboot_nogeli_mbr_ufs_uefi() {
289c89deb8fSWarner Losh    make_esp_mbr $1 $2
290f438a143SAllan Jude}
291f438a143SAllan Jude
292f438a143SAllan Judeboot_nogeli_mbr_ufs_both() {
293f438a143SAllan Jude    boot_nogeli_mbr_ufs_legacy $1 $2 $3
294f438a143SAllan Jude    boot_nogeli_mbr_ufs_uefi $1 $2 $3
295f438a143SAllan Jude}
296f438a143SAllan Jude
297f438a143SAllan Judeboot_nogeli_mbr_zfs_legacy() {
298f438a143SAllan Jude    dev=$1
299f438a143SAllan Jude    dst=$2
300f438a143SAllan Jude
301f438a143SAllan Jude    # search to find the BSD slice
30217160f21SJessica Clarke    s=$(find_part $dev "freebsd")
303f438a143SAllan Jude    if [ -z "$s" ] ; then
304f438a143SAllan Jude	die "No BSD slice found"
305f438a143SAllan Jude    fi
30617160f21SJessica Clarke    idx=$(find_part ${dev}s${s} "freebsd-zfs")
307f438a143SAllan Jude    if [ -z "$idx" ] ; then
308f438a143SAllan Jude	die "No freebsd-zfs slice found"
309f438a143SAllan Jude    fi
310f438a143SAllan Jude    # search to find the freebsd-zfs partition within the slice
311f438a143SAllan Jude    # Or just assume it is 'a' because it has to be since it fails otherwise
312f438a143SAllan Jude    doit gpart bootcode -b ${dst}/boot/mbr ${dev}
313f438a143SAllan Jude    dd if=${dst}/boot/zfsboot of=/tmp/zfsboot1 count=1
314f438a143SAllan Jude    doit gpart bootcode -b /tmp/zfsboot1 ${dev}s${s}	# Put boot1 into the start of part
315f438a143SAllan Jude    sysctl kern.geom.debugflags=0x10		# Put boot2 into ZFS boot slot
316f438a143SAllan Jude    doit dd if=${dst}/boot/zfsboot of=/dev/${dev}s${s}a skip=1 seek=1024
317f438a143SAllan Jude    sysctl kern.geom.debugflags=0x0
318f438a143SAllan Jude}
319f438a143SAllan Jude
320f438a143SAllan Judeboot_nogeli_mbr_zfs_uefi() {
321394641cfSIan Lepore    make_esp_mbr $1 $2
322f438a143SAllan Jude}
323f438a143SAllan Jude
324f438a143SAllan Judeboot_nogeli_mbr_zfs_both() {
325f438a143SAllan Jude    boot_nogeli_mbr_zfs_legacy $1 $2 $3
326f438a143SAllan Jude    boot_nogeli_mbr_zfs_uefi $1 $2 $3
327f438a143SAllan Jude}
328f438a143SAllan Jude
329f438a143SAllan Judeboot_geli_gpt_ufs_legacy() {
330f438a143SAllan Jude    boot_nogeli_gpt_ufs_legacy $1 $2 $3
331f438a143SAllan Jude}
332f438a143SAllan Jude
333f438a143SAllan Judeboot_geli_gpt_ufs_uefi() {
334f438a143SAllan Jude    boot_nogeli_gpt_ufs_uefi $1 $2 $3
335f438a143SAllan Jude}
336f438a143SAllan Jude
337f438a143SAllan Judeboot_geli_gpt_ufs_both() {
338f438a143SAllan Jude    boot_nogeli_gpt_ufs_both $1 $2 $3
339f438a143SAllan Jude}
340f438a143SAllan Jude
341f438a143SAllan Judeboot_geli_gpt_zfs_legacy() {
342f438a143SAllan Jude    boot_nogeli_gpt_zfs_legacy $1 $2 $3
343f438a143SAllan Jude}
344f438a143SAllan Jude
345f438a143SAllan Judeboot_geli_gpt_zfs_uefi() {
346f438a143SAllan Jude    boot_nogeli_gpt_zfs_uefi $1 $2 $3
347f438a143SAllan Jude}
348f438a143SAllan Jude
349f438a143SAllan Judeboot_geli_gpt_zfs_both() {
350f438a143SAllan Jude    boot_nogeli_gpt_zfs_both $1 $2 $3
351f438a143SAllan Jude}
352f438a143SAllan Jude
353f438a143SAllan Jude# GELI+MBR is not a valid configuration
354f438a143SAllan Judeboot_geli_mbr_ufs_legacy() {
355f438a143SAllan Jude    exit 1
356f438a143SAllan Jude}
357f438a143SAllan Jude
358f438a143SAllan Judeboot_geli_mbr_ufs_uefi() {
359f438a143SAllan Jude    exit 1
360f438a143SAllan Jude}
361f438a143SAllan Jude
362f438a143SAllan Judeboot_geli_mbr_ufs_both() {
363f438a143SAllan Jude    exit 1
364f438a143SAllan Jude}
365f438a143SAllan Jude
366f438a143SAllan Judeboot_geli_mbr_zfs_legacy() {
367f438a143SAllan Jude    exit 1
368f438a143SAllan Jude}
369f438a143SAllan Jude
370f438a143SAllan Judeboot_geli_mbr_zfs_uefi() {
371f438a143SAllan Jude    exit 1
372f438a143SAllan Jude}
373f438a143SAllan Jude
374f438a143SAllan Judeboot_geli_mbr_zfs_both() {
375f438a143SAllan Jude    exit 1
376cfc94828SWarner Losh}
377cfc94828SWarner Losh
378db8b5613SRebecca Cranusage() {
379db8b5613SRebecca Cran	printf 'Usage: %s -b bios [-d destdir] -f fs [-g geli] [-h] [-o optargs] -s scheme <bootdev>\n' "$0"
380db8b5613SRebecca Cran	printf 'Options:\n'
381db8b5613SRebecca Cran	printf ' bootdev       device to install the boot code on\n'
382db8b5613SRebecca Cran	printf ' -b bios       bios type: legacy, uefi or both\n'
383db8b5613SRebecca Cran	printf ' -d destdir    destination filesystem root\n'
384db8b5613SRebecca Cran	printf ' -f fs         filesystem type: ufs or zfs\n'
385db8b5613SRebecca Cran	printf ' -g geli       yes or no\n'
386db8b5613SRebecca Cran	printf ' -h            this help/usage text\n'
3870661cd79SRebecca Cran	printf ' -u            Run commands such as efibootmgr to update the\n'
3880661cd79SRebecca Cran	printf '               currently running system\n'
389db8b5613SRebecca Cran	printf ' -o optargs    optional arguments\n'
390db8b5613SRebecca Cran	printf ' -s scheme     mbr or gpt\n'
391db8b5613SRebecca Cran	exit 0
392db8b5613SRebecca Cran}
393db8b5613SRebecca Cran
394db8b5613SRebecca Cransrcroot=/
395cfc94828SWarner Losh
396cfc94828SWarner Losh# Note: we really don't support geli boot in this script yet.
397cfc94828SWarner Loshgeli=nogeli
398cfc94828SWarner Losh
3990661cd79SRebecca Cranwhile getopts "b:d:f:g:ho:s:u" opt; do
400cfc94828SWarner Losh    case "$opt" in
401cfc94828SWarner Losh	b)
402cfc94828SWarner Losh	    bios=${OPTARG}
403cfc94828SWarner Losh	    ;;
404cfc94828SWarner Losh	d)
405db8b5613SRebecca Cran	    srcroot=${OPTARG}
406cfc94828SWarner Losh	    ;;
407cfc94828SWarner Losh	f)
408cfc94828SWarner Losh	    fs=${OPTARG}
409cfc94828SWarner Losh	    ;;
410cfc94828SWarner Losh	g)
411cfc94828SWarner Losh	    case ${OPTARG} in
412cfc94828SWarner Losh		[Yy][Ee][Ss]|geli) geli=geli ;;
413cfc94828SWarner Losh		*) geli=nogeli ;;
414cfc94828SWarner Losh	    esac
415cfc94828SWarner Losh	    ;;
4160661cd79SRebecca Cran	u)
4170661cd79SRebecca Cran	    updatesystem=1
4180661cd79SRebecca Cran	    ;;
419cfc94828SWarner Losh	o)
420cfc94828SWarner Losh	    opts=${OPTARG}
421cfc94828SWarner Losh	    ;;
422cfc94828SWarner Losh	s)
423cfc94828SWarner Losh	    scheme=${OPTARG}
424cfc94828SWarner Losh	    ;;
425db8b5613SRebecca Cran
426db8b5613SRebecca Cran	?|h)
427db8b5613SRebecca Cran            usage
428db8b5613SRebecca Cran            ;;
429cfc94828SWarner Losh    esac
430cfc94828SWarner Loshdone
431cfc94828SWarner Losh
432db8b5613SRebecca Cranif [ -n "${scheme}" ] && [ -n "${fs}" ] && [ -n "${bios}" ]; then
433cfc94828SWarner Losh    shift $((OPTIND-1))
434cfc94828SWarner Losh    dev=$1
435db8b5613SRebecca Cranfi
436cfc94828SWarner Losh
437cfc94828SWarner Losh# For gpt, we need to install pmbr as the primary boot loader
438cfc94828SWarner Losh# it knows about
439db8b5613SRebecca Crangpt0=${srcroot}/boot/pmbr
440db8b5613SRebecca Crangpt2=${srcroot}/boot/gptboot
441db8b5613SRebecca Crangptzfs2=${srcroot}/boot/gptzfsboot
442cfc94828SWarner Losh
443f438a143SAllan Jude# For MBR, we have lots of choices, but select mbr, boot0 has issues with UEFI
444db8b5613SRebecca Cranmbr0=${srcroot}/boot/mbr
445db8b5613SRebecca Cranmbr2=${srcroot}/boot/boot
446cfc94828SWarner Losh
447cfc94828SWarner Losh# sanity check here
448cfc94828SWarner Losh
449db8b5613SRebecca Cran# Check if we've been given arguments. If not, this script is probably being
450db8b5613SRebecca Cran# sourced, so we shouldn't run anything.
451db8b5613SRebecca Cranif [ -n "${dev}" ]; then
452db8b5613SRebecca Cran	eval boot_${geli}_${scheme}_${fs}_${bios} $dev $srcroot $opts || echo "Unsupported boot env: ${geli}-${scheme}-${fs}-${bios}"
453db8b5613SRebecca Cranfi
454