net booting with DHCP, PXE-Linux and TFTP

It has annoyed me for a long time, that I still needed a floppy disk, when I wanted to do a net install of Linux.

After getting a couple of NICs (Intel and 3com) that supported netbooting, I set about testing it.

One thing I did discover, was that getting both types of NIC working with the same software setup wasn't easy.


I used 3 different types of NIC:

  1. 3com® 905C-TX-M
  2. Intel® PRO/100 S Desktop Adapter (75767 - PILA8460C3)
  3. Intel® PRO/100+ Server Adapter (729757 - PILA8470B)

It turns out that the PRO/100 S won't boot with only a DHCP and non-multicast TFTP server. It seems to require a PXE server, and a multicast TFTP server.

The 905C-TX-M, on the other hand ignores the PXE server, and won't work with the multicast TFTP server

The PRO/100+ worked like the 3com card, but it booted faster.


The software needed to get it all working was:

Needed for both cards:

Needed for the 3com card

Needed for the Intel card

All these were built from source rpms found on


Both the tftp server from the PXE package and the tftp-hpa must be running at the same time. Since the normal TFTP server runs on 69/udp and the multicast runs on 1759/udp this is not a problem.

Since the 3com NIC ignores the PXE server, it doesn't try to use the multicast TFTP server, which won't work.

The new Intel card won't boot from the normal TFTP server, but since it gets data from the PXE server, it uses the multicast instead, which works fine.

This is quite messy, but it works.

Once you've booted the kernel, you can proceed with a normal net install. With kickstart, this can be done quite quickly.



The configuration of the dhcp server had to be changed, to enable it to pass the right options to the clients. First the optionspace had to be set up

# Definition of PXE-specific options
# Code 1: Multicast IP address of boot file server
# Code 2: UDP port that client should monitor for MTFTP responses
# Code 3: UDP port that MTFTP servers are using to listen for MTFTP requests
# Code 4: Number of seconds a client must listen for activity before trying
#         to start a new MTFTP transfer
# Code 5: Number of seconds a client must listen before trying to restart
#         a MTFTP transfer

option space PXE;
option PXE.mtftp-ip               code 1 = ip-address;  
option PXE.mtftp-cport            code 2 = unsigned integer 16;
option PXE.mtftp-sport            code 3 = unsigned integer 16;
option PXE.mtftp-tmout            code 4 = unsigned integer 8;
option PXE.mtftp-delay            code 5 = unsigned integer 8;
option PXE.discovery-control      code 6 = unsigned integer 8;
option PXE.discovery-mcast-addr   code 7 = ip-address;

Then, configuration options were inserted into the dhcp scope:

class "pxeclients" {
    match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
    option vendor-class-identifier "PXEClient";
    vendor-option-space PXE;

    # At least one of the vendor-specific PXE options must be set in
    # order for the client boot ROMs to realize that we are a PXE-compliant
    # server.  We set the MCAST IP address to to tell the boot ROM
    # that we can't provide multicast TFTP (address means no
    # address).

    option PXE.mtftp-ip;

    # This is the name of the file the boot ROMs should download.
    filename "pxelinux.0";

    # This is the name of the server they should get it from.


The file pxelinux.0 was from the PXELinux package, and was located in /tftpboot

The configuration for PXELinux was located in /tftpboot/pxelinux.cfg/C0A802 and looked like this:

label install
kernel vmlinuz-2.4.19-rc1-BOOT
append initrd=immunix-install-initrd.img text devfs=nomount ks=nfs:

The kernel and initrd were homemade updated versions of the ones from Immunix 7.0.


The only configuration needed for the tftp server was the setup for xinetd (/etc/xinetd.d/tftp):

service tftp
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -u nobody -s /tftpboot
        disable                 = no
        per_source              = 11
        cps                     = 100 2

MTFTP (multicast TFTP)

The multicast TFTP server needed a bit more configuration, but the xinetd config was essentially the same:

service mtftp
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.mtftpd
        server_args             = /tftpboot
        disable                 = no
        per_source              = 11
        cps                     = 100 2

/etc/mtftp.conf contains many options that can be changed. My changes looks like this:


The X86PC/UNDI/linux-install/linux.0 file is the redhat PXE bootloader. The next files are the linux kernel and initrd mentioned above.

Important notes:

pxelinux.0 cannot be used with the multicast TFTP server (it doesn't understand multicast it seems). The RedHat loader must be used.

A kernel cannot be booted directly, a bootloader must be used (either RedHats or PXELinux).

When the boot process prompts to enter kernel parameters, I've had to press a key, and then press return, otherwise the kernel wouldn't boot.


The configuration for the PXE server was also changed minimally:

# Set the following entry to 0 if you have a DHCP server running on this 
# system.


Since a DHCP server was already running, the PXE server doesn't need to act as one. The PXE service doesn't run from xinetd, it is started by /etc/rc.d/init.d/pxe


The tftp service was already in my /etc/services, but I added these:

pxe             4011/udp
mtftp           1759/udp

Valid XHTML 1.1! Valid CSS!
Last updated: 2002-10-02 22:53