====== 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:
#!/bin/sh
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.