xref: /freebsd/tools/boot/rootgen.sh (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
1#!/bin/sh
2
3passphrase=passphrase
4iterations=50000
5
6# The smallest FAT32 filesystem is 33292 KB
7espsize=33292
8
9#
10# Builds all the bat-shit crazy combinations we support booting from,
11# at least for amd64. It assume you have a ~sane kernel in /boot/kernel
12# and copies that into the ~150MB root images we create (we create the du
13# size of the kernel + 20MB).
14#
15# Sad panda sez: this runs as root, but could be any user if someone
16# creates userland geli.
17#
18# This assumes an external program install-boot.sh which will install
19# the appropriate boot files in the appropriate locations.
20#
21# Assumes you've already rebuilt... maybe bad? Also maybe bad: the env
22# vars should likely be conditionally set to allow better automation.
23#
24
25. $(dirname $0)/install-boot.sh
26
27cpsys() {
28    src=$1
29    dst=$2
30
31    # Copy kernel + boot loader
32    (cd $src ; tar cf - .) | (cd $dst; tar xf -)
33}
34
35ufs_fstab() {
36    dir=$1
37
38    cat > ${dir}/etc/fstab <<EOF
39/dev/ufs/root	/		ufs	rw	1	1
40EOF
41}
42
43mk_nogeli_gpt_ufs_legacy() {
44    src=$1
45    img=$2
46
47    ufs_fstab ${src}
48    makefs -t ffs -B little -s 200m -o label=root ${img}.p2 ${src}
49    mkimg -s gpt -b ${src}/boot/pmbr \
50	  -p freebsd-boot:=${src}/boot/gptboot \
51	  -p freebsd-ufs:=${img}.p2 -o ${img}
52    rm -f ${src}/etc/fstab
53}
54
55mk_nogeli_gpt_ufs_uefi() {
56    src=$1
57    img=$2
58
59    ufs_fstab ${src}
60    make_esp_file ${img}.p1 ${espsize} ${src}/boot/loader.efi
61    makefs -t ffs -B little -s 200m -o label=root ${img}.p2 ${src}
62    mkimg -s gpt \
63	  -p efi:=${img}.p1 \
64	  -p freebsd-ufs:=${img}.p2 -o ${img}
65    rm -f ${src}/etc/fstab
66}
67
68mk_nogeli_gpt_ufs_both() {
69    src=$1
70    img=$2
71
72    ufs_fstab ${src}
73    make_esp_file ${img}.p1 ${espsize} ${src}/boot/loader.efi
74    makefs -t ffs -B little -s 200m -o label=root ${img}.p3 ${src}
75    # p1 is boot for uefi, p2 is boot for gpt, p3 is /
76    mkimg -b ${src}/boot/pmbr -s gpt \
77	  -p efi:=${img}.p1 \
78	  -p freebsd-boot:=${src}/boot/gptboot \
79	  -p freebsd-ufs:=${img}.p3 \
80	  -o ${img}
81    rm -f ${src}/etc/fstab
82}
83
84# XXX should not assume host == target
85zfs_extra()
86{
87    src=$1
88    dst=$2
89
90    mkdir -p $dst
91    mkdir -p $dst/boot/kernel
92    cat > ${dst}/boot/loader.conf.local <<EOF
93cryptodev_load=YES
94zfs_load=YES
95EOF
96    cp /boot/kernel/acl_nfs4.ko ${dst}/boot/kernel/acl_nfs4.ko
97    cp /boot/kernel/cryptodev.ko ${dst}/boot/kernel/cryptodev.ko
98    cp /boot/kernel/zfs.ko ${dst}/boot/kernel/zfs.ko
99}
100
101mk_nogeli_gpt_zfs_legacy() {
102    src=$1
103    img=$2
104    mntpt=$3
105    geli=$4
106    scheme=$5
107    fs=$6
108    bios=$7
109    pool=nogeli-gpt-zfs-legacy
110    dst=$img.extra
111
112    zfs_extra $src $dst
113    makefs -t zfs -s 200m \
114	-o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \
115	${img}.p2 ${src} ${dst}
116    mkimg -b ${src}/boot/pmbr -s gpt \
117	  -p freebsd-boot:=/boot/gptzfsboot \
118	  -p freebsd-zfs:=${img}.p2 \
119	  -o ${img}
120    rm -rf ${dst}
121}
122
123mk_nogeli_gpt_zfs_uefi() {
124    src=$1
125    img=$2
126    mntpt=$3
127    geli=$4
128    scheme=$5
129    fs=$6
130    bios=$7
131    pool=nogeli-gpt-zfs-uefi
132    dst=$img.extra
133
134    zfs_extra $src $dst
135    make_esp_file ${img}.p1 ${espsize} ${src}/boot/loader.efi
136    makefs -t zfs -s 200m \
137	-o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \
138	${img}.p2 ${src} ${dst}
139    mkimg -b ${src}/boot/pmbr -s gpt \
140	  -p efi:=${img}.p1 \
141	  -p freebsd-zfs:=${img}.p2 \
142	  -o ${img}
143    rm -rf ${dst}
144}
145
146mk_nogeli_gpt_zfs_both() {
147    src=$1
148    img=$2
149    mntpt=$3
150    geli=$4
151    scheme=$5
152    fs=$6
153    bios=$7
154    pool=nogeli-gpt-zfs-both
155    dst=$img.extra
156
157    zfs_extra $src $dst
158    make_esp_file ${img}.p2 ${espsize} ${src}/boot/loader.efi
159    makefs -t zfs -s 200m \
160	-o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \
161	${img}.p3 ${src} ${dst}
162    mkimg -b ${src}/boot/pmbr -s gpt \
163	  -p freebsd-boot:=/boot/gptzfsboot \
164	  -p efi:=${img}.p2 \
165	  -p freebsd-zfs:=${img}.p3 \
166	  -o ${img}
167    rm -rf ${dst}
168}
169
170mk_nogeli_mbr_ufs_legacy() {
171    src=$1
172    img=$2
173
174    ufs_fstab ${src}
175    makefs -t ffs -B little -s 200m -o label=root ${img}.s1a ${src}
176    mkimg -s bsd -b ${src}/boot/boot -p freebsd-ufs:=${img}.s1a -o ${img}.s1
177    mkimg -a 1 -s mbr -b ${src}/boot/boot0sio -p freebsd:=${img}.s1 -o ${img}
178    rm -f ${src}/etc/fstab
179}
180
181mk_nogeli_mbr_ufs_uefi() {
182    src=$1
183    img=$2
184
185    ufs_fstab ${src}
186    make_esp_file ${img}.s1 ${espsize} ${src}/boot/loader.efi
187    makefs -t ffs -B little -s 200m -o label=root ${img}.s2a ${src}
188    mkimg -s bsd -p freebsd-ufs:=${img}.s2a -o ${img}.s2
189    mkimg -a 1 -s mbr -p efi:=${img}.s1 -p freebsd:=${img}.s2 -o ${img}
190    rm -f ${src}/etc/fstab
191}
192
193mk_nogeli_mbr_ufs_both() {
194    src=$1
195    img=$2
196
197    ufs_fstab ${src}
198    make_esp_file ${img}.s1 ${espsize} ${src}/boot/loader.efi
199    makefs -t ffs -B little -s 200m -o label=root ${img}.s2a ${src}
200    mkimg -s bsd -b ${src}/boot/boot -p freebsd-ufs:=${img}.s2a -o ${img}.s2
201    mkimg -a 2 -s mbr -b ${src}/boot/mbr -p efi:=${img}.s1 -p freebsd:=${img}.s2 -o ${img}
202    rm -f ${src}/etc/fstab
203}
204
205mk_nogeli_mbr_zfs_legacy() {
206    src=$1
207    img=$2
208    mntpt=$3
209    geli=$4
210    scheme=$5
211    fs=$6
212    bios=$7
213    pool=nogeli-mbr-zfs-legacy
214
215    zfs_extra $src $dst
216    makefs -t zfs -s 200m \
217	-o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \
218	${img}.s1a ${src} ${dst}
219    # The old boot1/boot2 boot split is also used by zfs. We need to extract zfsboot1
220    # from this image. Since there's no room in the mbr format for the rest of the loader,
221    # it will load the zfsboot loader from the reserved for bootloader area of the ZFS volume
222    # being booted, hence the need to dd it into the raw img later.
223    # Please note: zfsboot only works with partition 'a' which must be the root
224    # partition / zfs volume
225    dd if=${src}/boot/zfsboot of=${dst}/zfsboot1 count=1
226    mkimg -s bsd -b ${dst}zfsboot1 -p freebsd-zfs:=${img}.s1a -o ${img}.s1
227    dd if=${src}/boot/zfsboot of=${img}.s1a skip=1 seek=1024
228    mkimg -a 1 -s mbr -b ${src}/boot/mbr -p freebsd:=${img}.s1 -o ${img}
229    rm -rf ${dst}
230}
231
232mk_nogeli_mbr_zfs_uefi() {
233    src=$1
234    img=$2
235    mntpt=$3
236    geli=$4
237    scheme=$5
238    fs=$6
239    bios=$7
240    pool=nogeli-mbr-zfs-uefi
241
242    zfs_extra $src $dst
243    make_esp_file ${img}.s1 ${espsize} ${src}/boot/loader.efi
244    makefs -t zfs -s 200m \
245	-o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \
246	${img}.s2a ${src} ${dst}
247    mkimg -s bsd -b ${dst}zfsboot1 -p freebsd-zfs:=${img}.s2a -o ${img}.s2
248    mkimg -a 1 -s mbr -b ${src}/boot/mbr -p efi:=${img}.s1 -p freebsd:=${img}.s2 -o ${img}
249    rm -rf ${dst}
250}
251
252mk_nogeli_mbr_zfs_both() {
253    src=$1
254    img=$2
255    mntpt=$3
256    geli=$4
257    scheme=$5
258    fs=$6
259    bios=$7
260    pool=nogeli-mbr-zfs-both
261
262    zfs_extra $src $dst
263    make_esp_file ${img}.s1 ${espsize} ${src}/boot/loader.efi
264    makefs -t zfs -s 200m \
265	-o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \
266	${img}.s2a ${src} ${dst}
267    # The old boot1/boot2 boot split is also used by zfs. We need to extract zfsboot1
268    # from this image. Since there's no room in the mbr format for the rest of the loader,
269    # it will load the zfsboot loader from the reserved for bootloader area of the ZFS volume
270    # being booted, hence the need to dd it into the raw img later.
271    # Please note: zfsboot only works with partition 'a' which must be the root
272    # partition / zfs volume
273    dd if=${src}/boot/zfsboot of=${dst}/zfsboot1 count=1
274    mkimg -s bsd -b ${dst}zfsboot1 -p freebsd-zfs:=${img}.s2a -o ${img}.s2
275    dd if=${src}/boot/zfsboot of=${img}.s1a skip=1 seek=1024
276    mkimg -a 1 -s mbr -b ${src}/boot/mbr -p efi:=${img}.s1 -p freebsd:=${img}.s2 -o ${img}
277}
278
279mk_geli_gpt_ufs_legacy() {
280    src=$1
281    img=$2
282    mntpt=$3
283    geli=$4
284    scheme=$5
285    fs=$6
286    bios=$7
287
288    dd if=/dev/zero of=${img} count=1 seek=$(( 200 * 1024 * 1024 / 512 ))
289    md=$(mdconfig -f ${img})
290    gpart create -s gpt ${md}
291    gpart add -t freebsd-boot -s 400k -a 4k	${md}	# <= ~540k
292    gpart add -t freebsd-ufs -l root $md
293    # install-boot will make this bootable
294    echo ${passphrase} | geli init -bg -e AES-XTS -i ${iterations} -J - -l 256 -s 4096 ${md}p2
295    echo ${passphrase} | geli attach -j - ${md}p2
296    newfs -L root /dev/${md}p2.eli
297    mount /dev/${md}p2.eli ${mntpt}
298    cpsys ${src} ${mntpt}
299    # need to make a couple of tweaks
300    cat > ${mntpt}/boot/loader.conf <<EOF
301geom_eli_load=YES
302EOF
303    ufs_fstab ${mntpt}
304
305    cp /boot/kernel/geom_eli.ko ${mntpt}/boot/kernel/geom_eli.ko
306    # end tweaks
307    umount -f ${mntpt}
308    geli detach ${md}p2
309    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
310    mdconfig -d -u ${md}
311}
312
313mk_geli_gpt_ufs_uefi() {
314    src=$1
315    img=$2
316    mntpt=$3
317    geli=$4
318    scheme=$5
319    fs=$6
320    bios=$7
321
322    dd if=/dev/zero of=${img} count=1 seek=$(( 200 * 1024 * 1024 / 512 ))
323    md=$(mdconfig -f ${img})
324    gpart create -s gpt ${md}
325    gpart add -t efi -s ${espsize}k -a 4k ${md}
326    gpart add -t freebsd-ufs -l root $md
327    # install-boot will make this bootable
328    echo ${passphrase} | geli init -bg -e AES-XTS -i ${iterations} -J - -l 256 -s 4096 ${md}p2
329    echo ${passphrase} | geli attach -j - ${md}p2
330    newfs -L root /dev/${md}p2.eli
331    mount /dev/${md}p2.eli ${mntpt}
332    cpsys ${src} ${mntpt}
333    # need to make a couple of tweaks
334    cat > ${mntpt}/boot/loader.conf <<EOF
335geom_eli_load=YES
336EOF
337    ufs_fstab ${mntpt}
338
339    cp /boot/kernel/geom_eli.ko ${mntpt}/boot/kernel/geom_eli.ko
340    # end tweaks
341    umount -f ${mntpt}
342    geli detach ${md}p2
343    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
344    mdconfig -d -u ${md}
345}
346
347mk_geli_gpt_ufs_both() {
348    src=$1
349    img=$2
350    mntpt=$3
351    geli=$4
352    scheme=$5
353    fs=$6
354    bios=$7
355
356    dd if=/dev/zero of=${img} count=1 seek=$(( 200 * 1024 * 1024 / 512 ))
357    md=$(mdconfig -f ${img})
358    gpart create -s gpt ${md}
359    gpart add -t efi -s ${espsize}k -a 4k ${md}
360    gpart add -t freebsd-boot -s 400k -a 4k	${md}	# <= ~540k
361    gpart add -t freebsd-ufs -l root $md
362    # install-boot will make this bootable
363    echo ${passphrase} | geli init -bg -e AES-XTS -i ${iterations} -J - -l 256 -s 4096 ${md}p3
364    echo ${passphrase} | geli attach -j - ${md}p3
365    newfs -L root /dev/${md}p3.eli
366    mount /dev/${md}p3.eli ${mntpt}
367    cpsys ${src} ${mntpt}
368    # need to make a couple of tweaks
369    cat > ${mntpt}/boot/loader.conf <<EOF
370geom_eli_load=YES
371EOF
372    ufs_fstab ${mntpt}
373
374    cp /boot/kernel/geom_eli.ko ${mntpt}/boot/kernel/geom_eli.ko
375    # end tweaks
376    umount -f ${mntpt}
377    geli detach ${md}p3
378    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
379    mdconfig -d -u ${md}
380}
381
382mk_geli_gpt_zfs_legacy() {
383    src=$1
384    img=$2
385    mntpt=$3
386    geli=$4
387    scheme=$5
388    fs=$6
389    bios=$7
390    pool=geli-gpt-zfs-legacy
391
392    # Note that in this flavor we create an empty p2 ufs partition, and put
393    # the bootable zfs stuff on p3, just to test the ability of the zfs probe
394    # probe routines to find a pool on a partition other than the first one.
395
396    dd if=/dev/zero of=${img} count=1 seek=$(( 300 * 1024 * 1024 / 512 ))
397    md=$(mdconfig -f ${img})
398    gpart create -s gpt ${md}
399    gpart add -t freebsd-boot -s 400k -a 4k	${md}	# <= ~540k
400    gpart add -t freebsd-ufs -s 100m ${md}
401    gpart add -t freebsd-zfs -l root $md
402    # install-boot will make this bootable
403    echo ${passphrase} | geli init -bg -e AES-XTS -i ${iterations} -J - -l 256 -s 4096 ${md}p3
404    echo ${passphrase} | geli attach -j - ${md}p3
405    zpool create -O mountpoint=none -R ${mntpt} ${pool} ${md}p3.eli
406    zpool set bootfs=${pool} ${pool}
407    zfs create -po mountpoint=/ ${pool}/ROOT/default
408    # NB: The online guides go nuts customizing /var and other mountpoints here, no need
409    cpsys ${src} ${mntpt}
410    # need to make a couple of tweaks
411    cat >> ${mntpt}/boot/loader.conf <<EOF
412cryptodev_load=YES
413zfs_load=YES
414geom_eli_load=YES
415EOF
416    cp /boot/kernel/acl_nfs4.ko ${mntpt}/boot/kernel/acl_nfs4.ko
417    cp /boot/kernel/cryptodev.ko ${mntpt}/boot/kernel/cryptodev.ko
418    cp /boot/kernel/zfs.ko ${mntpt}/boot/kernel/zfs.ko
419    cp /boot/kernel/geom_eli.ko ${mntpt}/boot/kernel/geom_eli.ko
420    # end tweaks
421    zfs umount -f ${pool}/ROOT/default
422    zfs set mountpoint=none ${pool}/ROOT/default
423    zpool set bootfs=${pool}/ROOT/default ${pool}
424    zpool set autoexpand=on ${pool}
425    zpool export ${pool}
426    geli detach ${md}p3
427    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
428    mdconfig -d -u ${md}
429}
430
431mk_geli_gpt_zfs_uefi() {
432    src=$1
433    img=$2
434    mntpt=$3
435    geli=$4
436    scheme=$5
437    fs=$6
438    bios=$7
439    pool=geli-gpt-zfs-uefi
440
441    # Note that in this flavor we create an empty p2 ufs partition, and put
442    # the bootable zfs stuff on p3, just to test the ability of the zfs probe
443    # probe routines to find a pool on a partition other than the first one.
444
445    dd if=/dev/zero of=${img} count=1 seek=$(( 300 * 1024 * 1024 / 512 ))
446    md=$(mdconfig -f ${img})
447    gpart create -s gpt ${md}
448    gpart add -t efi -s ${espsize}k -a 4k ${md}
449    gpart add -t freebsd-ufs -s 100m ${md}
450    gpart add -t freebsd-zfs -l root $md
451    # install-boot will make this bootable
452    echo ${passphrase} | geli init -bg -e AES-XTS -i ${iterations} -J - -l 256 -s 4096 ${md}p3
453    echo ${passphrase} | geli attach -j - ${md}p3
454    zpool create -O mountpoint=none -R ${mntpt} ${pool} ${md}p3.eli
455    zpool set bootfs=${pool} ${pool}
456    zfs create -po mountpoint=/ ${pool}/ROOT/default
457    # NB: The online guides go nuts customizing /var and other mountpoints here, no need
458    cpsys ${src} ${mntpt}
459    # need to make a couple of tweaks
460    cat >> ${mntpt}/boot/loader.conf <<EOF
461cryptodev_load=YES
462zfs_load=YES
463geom_eli_load=YES
464EOF
465    cp /boot/kernel/acl_nfs4.ko ${mntpt}/boot/kernel/acl_nfs4.ko
466    cp /boot/kernel/cryptodev.ko ${mntpt}/boot/kernel/cryptodev.ko
467    cp /boot/kernel/zfs.ko ${mntpt}/boot/kernel/zfs.ko
468    cp /boot/kernel/geom_eli.ko ${mntpt}/boot/kernel/geom_eli.ko
469    # end tweaks
470    zfs umount -f ${pool}/ROOT/default
471    zfs set mountpoint=none ${pool}/ROOT/default
472    zpool set bootfs=${pool}/ROOT/default ${pool}
473    zpool set autoexpand=on ${pool}
474    zpool export ${pool}
475    geli detach ${md}p3
476    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
477    mdconfig -d -u ${md}
478}
479
480mk_geli_gpt_zfs_both() {
481    src=$1
482    img=$2
483    mntpt=$3
484    geli=$4
485    scheme=$5
486    fs=$6
487    bios=$7
488    pool=geli-gpt-zfs-both
489
490    dd if=/dev/zero of=${img} count=1 seek=$(( 200 * 1024 * 1024 / 512 ))
491    md=$(mdconfig -f ${img})
492    gpart create -s gpt ${md}
493    gpart add -t efi -s ${espsize}k -a 4k ${md}
494    gpart add -t freebsd-boot -s 400k -a 4k	${md}	# <= ~540k
495    gpart add -t freebsd-zfs -l root $md
496    # install-boot will make this bootable
497    echo ${passphrase} | geli init -bg -e AES-XTS -i ${iterations} -J - -l 256 -s 4096 ${md}p3
498    echo ${passphrase} | geli attach -j - ${md}p3
499    zpool create -O mountpoint=none -R ${mntpt} ${pool} ${md}p3.eli
500    zpool set bootfs=${pool} ${pool}
501    zfs create -po mountpoint=/ ${pool}/ROOT/default
502    # NB: The online guides go nuts customizing /var and other mountpoints here, no need
503    cpsys ${src} ${mntpt}
504    # need to make a couple of tweaks
505    cat > ${mntpt}/boot/loader.conf <<EOF
506cryptodev_load=YES
507zfs_load=YES
508geom_eli_load=YES
509EOF
510    cp /boot/kernel/acl_nfs4.ko ${mntpt}/boot/kernel/acl_nfs4.ko
511    cp /boot/kernel/cryptodev.ko ${mntpt}/boot/kernel/cryptodev.ko
512    cp /boot/kernel/zfs.ko ${mntpt}/boot/kernel/zfs.ko
513    cp /boot/kernel/geom_eli.ko ${mntpt}/boot/kernel/geom_eli.ko
514    # end tweaks
515    zfs umount -f ${pool}/ROOT/default
516    zfs set mountpoint=none ${pool}/ROOT/default
517    zpool set bootfs=${pool}/ROOT/default ${pool}
518    zpool set autoexpand=on ${pool}
519    zpool export ${pool}
520    geli detach ${md}p3
521    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
522    mdconfig -d -u ${md}
523}
524
525# GELI+MBR is not a valid configuration
526mk_geli_mbr_ufs_legacy() {
527}
528
529mk_geli_mbr_ufs_uefi() {
530}
531
532mk_geli_mbr_ufs_both() {
533}
534
535mk_geli_mbr_zfs_legacy() {
536}
537
538mk_geli_mbr_zfs_uefi() {
539}
540
541mk_geli_mbr_zfs_both() {
542}
543
544# iso
545# pxeldr
546# u-boot
547# powerpc
548
549qser="-monitor telnet::4444,server,nowait -serial stdio -nographic"
550
551# https://wiki.freebsd.org/QemuRecipes
552# aarch64
553qemu_aarch64_uefi()
554{
555    img=$1
556    sh=$2
557
558    echo "qemu-system-aarch64 -m 4096M -cpu cortex-a57 -M virt  \
559        -bios QEMU_EFI.fd ${qser} \
560        -drive if=none,file=${img},id=hd0 \
561        -device virtio-blk-device,drive=hd0" > $sh
562    chmod 755 $sh
563# https://wiki.freebsd.org/arm64/QEMU also has
564#       -device virtio-net-device,netdev=net0
565#       -netdev user,id=net0
566}
567
568log_for()
569{
570    dir=$(dirname $1)
571    fn=$(basename $1 .sh)
572    echo $dir/$fn.log
573}
574
575# Amd64 qemu
576qemu_amd64_legacy()
577{
578    img=$1
579    sh=$2
580    log=$(log_for $2)
581
582    echo "echo -n $(basename $sh .sh):' '" > $sh
583    echo "(qemu-system-x86_64 -m 256m --drive file=${img},format=raw ${qser} | tee $log 2>&1 | grep -q SUCCESS) && echo legacy pass || echo legacy fail" >> $sh
584    chmod 755 $sh
585}
586
587qemu_amd64_uefi()
588{
589    img=$1
590    sh=$2
591    log=$(log_for $2)
592
593    echo "echo -n $(basename $sh .sh):' '" > $sh
594    echo "(qemu-system-x86_64 -m 256m -bios ~/bios/OVMF-X64.fd --drive file=${img},format=raw ${qser} | tee $log 2>&1 | grep -q SUCCESS) && echo uefi pass || echo uefi fail" >> $sh
595    chmod 755 $sh
596}
597
598qemu_amd64_both()
599{
600    img=$1
601    sh=$2
602    log=$(log_for $2)
603
604    echo "echo -n $(basename $sh .sh):' '" > $sh
605    echo "(qemu-system-x86_64 -m 256m --drive file=${img},format=raw ${qser} | tee $log 2>&1 | grep -q SUCCESS) && echo legacy pass || echo legacy fail" >> $sh
606    echo "echo -n $(basename $sh .sh):' '" >> $sh
607    echo "(qemu-system-x86_64 -m 256m -bios ~/bios/OVMF-X64.fd --drive file=${img},format=raw ${qser} | tee -a $log 2>&1 | grep -q SUCCESS) && echo uefi pass || echo uefi fail" >> $sh
608    chmod 755 $sh
609}
610
611# arm
612# nothing listed?
613
614# i386
615qemu_i386_legacy()
616{
617    img=$1
618    sh=$2
619
620    echo "qemu-system-i386 --drive file=${img},format=raw ${qser}" > $sh
621    chmod 755 $sh
622}
623
624# Not yet supported
625qemu_i386_uefi()
626{
627    img=$1
628    sh=$2
629
630    echo "qemu-system-i386 -bios ~/bios/OVMF-X32.fd --drive file=${img},format=raw ${qser}" > $sh
631    chmod 755 $sh
632}
633
634# Needs UEFI to be supported
635qemu_i386_both()
636{
637    img=$1
638    sh=$2
639
640    echo "qemu-system-i386 --drive file=${img},format=raw ${qser}" > $sh
641    echo "qemu-system-i386 -bios ~/bios/OVMF-X32.fd --drive file=${img},format=raw ${qser}" >> $sh
642    chmod 755 $sh
643}
644
645make_one_image()
646{
647    local arch=${1?}
648    local geli=${2?}
649    local scheme=${3?}
650    local fs=${4?}
651    local bios=${5?}
652
653    # Create sparse file and mount newly created filesystem(s) on it
654    img=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.img
655    sh=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.sh
656    echo "$sh" >> ${IMGDIR}/all.sh
657    echo date >> ${IMGDIR}/all.sh
658    echo "vvvvvvvvvvvvvv   Creating $img  vvvvvvvvvvvvvvv"
659    rm -f ${img}*
660    eval mk_${geli}_${scheme}_${fs}_${bios} ${DESTDIR} ${img} ${MNTPT} ${geli} ${scheme} ${fs} ${bios}
661    eval qemu_${arch}_${bios} ${img} ${sh}
662    [ -n "${SUDO_USER}" ] && chown ${SUDO_USER} ${img}*
663    echo "^^^^^^^^^^^^^^   Created $img   ^^^^^^^^^^^^^^^"
664}
665
666# Powerpc -- doesn't work but maybe it would enough for testing -- needs details
667# powerpc64
668# qemu-system-ppc64 -drive file=/path/to/disk.img,format=raw
669
670# Misc variables
671SRCTOP=$(make -v SRCTOP)
672cd ${SRCTOP}/stand
673OBJDIR=$(make -v .OBJDIR)
674IMGDIR=${OBJDIR}/boot-images
675mkdir -p ${IMGDIR}
676MNTPT=$(mktemp -d /tmp/stand-test.XXXXXX)
677
678# Setup the installed tree...
679DESTDIR=${OBJDIR}/boot-tree
680rm -rf ${DESTDIR}
681mkdir -p ${DESTDIR}/boot/defaults
682mkdir -p ${DESTDIR}/boot/kernel
683cp /boot/kernel/kernel ${DESTDIR}/boot/kernel
684echo -h -D -S115200 > ${DESTDIR}/boot.config
685cat > ${DESTDIR}/boot/loader.conf <<EOF
686comconsole_speed=115200
687autoboot_delay=0
688EOF
689# XXX
690cp /boot/device.hints ${DESTDIR}/boot/device.hints
691# Assume we're already built
692make install DESTDIR=${DESTDIR} MK_MAN=no MK_INSTALL_AS_USER=yes WITHOUT_DEBUG_FILES=yes
693if [ $? -ne 0 ]; then
694        echo "make install failed"
695        exit 1
696fi
697# Copy init, /bin/sh, minimal libraries and testing /etc/rc
698mkdir -p ${DESTDIR}/sbin ${DESTDIR}/bin \
699      ${DESTDIR}/lib ${DESTDIR}/libexec \
700      ${DESTDIR}/etc ${DESTDIR}/dev
701for f in /sbin/halt /sbin/init /bin/sh /sbin/sysctl $(ldd /bin/sh | awk 'NF == 4 { print $3; }') /libexec/ld-elf.so.1; do
702    cp $f ${DESTDIR}/$f
703done
704cat > ${DESTDIR}/etc/rc <<EOF
705#!/bin/sh
706
707sysctl machdep.bootmethod
708echo "RC COMMAND RUNNING -- SUCCESS!!!!!"
709halt -p
710EOF
711
712# If we were given exactly 5 args, go make that one image.
713
714rm -f ${IMGDIR}/all.sh
715echo date > ${IMGDIR}/all.sh
716chmod +x  ${IMGDIR}/all.sh
717
718if [ $# -eq 5 ]; then
719    make_one_image $*
720    echo ${IMGDIR}/all.sh
721    exit
722fi
723
724# OK. Let the games begin
725
726for arch in amd64; do
727    for geli in nogeli; do # geli
728	for scheme in gpt mbr; do
729	    for fs in ufs zfs; do
730		for bios in legacy uefi both; do
731		    make_one_image ${arch} ${geli} ${scheme} ${fs} ${bios}
732		done
733	    done
734	done
735    done
736done
737    # We should also do a cd image for amd64 here
738echo ${IMGDIR}/all.sh
739
740rmdir ${MNTPT}
741
742exit 0
743
744# Notes for the future
745
746for arch in i386; do
747    for geli in nogeli geli; do
748	for scheme in gpt mbr; do
749	    for fs in ufs zfs; do
750		for bios in legacy; do
751		    # The legacy boot is shared with amd64 so those routines could
752		    # likely be used here.
753		    make_one_image ${arch} ${geli} ${scheme} ${fs} ${bios}
754		done
755	    done
756	done
757    done
758done
759    # We should also do a cd image for i386 here
760
761for arch in arm aarch64; do
762    geli=nogeli		# I don't think geli boot works / is supported on arm
763    for scheme in gpt mbr; do
764      for fs in ufs zfs; do
765	bios=efi # Note: arm has some uboot support with ufs, what to do?
766	make_one_image ${arch} ${geli} ${scheme} ${fs} ${bios}
767      done
768    done
769done
770
771# It's not clear that the nested looping paradigm is best for powerpc
772# due to its diversity.
773for arch in powerpc powerpc64 powerpc64le; do
774    geli=nogeli
775    for scheme in apm gpt; do
776	fs=ufs # zfs + gpt might be supported?
777	for bios in ofw uboot chrp; do
778	    make_one_image ${arch} ${geli} ${scheme} ${fs} ${bios}
779	done
780    done
781done
782
783for arch in riscv; do
784    geli=nogeli
785    fs=ufs		# Generic ZFS booting support with efi?
786    scheme=gpt
787    bios=efi
788    make_one_image ${arch} ${geli} ${scheme} ${fs} ${bios}
789done
790