Using pxeboot to install FreeBSD 5.3 on a laptop without bootable CDROM drive
Grenville Armitage
December 5th 2004

This month I had to install FreeBSD 5.3 on a laptop that lacked a bootable CDROM (a Toshiba Portege R100). Rather than launch the installation from floppies, I decided to explore the use of pxeboot (supported by the R100's BIOS) to enable the laptop to boot the FreeBSD 5.3 Installation CDROM over my local LAN.
This documentation is largely for my own benefit - a record of what I did in case I ever need to do it again. With any luck, this information will be useful to others (like you, if you're reading this page and you aren't me).

What is pxeboot?

A quick summary - when your BIOS is set to perform a "LAN boot" it pulls boot information (a pxeboot executable, boot-time configuration details and an operational kernel) from another host on the local LAN. The process requires your on-LAN DHCP server to co-operate by handing back pxeboot-specific optional parameters - the booting machine uses DHCP to query for both an IP address and the on-LAN location of the boot time configuration files and kernel.

What I wanted to do is use pxeboot to force my laptop to boot from the FreeBSD 5.3 installation CDROM, in the absence of a bootable CDROM drive on the laptop itself.

Some more info on pxeboot can be found in the FreeBSD manpage or an article on the FreeBSD website.

An overview of the solution

There are three main components required on your local network:
When a client begins to boot over the local LAN, it queries the DHCP server and expects to get back not only a valid IP address but also pointers to where it can find a functional pxeboot executable. The client then initiates a TFTP transfer of the nominated pxeboot executable into local memory, and begins executing pxeboot in place of the more usual boot loader. pxeboot then attempts to NFS-mount a nominated file system that is assumed to contain /boot, the location (under FreeBSD 5.3 at least) of a bootable kernel and various boot-time configuration files.

I chose to create an NFS-exported file system under /cdroms/fb53pxe/ which contained only one directory - /boot/ - copied from the FreeBSD 5.3 installation CDROM. The TFTP server pointed to a copy of pxeboot located at
/cdroms/fb53pxe/boot/pxeboot and the NFS server exported /cdroms/fb53pxe/. (It was important to have a modifiable copy of /boot, rather than exporting the FreeBSD 5.3 installation CDROM directly, because /boot/loader.conf needs an extra line to make pxebooting work properly for my needs.)

Creating the pxe-bootable version of the FreeBSD 5.3 Installer file system

As root I first created a minimal, bootable file system from the FreeBSD 5.3 installation CROM using the following steps:

mount /cdrom               [...assuming the FreeBSD 5.3 installation CDROM is in the drive]
mkdir -p /cdroms/fb53pxe
cp -Rp /cdrom/boot
umount /cdrom

The main reason we create a separate copy of /boot on regular disk is to edit /cdroms/fb53pxe/boot/loader.conf by adding the following line:


(This line forces the kernel to use memory mapped disk at /dev/md0c as the root partition, despite the fact that pxeboot normally expects to use an NFS-mounted root partition. The importance of this change will become clearer below.)

DHCP Server configuration

I already had a DHCP server installed on my central machine (easily installed with 'pkg_add -r isc-dhcp3-server' and adding 'dhcpd_enable="YES"' to /etc/rc.conf). The IP to MAC address mappings are defined in /usr/local/etc/dhcpd.conf. In my case, my laptop machine (r100, at already had a special entry that looked like this:

host r100 {
  hardware ethernet 00:08:0d:88:c4:33;   [This uniquely identifies the client]
  fixed-address;            [DHCP assigns this IP address to the client]

This entry was augmented with three additional lines to support pxeboot, and now looked like:

host r100 {
  hardware ethernet 00:08:0d:88:c4:33;
  next-server;            [Client will do TFTP and NFS transfers from]
  filename "fb53pxe/boot/pxeboot";      [Grabbed via TFTP, executed in place of the client host's boot loader]
  option root-path "/cdroms/fb53pxe/";   [pxeboot will look for /boot/kernel relative to this NFS-mounted directory]

TFTP Server configuration

TFTP was easily enabled  by editting /etc/inetd.conf to have the following line:

tftp    dgram   udp     wait    root    /usr/libexec/tftpd      tftpd -s /cdroms/

The line above means that all TFTP requests will be resolved relative to /cdroms on my server host (the "-s" forces tftpd to perform a chroot to /cdroms/ after starting up). Recall that I placed a copy of the installation CDROM's /boot directory tree under /cdroms/fb53pxe/boot.  The path specified under filename in the DHCP server's configuration file (above) thus results in the client requesting the file/cdroms/fb53pxe/boot/pxeboot using TFTP, as required.

kill -HUP `cat /var/run/` after editting /etc/inetd.conf to ensure inetd is re-initialised correctly.

NFS Server configuration

I already had NFS running, so the only additional step was to add /cdroms/fb53pxe in the list of exported filesystems. The following line was added to /etc/exports:

/cdroms/fb53pxe  -network 192.168.10  -mask

This export matches the option root-path in the
DHCP server's configuration file (above), the path that the pxeboot client will automount and use as the intial root directory during the early stage of booting.

Run kill -HUP `cat /var/run/` after editting /etc/exports to ensure the NFS server is re-initialised correctly.

What happens during boot now?

Assuming everything's working okay, a typical boot sequence is now:
Once the client is booted in this fashion it continues into the standard FreeBSD 5.3 Installer, and from this point functions just the same as if we'd booted from CDROM or floppies. One advantage of this approach is that you can add multiple hosts in the DHCP server's configuration if you need to run the FreeBSD 5.3 installer on numerous machines that support pxeboot but lack bootable CDROM drives.

(In my case I continued on to doing the actual Installation over NFS, since I was also exporting the entire FreeBSD 5.3 CDROM image via NFS using the technique described here.)