xref: /freebsd/tools/boot/install-boot.sh (revision 780fb4a2fa9a9aee5ac48a60b790f567c0dc13e9)
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