PXE Install (Network Installation) of FreeBSD from a Linux Box

Posted at — Jun 23, 2010


All information outdated, nothing appropriate? Same here! The Jumpstart (freebsdish for PXE) Guide is from ‘05, and uses obsolete commands. Other HowTos need a functional FreeBSD system to create a customized image with bsd slices to push from the server (which is unnecessary), so, i wrote up my findings.


A Client that supports PXE boot (obviously), and the server running NFSd (apt-get install nfs-kernel-server), tftpd (tftpd-hpa), and dhcpd (dhcp3-server). Software: The FreeBSD bootonly.iso, I used today’s current release, 8.0-RELEASE-amd64-bootonly.iso. All things done on Debian, but should be minor changes for other distributions.



Here I used 'dhcp3-server': All changes i did to the default config file (/etc/dhcp3/dhcpd.conf) affect the PXE offer to the client, expect that you need to define a subnet to listen on. I simply uncommented the default:

# A slightly different configuration for an internal subnet.
subnet netmask {
#  option domain-name-servers ns1.internal.example.org;
#  option domain-name "internal.example.org";
#  option routers;
#  option broadcast-address;
  default-lease-time 600;
  max-lease-time 7200;

and added this for pxe boot (same file):

  host atom {
    hardware ethernet 70:71:BC:3C:1D:76;
    filename "/boot/pxeboot";
    option root-path "";

Here you say where the directory is located that holds your FreeBSD NetInstall image. As you can see, you define a root-path for the PXE boot, which is the tftp directory. There under /boot/pxeboot lies the bootloader that the client loads. Thus, together this refers to /srv/tftp/boot/pxeboot on your system. The first 3 lines in the ‘host atom’ configuration need your adjustment. The hardware ethernet statement stands for the MAC address of your client, the fixed-address is the ip that will be given to the client. Just pick a random one within the subnet. The next-server refers to your servers ip.

network config:

The settings must fit your servers network configuration. Either use ifconfig/ifup or /etc/network/interfaces in Debian:

# The primary network interface
auto eth1
iface eth1 inet static


Debian defaults the tftpd working directory to /srv/tftp. I kept that, and simply put all stuff in there. So mount the iso file and copy the roughly 30mb to that folder.

 cd /srv/tftp/
 losetup /dev/loop1 /tmp/build/8.0-RELEASE-amd64-bootonly.iso
 mount /dev/loop0 /mnt/iso/
 cp -dpR /mnt/iso/* ./

For tftp there is nothing to configure, but if you are curious, the config file is at /etc/default/tftpd-hpa and should have the above mentioned folder defined.

exports (NFSd):

At last, write a simple exports for nfs that serves your need:



So, the real trick comes now. The FreeBSD Installer needs NFSv1 or NFSv2, so keep in mind, that you don’t disable the older versions, or you can’t mount your NFS shared files. Your pxeboot will complain that there is no /dev/ and can’t find init:

Lookup of /dev for devfs, error: 2
init: not found in path

and then the client reboots. The workaround is, to specify vfs.root.mountfrom="ufs:/dev/md0" to make the loader find the kernel on a specific slice. It tries to mount root / filesystem via NFS as opposed to just looking for /tfpt/ instead. Without the trailing c after md0 you kept finding elsewhere. I’ve simply thrown all that in the loader.rc file at (/srv/tftp/boot/loader.rc).

load /boot/kernel/kernel
load -t mfs_root /boot/mfsroot
set vfs.root.mountfrom="ufs:/dev/md0"

That defines the kernel location, loads an mfs (ramdisk) and boots from there and fires up the install.