xref: /freebsd/tools/boot/rootgen.sh (revision ecbde90073aef9166e77cecf61bd80c15a707a53)
1#!/bin/sh
2
3# $FreeBSD$
4
5#
6# Builds all the bat-shit crazy combinations we support booting from,
7# at least for amd64. It assume you have a ~sane kernel in /boot/kernel
8# and copies that into the ~150MB root images we create (we create the du
9# size of the kernel + 20MB
10#
11# Sad panda sez: this runs as root, but could be userland if someone
12# creates userland geli and zfs tools.
13#
14# This assumes an external prograam install-boot.sh which will install
15# the appropriate boot files in the appropriate locations.
16#
17# These images assume ada0 will be the root image. We should likely
18# use labels, but we don't.
19#
20# ASsumes you've already rebuilt... maybe bad? Also maybe bad: the env
21# vars should likely be conditionally set to allow better automation.
22#
23
24cpsys() {
25    src=$1
26    dst=$2
27
28    # Copy kernel + boot loader
29    (cd $src ; tar cf - .) | (cd $dst; tar xf -)
30}
31
32mk_nogeli_gpt_ufs_legacy() {
33    src=$1
34    img=$2
35
36    cat > ${src}/etc/fstab <<EOF
37/dev/ada0p2	/		ufs	rw	1	1
38EOF
39    makefs -t ffs -B little -s 200m ${img}.p2 ${src}
40    mkimg -s gpt -b ${src}/boot/pmbr \
41	  -p freebsd-boot:=${src}/boot/gptboot \
42	  -p freebsd-ufs:=${img}.p2 -o ${img}
43    rm -f ${src}/etc/fstab
44}
45
46mk_nogeli_gpt_ufs_uefi() {
47    src=$1
48    img=$2
49
50    cat > ${src}/etc/fstab <<EOF
51/dev/ada0p2	/		ufs	rw	1	1
52EOF
53# XXX need to make msdos part for this to work XXXX
54    cp ${src}/boot/boot.efifat ${img}.p1
55    makefs -t ffs -B little -s 200m ${img}.p2 ${src}
56    mkimg -s gpt -b ${src}/boot/pmbr \
57	  -p efi:=${img}.p1 \
58	  -p freebsd-ufs:=${img}.p2 -o ${img}
59    rm -f ${src}/etc/fstab
60}
61
62mk_nogeli_gpt_ufs_both() {
63    src=$1
64    img=$2
65
66    cat > ${src}/etc/fstab <<EOF
67/dev/ada0p3	/		ufs	rw	1	1
68EOF
69    # XXX need to make msdos part for this to work XXXX
70    cp ${src}/boot/boot.efifat ${img}.p1
71    makefs -t ffs -B little -s 200m ${img}.p3 ${src}
72    # p1 is boot for uefi, p2 is boot for gpt, p3 is /
73    mkimg -b ${src}/boot/pmbr -s gpt \
74	  -p efi:=${src}/boot/boot1.efifat \
75	  -p freebsd-boot:=${src}/boot/gptboot \
76	  -p freebsd-ufs:=${img}.p3 \
77	  -o ${img}
78    rm -f ${src}/etc/fstab
79}
80
81mk_nogeli_gpt_zfs_legacy() {
82    src=$1
83    img=$2
84    mntpt=$3
85    geli=$4
86    scheme=$5
87    fs=$6
88    bios=$7
89    pool=nogeli-gpt-zfs-legacy
90
91    dd if=/dev/zero of=${img} count=1 seek=$((200 * 1024 * 1024 / 512))
92    md=$(mdconfig -f ${img})
93    gpart create -s gpt ${md}
94    gpart add -t freebsd-boot -s 400k -a 4k	${md}	# <= ~540k
95    gpart add -t freebsd-zfs -l root $md
96    # install-boot will make this bootable
97    zpool create -O mountpoint=none -R ${mntpt} ${pool} ${md}p2
98    zpool set bootfs=${pool} ${pool}
99    zfs create -po mountpoint=/ ${pool}/ROOT/default
100    # NB: The online guides go nuts customizing /var and other mountpoints here, no need
101    cpsys ${src} ${mntpt}
102    df
103    # need to make a couple of tweaks
104    cat > ${mntpt}/boot/loader.conf <<EOF
105zfs_load=YES
106opensolaris_load=YES
107EOF
108    cp /boot/kernel/zfs.ko ${mntpt}/boot/kernel/zfs.ko
109    cp /boot/kernel/opensolaris.ko ${mntpt}/boot/kernel/opensolaris.ko
110    ls -las ${mntpt}/boot
111    # end tweaks
112    zfs umount -f ${pool}/ROOT/default
113    zfs set mountpoint=none ${pool}/ROOT/default
114    zpool set bootfs=${pool}/ROOT/default ${pool}
115    zpool set autoexpand=on ${pool}
116    zpool export ${pool}
117    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
118    mdconfig -d -u ${md}
119}
120
121mk_nogeli_gpt_zfs_uefi() {
122    src=$1
123    img=$2
124    mntpt=$3
125    geli=$4
126    scheme=$5
127    fs=$6
128    bios=$7
129    pool=nogeli-gpt-zfs-uefi
130
131    dd if=/dev/zero of=${img} count=1 seek=$((200 * 1024 * 1024 / 512))
132    md=$(mdconfig -f ${img})
133    gpart create -s gpt ${md}
134    gpart add -t efi -s 800k -a 4k ${md}
135    gpart add -t freebsd-zfs -l root $md
136    # install-boot will make this bootable
137    zpool create -O mountpoint=none -R ${mntpt} ${pool} ${md}p2
138    zpool set bootfs=${pool} ${pool}
139    zfs create -po mountpoint=/ ${pool}/ROOT/default
140    # NB: The online guides go nuts customizing /var and other mountpoints here, no need
141    cpsys ${src} ${mntpt}
142    df
143    # need to make a couple of tweaks
144    cat > ${mntpt}/boot/loader.conf <<EOF
145zfs_load=YES
146opensolaris_load=YES
147EOF
148    cp /boot/kernel/zfs.ko ${mntpt}/boot/kernel/zfs.ko
149    cp /boot/kernel/opensolaris.ko ${mntpt}/boot/kernel/opensolaris.ko
150    ls -las ${mntpt}/boot
151    # end tweaks
152    zfs umount -f ${pool}/ROOT/default
153    zfs set mountpoint=none ${pool}/ROOT/default
154    zpool set bootfs=${pool}/ROOT/default ${pool}
155    zpool set autoexpand=on ${pool}
156    zpool export ${pool}
157    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
158    mdconfig -d -u ${md}
159}
160
161mk_nogeli_gpt_zfs_both() {
162    src=$1
163    img=$2
164    mntpt=$3
165    geli=$4
166    scheme=$5
167    fs=$6
168    bios=$7
169    pool=nogeli-gpt-zfs-both
170
171    dd if=/dev/zero of=${img} count=1 seek=$((200 * 1024 * 1024 / 512))
172    md=$(mdconfig -f ${img})
173    gpart create -s gpt ${md}
174    gpart add -t efi -s 800k -a 4k ${md}
175    gpart add -t freebsd-boot -s 400k -a 4k	${md}	# <= ~540k
176    gpart add -t freebsd-zfs -l root $md
177    # install-boot will make this bootable
178    zpool create -O mountpoint=none -R ${mntpt} ${pool} ${md}p3
179    zpool set bootfs=${pool} ${pool}
180    zfs create -po mountpoint=/ ${pool}/ROOT/default
181    # NB: The online guides go nuts customizing /var and other mountpoints here, no need
182    cpsys ${src} ${mntpt}
183    df
184    # need to make a couple of tweaks
185    cat > ${mntpt}/boot/loader.conf <<EOF
186zfs_load=YES
187opensolaris_load=YES
188EOF
189    cp /boot/kernel/zfs.ko ${mntpt}/boot/kernel/zfs.ko
190    cp /boot/kernel/opensolaris.ko ${mntpt}/boot/kernel/opensolaris.ko
191    ls -las ${mntpt}/boot
192    # end tweaks
193    zfs umount -f ${pool}/ROOT/default
194    zfs set mountpoint=none ${pool}/ROOT/default
195    zpool set bootfs=${pool}/ROOT/default ${pool}
196    zpool set autoexpand=on ${pool}
197    zpool export ${pool}
198    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
199    mdconfig -d -u ${md}
200}
201
202mk_nogeli_mbr_ufs_legacy() {
203    src=$1
204    img=$2
205
206    cat > ${src}/etc/fstab <<EOF
207/dev/ada0s1a	/		ufs	rw	1	1
208EOF
209    makefs -t ffs -B little -s 200m ${img}.s1a ${src}
210    mkimg -s bsd -b ${src}/boot/boot -p freebsd-ufs:=${img}.s1a -o ${img}.s1
211    mkimg -a 1 ${bootmbr} -s mbr -b ${src}/boot/boot0sio -p freebsd:=${img}.s1 -o ${img}
212    rm -f ${src}/etc/fstab
213}
214
215mk_nogeli_mbr_ufs_uefi() {
216}
217
218mk_nogeli_mbr_ufs_both() {
219}
220
221mk_nogeli_mbr_zfs_legacy() {
222}
223
224mk_nogeli_mbr_zfs_uefi() {
225}
226
227mk_nogeli_mbr_zfs_both() {
228}
229
230mk_geli_gpt_ufs_legacy() {
231}
232
233mk_geli_gpt_ufs_uefi() {
234}
235
236mk_geli_gpt_ufs_both() {
237}
238
239mk_geli_gpt_zfs_legacy() {
240}
241
242mk_geli_gpt_zfs_uefi() {
243}
244
245mk_geli_gpt_zfs_both() {
246}
247
248mk_geli_mbr_ufs_legacy() {
249}
250
251mk_geli_mbr_ufs_uefi() {
252}
253
254mk_geli_mbr_ufs_both() {
255}
256
257mk_geli_mbr_zfs_legacy() {
258}
259
260mk_geli_mbr_zfs_uefi() {
261}
262
263mk_geli_mbr_zfs_both() {
264}
265
266# iso
267# pxeldr
268# u-boot
269# powerpc
270
271mk_sparc64_nogeli_vtoc8_ufs_ofw() {
272    src=$1
273    img=$2
274    mntpt=$3
275    geli=$4
276    scheme=$5
277    fs=$6
278    bios=$7
279
280    cat > ${src}/etc/fstab <<EOF
281/dev/ada0a	/		ufs	rw	1	1
282EOF
283    makefs -t ffs -B big -s 200m ${img} ${src}
284    md=$(mdconfig -f ${img})
285    # For non-native builds, ensure that geom_part(4) supports VTOC8.
286    kldload geom_part_vtoc8.ko
287    gpart create -s VTOC8 ${md}
288    gpart add -t freebsd-ufs ${md}
289    ${SRCTOP}/tools/boot/install-boot.sh -g ${geli} -s ${scheme} -f ${fs} -b ${bios} -d ${src} ${md}
290    mdconfig -d -u ${md}
291    rm -f ${src}/etc/fstab
292}
293
294qser="-serial telnet::4444,server -nographic"
295
296# https://wiki.freebsd.org/QemuRecipes
297# aarch64
298qemu_aarch64_uefi()
299{
300    img=$1
301    sh=$2
302
303    echo "qemu-system-aarch64 -m 4096M -cpu cortex-a57 -M virt  \
304        -bios QEMU_EFI.fd ${qser} \
305        -drive if=none,file=${img},id=hd0 \
306        -device virtio-blk-device,drive=hd0" > $sh
307# https://wiki.freebsd.org/arm64/QEMU also has
308#       -device virtio-net-device,netdev=net0
309#       -netdev user,id=net0
310}
311
312# Amd64 qemu
313qemu_amd64_legacy()
314{
315    img=$1
316    sh=$2
317
318    echo "qemu-system-x86_64 --drive file=${img},format=raw ${qser}" > $sh
319}
320
321qemu_amd64_uefi()
322{
323    img=$1
324    sh=$2
325
326    echo "qemu-system-x86_64 -bios ~/bios/OVMF-X64.fd --drive file=${img},format=raw ${qser}" > $sh
327}
328
329qemu_amd64_both()
330{
331    img=$1
332    sh=$2
333
334    echo "qemu-system-x86_64 --drive file=${img},format=raw ${qser}" > $sh
335    echo "qemu-system-x86_64 -bios ~/bios/OVMF-X64.fd --drive file=${img},format=raw ${qser}" >> $sh
336}
337
338# arm
339# nothing listed?
340
341# i386
342qemu_i386_legacy()
343{
344    img=$1
345    sh=$2
346
347    echo "qemu-system-i386 --drive file=${img},format=raw ${qser}" > $sh
348}
349
350# Not yet supported
351qemu_i386_uefi()
352{
353    img=$1
354    sh=$2
355
356    echo "qemu-system-i386 -bios ~/bios/OVMF-X32.fd --drive file=${img},format=raw ${qser}" > $sh
357}
358
359# Needs UEFI to be supported
360qemu_i386_both()
361{
362    img=$1
363    sh=$2
364
365    echo "qemu-system-i386 --drive file=${img},format=raw ${qser}" > $sh
366    echo "qemu-system-i386 -bios ~/bios/OVMF-X32.fd --drive file=${img},format=raw ${qser}" >> $sh
367}
368
369# mips
370# qemu-system-mips -kernel /path/to/rootfs/boot/kernel/kernel -nographic -hda /path/to/disk.img -m 2048
371
372# Powerpc -- doesn't work but maybe it would enough for testing -- needs details
373# powerpc64
374# qemu-system-ppc64 -drive file=/path/to/disk.img,format=raw
375
376# sparc64
377# qemu-system-sparc64 -drive file=/path/to/disk.img,format=raw
378
379# Misc variables
380SRCTOP=$(make -v SRCTOP)
381cd ${SRCTOP}/stand
382OBJDIR=$(make -v .OBJDIR)
383IMGDIR=${OBJDIR}/boot-images
384mkdir -p ${IMGDIR}
385MNTPT=$(mktemp -d /tmp/stand-test.XXXXXX)
386
387# Setup the installed tree...
388DESTDIR=${OBJDIR}/boot-tree
389rm -rf ${DESTDIR}
390mkdir -p ${DESTDIR}/boot/defaults
391mkdir -p ${DESTDIR}/boot/kernel
392cp /boot/boot0 ${DESTDIR}/boot
393cp /boot/boot0sio ${DESTDIR}/boot
394cp /boot/pmbr ${DESTDIR}/boot
395cp /boot/boot ${DESTDIR}/boot
396# XXX boot1 exists only on sparc64
397cp /boot/boot1 ${DESTDIR}/boot
398cp /boot/boot1.efifat ${DESTDIR}/boot
399cp /boot/gptboot ${DESTDIR}/boot
400cp /boot/gptzfsboot ${DESTDIR}/boot
401cp /boot/loader ${DESTDIR}/boot
402cp /boot/kernel/kernel ${DESTDIR}/boot/kernel
403echo -h -D -S115200 > ${DESTDIR}/boot.config
404# XXX
405cp /boot/device.hints ${DESTDIR}/boot/device.hints
406# Assume we're already built
407make install DESTDIR=${DESTDIR} MK_MAN=no MK_INSTALL_AS_USER=yes
408# Copy init, /bin/sh, minimal libraries and testing /etc/rc
409mkdir -p ${DESTDIR}/sbin ${DESTDIR}/bin \
410      ${DESTDIR}/lib ${DESTDIR}/libexec \
411      ${DESTDIR}/etc ${DESTDIR}/dev
412for f in /sbin/halt /sbin/init /bin/sh $(ldd /bin/sh | awk 'NF == 4 { print $3; }') /libexec/ld-elf.so.1; do
413    cp $f ${DESTDIR}/$f
414done
415cat > ${DESTDIR}/etc/rc <<EOF
416#!/bin/sh
417
418echo "RC COMMAND RUNNING -- SUCCESS!!!!!"
419halt -p
420EOF
421
422# OK. Let the games begin
423
424for arch in amd64; do
425    for geli in nogeli geli; do
426	for scheme in gpt mbr; do
427	    for fs in ufs zfs; do
428		for bios in legacy uefi both; do
429		    # Create sparse file and mount newly created filesystem(s) on it
430		    img=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.img
431		    sh=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.sh
432		    echo "vvvvvvvvvvvvvvvvvvvvvv   Creating $img  vvvvvvvvvvvvvvvvvvvvvvv"
433		    rm -f ${img}*
434		    eval mk_${geli}_${scheme}_${fs}_${bios} ${DESTDIR} ${img} ${MNTPT} ${geli} ${scheme} ${fs} ${bios}
435		    eval qemu_${arch}_${bios} ${img} ${sh}
436		    [ -n "${SUDO_USER}" ] && chown ${SUDO_USER} ${img}*
437		    echo "^^^^^^^^^^^^^^^^^^^^^^   Creating $img  ^^^^^^^^^^^^^^^^^^^^^^^"
438		done
439	    done
440	done
441    done
442done
443
444rmdir ${MNTPT}
445
446exit 0
447
448# Notes for the future
449
450for arch in i386; do
451    for geli in nogeli geli; do
452	for scheme in gpt mbr; do
453	    for fs in ufs zfs; do
454		for bios in legacy; do
455		    # Create sparse file and mount newly created filesystem(s) on it
456		    img=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.img
457		    sh=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.sh
458		    echo "vvvvvvvvvvvvvvvvvvvvvv   Creating $img  vvvvvvvvvvvvvvvvvvvvvvv"
459		    rm -f ${img}*
460		    eval mk_${geli}_${scheme}_${fs}_${bios} ${DESTDIR} ${img} ${MNTPT} ${geli} ${scheme} ${fs} ${bios}
461		    eval qemu_${arch}_${bios} ${img} ${sh}
462		    [ -n "${SUDO_USER}" ] && chown ${SUDO_USER} ${img}*
463		    echo "^^^^^^^^^^^^^^^^^^^^^^   Creating $img  ^^^^^^^^^^^^^^^^^^^^^^^"
464		done
465	    done
466	done
467    done
468done
469
470for arch in arm aarch64; do
471    for scheme in gpt mbr; do
472	fs=ufs
473	for bios in uboot efi; do
474	    # Create sparse file and mount newly created filesystem(s) on it
475	    img=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.img
476	    sh=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.sh
477	    echo "vvvvvvvvvvvvvvvvvvvvvv   Creating $img  vvvvvvvvvvvvvvvvvvvvvvv"
478	    rm -f ${img}*
479	    eval mk_${geli}_${scheme}_${fs}_${bios} ${DESTDIR} ${img} ${MNTPT} ${geli} ${scheme} ${fs} ${bios}
480	    eval qemu_${arch}_${bios} ${img} ${sh}
481	    [ -n "${SUDO_USER}" ] && chown ${SUDO_USER} ${img}*
482	    echo "^^^^^^^^^^^^^^^^^^^^^^   Creating $img  ^^^^^^^^^^^^^^^^^^^^^^^"
483	done
484    done
485done
486
487for arch in powerpc powerpc64; do
488    for scheme in ppc-wtf; do
489	fs=ufs
490	for bios in ofw uboot chrp; do
491	    # Create sparse file and mount newly created filesystem(s) on it
492	    img=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.img
493	    sh=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.sh
494	    echo "vvvvvvvvvvvvvvvvvvvvvv   Creating $img  vvvvvvvvvvvvvvvvvvvvvvv"
495	    rm -f ${img}*
496	    eval mk_${geli}_${scheme}_${fs}_${bios} ${DESTDIR} ${img} ${MNTPT} ${geli} ${scheme} ${fs} ${bios}
497	    eval qemu_${arch}_${bios} ${img} ${sh}
498	    [ -n "${SUDO_USER}" ] && chown ${SUDO_USER} ${img}*
499	    echo "^^^^^^^^^^^^^^^^^^^^^^   Creating $img  ^^^^^^^^^^^^^^^^^^^^^^^"
500	done
501    done
502done
503
504for arch in sparc64; do
505    for geli in nogeli; do
506	for scheme in vtoc8; do
507	    for fs in ufs; do
508		for bios in ofw; do
509		    # Create sparse file and mount newly created filesystem(s) on it
510		    img=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.img
511		    sh=${IMGDIR}/${arch}-${geli}-${scheme}-${fs}-${bios}.sh
512		    echo "vvvvvvvvvvvvvvvvvvvvvv   Creating $img  vvvvvvvvvvvvvvvvvvvvvvv"
513		    rm -f ${img}*
514		    eval mk_${arch}_${geli}_${scheme}_${fs}_${bios} ${DESTDIR} ${img} ${MNTPT} ${geli} ${scheme} ${fs} ${bios}
515		    eval qemu_${arch}_${bios} ${img} ${sh}
516		    [ -n "${SUDO_USER}" ] && chown ${SUDO_USER} ${img}*
517		    echo "^^^^^^^^^^^^^^^^^^^^^^   Creating $img  ^^^^^^^^^^^^^^^^^^^^^^^"
518		done
519	    done
520	done
521    done
522done
523