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