--- tags: qemu, freebsd, ufs --- # building a UFS bootable image from scratch TLDR: - create a file-backed mdconfig device - initialise and partition it - write boot code into new - newfs the leftovers - untar base and kernel - fix up bits (tzsetup, fstab, boot delay, ssh keys...) ## make it so - should really make the mdconfig and image file with mktemp dynamically - ensure gpart labels are unique so we don't screw the actual system ```shell truncate -s 4g /tmp/img mdconfig -a -t vnode -f /tmp/img -u md0 gpart create -s gpt /dev/md0 gpart add -t freebsd-boot -l mdboot -b 40 -s 512K md0 gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 md0 gpart add -t freebsd-ufs -l mdroot -b 1M -s 3G md0 newfs -U /dev/md0p2 mount /dev/md0p2 /mnt tar xzf /usr/jails/downloads/12.0-RELEASE/base.txz -C /mnt tar xzf /usr/jails/downloads/12.0-RELEASE/kernel.txz -C /mnt /usr/sbin/freebsd-update -b /mnt \ --currently-running 12.0-RELEASE \ --not-running-from-cron \ fetch install \ >/dev/null tee -a /mnt/etc/rc.conf << EOC ntpd_enable=YES growfs_enable=YES EOC echo "/dev/ada0p2 / ufs rw,noatime 1 1" >/mnt/etc/fstab touch /mnt/firstboot tee -a /mnt/boot/loader.conf << EOL kern.geom.label.disk_ident.enable="0" kern.geom.label.gptid.enable="0" autoboot_delay="0" vfs.root.mountfrom="ufs:/dev/ada0p2" # This may or may not be necessary EOL tzsetup -s -C /mnt UTC mkdir -p /mnt/usr/local/etc/pkg/repos/ tee /mnt/usr/local/etc/pkg/repos/FreeBSD.conf << EOP FreeBSD: { url: pkg+http://pkg.FreeBSD.org/\$\{ABI\}/latest enabled: yes } EOP env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg -c /mnt bootstrap -f umount /mnt mdconfig -du md0 qemu-img convert -f raw -O qcow2 /tmp/img img.qcow2 qemu-img resize img.qcow2 16G ``` ## run it ```shell qemu-system-x86_64 -m 4096 -hda img.qcow2 -display curses ``` ## references & useful bits - https://www.freebsd.org/cgi/man.cgi?query=gptboot - https://www.freebsd.org/cgi/man.cgi?query=gpart - https://github.com/bitboss-ca/freebsd-gce-tools/blob/master/create-image.sh