Pure TFTP booting
Build Stage
First, a staging dir is needed to place all the tftp files in, for example: /usr/local/tftp/.
Then bzip2 support is needed in the pxeboot binary, so add these to {make,src}.conf and rebuild pxeboot:
LOADER_NO_GELI_SUPPORT=y LOADER_BZIP2_SUPPORT=y
A custom KERNEL can be a good idea to cut down on the size and make it faster to load and less prone to errors. I use this config file:
include MINIMAL ident NETBOOT nomakeoptions DEBUG # Build kernel with gdb(1) debug symbols nomakeoptions WITH_CTF # Run ctfconvert(1) for DTrace support nooptions COMPAT_FREEBSD32 nooptions COMPAT_FREEBSD4 nooptions COMPAT_FREEBSD5 nooptions COMPAT_FREEBSD6 nooptions COMPAT_FREEBSD7 nooptions COMPAT_FREEBSD9 nooptions COMPAT_FREEBSD10 nooptions COMPAT_FREEBSD11 nooptions KTRACE nooptions AUDIT nooptions CAPABILITY_MODE nooptions CAPABILITIES nooptions MAC nooptions KDTRACE_FRAME nooptions KDTRACE_HOOKS nooptions DDB_CTF nooptions DEADLKRES nooptions INVARIANTS nooptions INVARIANT_SUPPORT nooptions WITNESS nooptions WITNESS_SKIPSPIN # USB support options USB_DEBUG # enable debug msgs device uhci # UHCI PCI->USB interface device ohci # OHCI PCI->USB interface device ehci # EHCI PCI->USB interface (USB 2.0) device xhci # XHCI PCI->USB interface (USB 3.0) device usb # USB Bus (required) device ukbd # Keyboard nooptions XENHVM # Xen HVM kernel infrastructure nodevice xenpci # Xen HVM Hypervisor services driver options GEOM_PART_GPT options GEOM_RAID options GEOM_LABEL options GEOM_UZIP options IFLIB device em # Intel PRO/1000 Gigabit Ethernet Family device md device tmpfs options NKPT=128
Note: Only one Ethernet driver is included, others can be loaded as modules or the config modified to include the appropriate module.
Then a small netboot img is needed to load via TFTP. To cut down the size we can use a custom {src,make}.conf like so:
WITHOUT_ACPI="YES" WITHOUT_APM="YES" WITHOUT_ACCT="YES" WITHOUT_AMD="YES" WITHOUT_ASSERT_DEBUG="YES" WITHOUT_AT="YES" WITHOUT_ATM="YES" WITHOUT_AUDIT="YES" WITHOUT_AUTHPF="YES" WITHOUT_AUTOFS="YES" WITHOUT_BHYVE="YES" WITHOUT_BLACKLIST=YES" WITHOUT_BLUETOOTH="YES" WITHOUT_BSDINSTALL="YES" WITHOUT_BOOTPARAMD="YES" WITHOUT_BSNMP="YES" WITHOUT_CALENDAR="YES" WITHOUT_CAPSICUM="YES" WITHOUT_CCD="YES" WITHOUT_CDDL="YES" WITHOUT_COMPAT32="YES" WITHOUT_CTM="YES" WITHOUT_CUSE="YES" WITHOUT_CXX="YES" WITHOUT_DIALOG="YES" WITHOUT_DICT="YES" WITHOUT_DEBUG_FILES="YES" WITHOUT_EE="YES" WITHOUT_EXAMPLES="YES WITHOUT_FDT="YES" WITHOUT_FINGER="YES" WITHOUT_FLOPPY="YES" WITHOUT_FMTREE="YES" WITHOUT_FTP="YES" WITHOUT_FREEBSD_UPDATE="YES" WITHOUT_GAMES="YES" WITHOUT_HTML="YES" WITHOUT_ICONV="YES" WITHOUT_IPFILTER="YES" WITHOUT_IPFW="YES" WITHOUT_ISCSI="YES" WITHOUT_JAIL="YES" WITHOUT_KDUMP="YES" WITHOUT_LEGACY_CONSOLE="YES" WITHOUT_LIB32="YES" WITHOUT_LOCALES="YES" WITHOUT_LPR="YES" WITHOUT_LZMA_SUPPORT="YES" WITHOUT_MAKE="YES" WITHOUT_MAN="YES" WITHOUT_NDIS="YES" WITHOUT_NETGRAPH="YES" WITHOUT_NIS="YES" WITHOUT_NLS="YES" WITHOUT_NLS_CATALOGS="YES" WITHOUT_NS_CACHING="YES" WITHOUT_PC_SYSINSTALL="YES" WITHOUT_PF="YES" WITHOUT_PORTSNAP="YES" WITHOUT_PPP="YES" WITHOUT_PROFILE="YES" WITHOUT_QUOTAS="YES" WITHOUT_RADIUS_SUPPORT="YES" WITHOUT_RBOOTD="YES" WITHOUT_RCMDS="YES" WITHOUT_RESCUE="YES" WITHOUT_ROUTED="YES" WITHOUT_SENDMAIL="YES" WITHOUT_SERVICESDB="YES" WITHOUT_SHAREDOCS="YES" WITHOUT_SSP="YES" WITHOUT_SYSCONS="YES" WITHOUT_SVNLITE="YES" WITHOUT_TALK="YES" WITHOUT_TELNET="YES" WITHOUT_TESTS="YES" WITHOUT_TEXTPROC="YES" WITHOUT_TFTP="YES" WITHOUT_TIMED="YES" WITHOUT_TOOLCHAIN="YES" WITHOUT_USB="YES" WITHOUT_WIRELESS="YES" WITHOUT_VT="YES" WITHOUT_ZONEINFO="YES"
Modify as appropriate for your needs.
And a script to build the OS and create the small image:
DEST='/tmp/netboot' TFTPROOT='/usr/local/tftp' JOBS=`sysctl -n hw.ncpu` for target in buildworld buildkernel installworld distribution; do make -j${JOBS} $target \ SRCCONF=/home/user/netboot/src.conf.netboot \ __MAKE_CONF=/home/user/netboot/make.conf.netboot \ DESTDIR=${DEST} \ KERNCONF=NETBOOT \ || exit 1 done for target in delete-old delete-old-libs; do make $target \ BATCH_DELETE_OLD_FILES=yes \ SRCCONF=/home/user/netboot/src.conf.netboot \ __MAKE_CONF=/home/user/netboot/make.conf.netboot \ DESTDIR=${DEST} \ || exit 1 done rm -rf ${DEST}/var/db/pkg rm -rf ${DEST}/var/cache/pkg rm -rf ${DEST}/var/db/services.db rm -rf ${DEST}/netboot/boot/* for file in magic magic.mgc mdoc.template operator organization.dot \ pci_vendors scsi_modes ascii birthtoken bsd-family-tree \ definitions.units eqnchar flowers iso3166 iso639 latin1 \ committers-src.dot committers-doc.dot committers-ports.dot; do rm -rf /tftpboot/netboot/usr/share/misc/${file} done rm -rf ${DEST}/usr/share/misc/committers mkdir -p /usr/local/tftp/ makefs -M 96m ${TFTPROOT}/netboot.img ${DEST} cp ${DEST}/sys/NETBOOT/kernel ${TFTPROOT} cp ${DEST}/sys/boot/i386/pxeldr/pxeboot ${TFTPROOT} cp ${DEST}/sys/boot/efi/loader/loader.efi ${TFTPROOT} bzip2 -f ${TFTPROOT}/netboot.img bzip2 -f ${TFTPROOT}/kernel
Configure Stage
DNSMASQ will be used for this step as it supports TFTP and DHCP all at once.