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