Booting FreeBSD 5.0 on a Sun machine over the network

Anthony Volodkin <anthonyv@brainlink.com>

Introduction

In recent years, the FreeBSD-sparc64 port gathered significant attention among developers. A large amount of work has been done over the years; however, there is still a lot that must be accomplished in terms of device support and stability. One of the shortcomings of the FreeBSD-sparc64 port is the lack of support for some onboard SCSI devices that are used in Sun Ultra 1's, Ultra 2's, and possibly other models. This prevents FreeBSD from recognizing attached disk drives and thus booting from a disk.

To allow developers to test their code, especially disk drivers, it is necessary to boot the machine without using a disk. The FreeBSD Handbook describes the procedure for booting a diskless workstation, but that does not entirely apply to booting a FreeBSD-sparc64 system on a machine such as an Ultra 2. The solution below involves using TFTP and the kernel support for a NFS-mounted root partition to boot FreeBSD from the network.

Our example setup involves a fast i386 machine running FreeBSD 4.7-RELEASE and a Sun Ultra 2 with FreeBSD 5.0-DP2. This procedure is applicable to a wide range of Sun hardware and will work with later releases of the FreeBSD 5.0.

Setting up DHCPd

First, we need to download and install isc-dhcpd 3.x onto the machine that will also act as the TFTP/NFS server. You can find it in /usr/ports/net/isc-dhcp3/. After completeing the basic dhcpd configuration such as the subnet definitions, IP addressess ranges, etc., we can proceed with adding a host section for the netbooted machine.

Here is an example:

	host divine {
		hardware ethernet 08:00:20:89:cf:f3;
		option host-name "divine.local.non-standard.net";
		fixed-address 192.168.1.5;
		always-reply-rfc1048 on;
		filename "loader.nfs";
		next-server 192.168.1.3;
		option root-path "192.168.1.3:/storage3/sparc64-nfsroot";
	}

The filename field refers to the name of the file that should be originally sent to the machine after its first DHCP/BOOTP request. The next-server field specifies which server should be used for downloading the kernel using TFTP or NFS. The root-path option describes where the kernel is located on the NFS server.

Setting up TFTPd

In the next step we use the default TFTP daemon that comes with FreeBSD. However, the default configuration in /etc/inetd.conf does not work properly in this case. Access Violations (even while proper permissions are set) and other errors appear when a client requests "/loader.nfs" instead of "loader.nfs" or vice-versa. In order to make it work we have to modify inetd.conf to look like the following:

	tftp dgram udp wait root /usr/libexec/tftpd tftpd -l -s /tftpboot

This does the trick, and a request for "/loader.nfs" gets treated identically to "loader.nfs" Now all we need to do is to obtain loader.nfs and place it in the /tftpboot directory. You can download it from http://non-standard.net/freebsd/loader.nfs To avoid any permission problems just execute the following:

	chown -R nobody:nobody /tftpboot
	chmod -R 755 /tftpboot

Setting up NFS

Now we have to download the live-filesystem ISO from ftp://ftp.freebsd.org/pub/FreeBSD/ISO-IMAGES-sparc64/5.0-DP2-disc2.iso (use a mirror), and mount it using vnconfig. Note that vnconfig for FreeBSD 4.7 is known as mdconfig in FreeBSD 5.0-CURRENT.

	vnconfig vn0 5.0-DP2-disc2.iso  # associate vn0 with the cd image
	mount -t cd9660 /dev/vn0c /mnt  # mount the image

Copy the contents of /mnt directory somewhere on your machine. A simple cp will work; however, the live-filesystem contains symlinks so it is better to use rsync.

	cd /storage3/sparc64-nfsroot    # go into the future nfsroot directory
	rsync --progress -avr /mnt/ .   # extract contents 
	umount /mnt
	vnconfig -u vn0

Create a /etc/fstab in the nfsroot directory (in this case it is /storage3/sparc64-nfsroot) and add the following information to it:

	# Device Mountpoint FStype Options Dump Pass#
	192.168.1.3:/storage3/sparc64-nfsroot / nfs rw 0 0

Add the following to /etc/exports to enable the netbooted machine to mount its root filesystem from /storage3/sparc64-nfsroot:

	/storage3/sparc64-nfsroot -maproot=root 192.168.1.5

Start the NFS daemons (If you are using a 5.0-CURRENT machine as a server, use the rpcbind command instead of portmap):

	portmap
	nfsd -u -t -n 4
	mountd -r
	rpc.statd
	rpc.lockd

If you also want NFS to run upon bootup add the following to /etc/rc.conf

	portmap_enable="YES"
	nfs_server_enable="YES"
	mountd_flags="-r"
	rpc_statd_enable="YES"
	rpc_lockd_enable="YES"

Now we are ready to build a custom sparc64 kernel. The GENERIC one on the CD image does not include the options necessary for a successful diskless boot. We have to get the 5.0-CURRENT sources using cvsup (refer to the FreeBSD handbook for detailed instructions) and edit "/usr/src/sys/sparc64/conf/DIVINE" (DIVINE will be our sample kernel) and add the following:

	options BOOTP # Use BOOTP to obtain IP address/hostname
	options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info
	options BOOTP_NFSV3 # Use NFS v3 to NFS mount root
	options BOOTP_COMPAT # Workaround for broken bootp daemons.
	options BOOTP_WIRED_TO=hme0 # Use interface fxp0 for BOOTP

Then we build the kernel. It is possible to cross-compile a sparc64 kernel/world on a i386 machine:

	cd /usr/src/
	make TARGET_ARCH=sparc64 buildworld   # buildworld for the sparc64 port
	make TARGET_ARCH=sparc64 buildkernel  # build the sparc64 kernel

When this is completed, we will move the files:

	mv /storage3/sparc64-nfsroot/boot/kernel /storage3/sparc64-nfsroot/boot/kernel.GENERIC   # move the default kernel tree in the nfsroot to another location
	mkdir /storage3/sparc64-nfsroot/boot/kernel                                              # make new kernel directory
	cp /usr/obj/sparc64/usr/src/sys/DIVINE/* /storage3/sparc64-nfsroot/boot/kernel/          # copy the kernel as well as the modules into the new kernel directory

Note that it's important not to do a cp -r, because then a whole bunch of unnecessary parts of the source will be copied into the kernel directory.

Booting the Sun machine

Finally, at the OpenBoot prompt enter the following:

	ok (0) boot net:dhcp,192.168.1.3,loader.nfs

This will use DHCP to get an IP address and then download and execute loader.nfs from 192.168.1.3 via TFTP. After this, you will see a normal login prompt. If your Ultra 2 does not support these boot options, you might have to upgrade the firmware (http://sunsolve.sun.com/.

Comments or corrections are welcome at anthonyv@brainlink.com. Special thanks to Jake Burkholder for his input.



Author maintains all copyrights on this article.