Host Setup

This guide covers the generic setup of network services on an Ubuntu host machine. These services include DHCP, TFTP, and NFS servers that enable diskless booting and development.

Install Required Packages

First, update your package list and install the required services:

sh-host:~$ sudo apt update
sh-host:~$ sudo apt install isc-dhcp-server tftpd-hpa nfs-kernel-server

Note

firewalld can be installed to configure iptables if you have an active firewall on your system. Ubuntu ships with UFW (The default firewall manager) disabled.

# To install firewalld
sh-host:~$ sudo apt install firewalld
# To configure the TFTP port
sh-host:~$ sudo firewall-cmd --add-port=69/udp
# To configure the NFS port
sh-host:~$ sudo firewall-cmd --add-port=2049/tcp

Network Interface Setup

We will need our Host Machine’s IPv4 address. Use ip addr to check your Host’s IP address:

sh-host:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
    valid_lft forever preferred_lft forever
2: enp11s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 6c:24:08:cf:12:4b brd ff:ff:ff:ff:ff:ff
    inet 172.22.10.32/24 brd 172.22.10.255 scope global dynamic noprefixroute enp11s0
    valid_lft 405645sec preferred_lft 405645sec
    inet6 fe80::d4b:2f18:2975:a5c9/64 scope link noprefixroute
    valid_lft forever preferred_lft forever
3: enx047bcb62cb4a: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 04:7b:cb:62:cb:4a brd ff:ff:ff:ff:ff:ff

In the above example output, it can be seen that this Host Machine’s USB to Ethernet adapter has a network interface named enx047bcb62cb4a.

Bring up the interface first:

sh-host:~$ sudo ip link set enx047bcb62cb4a up

Once the interface is up, we can assign an address as follows:

sh-host:~$ sudo ip addr add 192.168.100.1/24 dev enx047bcb62cb4a

Note

Depending on your LAN, IT department’s routing rules, and/or your specific Host Machine installation (virtual versus native) there may be additional consideration when establishing a valid network connection between your Host Machine and Target hardware.

In general, you usually need your Target device and Host Machine on the same subnet (ie the Host Machine and Target device should be assigned similar IPv4 addresses where all numbers match, such as 192.168.100.X where only the X is different for the two devices). This usually isn’t a issue if both the Host and Target device are connected to the same network switch.

In the case that your Ubuntu Host Machine is setup as a virtual machine (VM), you may need to modify the VM’s Networking settings:

  • Network Address Translation (NAT) mode is often times the default networking configuration for VMs and causes the underlying Host to route traffic between the VM and the network (the VM is essentially hidden behind the underlying Host from the perspective of the network). While NAT mode is great for anonymously connecting your VM to a network, it makes it invisible to other devices such as embedded development boards and thus prevents Network Boot from working properly.

  • Bridged mode allows your VM to connect directly to the network, replicating a physical device connection. You’ll generally want your VM in Bridged mode whenever it runs network services, which would allow devices to access it.

Setup DHCP Server

Configure which interface the DHCP server should use:

sh-host:~$ sudo vim /etc/default/isc-dhcp-server

Update the file with your usb-to-eth device interface. The interface must be properly defined or the isc-dhcp-server will fail to start.

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#   Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACESv4="enx047bcb62cb4a"
INTERFACESv6=""

Now configure the DHCP server by editing dhcpd.conf:

sh-host:~$ sudo vim /etc/dhcp/dhcpd.conf

Here is a minimal configuration that will assign IP addresses to devices on your network. Adapt the subnet range depending on your network card! In our case, subnet is 192.168.100.0/24

default-lease-time 600;
max-lease-time 7200;

option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.100.1;
option routers 192.168.100.1;
option broadcast-address 192.168.100.255;

# Define the subnet and netmask
subnet 192.168.100.0 netmask 255.255.255.0
{
    # Specify a range of IP addresses
    range 192.168.100.10 192.168.100.100;

    # Lease times
    default-lease-time 6000;
    max-lease-time 72000;
}

We can now start our DHCP server:

sh-host:~$ sudo systemctl start isc-dhcp-server

To check the status of our server we can run the following:

Example Output
sh-host:~$ systemctl status isc-dhcp-server
● isc-dhcp-server.service - ISC DHCP IPv4 server
        Loaded: loaded (/lib/systemd/system/isc-dhcp-server.service; enabled; vendor preset: enabled)
        Active: active (running) since Wed 2024-07-31 15:43:35 PDT; 4s ago
        Docs: man:dhcpd(8)
    Main PID: 173833 (dhcpd)
        Tasks: 4 (limit: 115431)
        Memory: 4.5M
            CPU: 15ms
        CGroup: /system.slice/isc-dhcp-server.service
                └─173833 dhcpd -user dhcpd -group dhcpd -f -4 -pf /run/dhcp-server/dhcpd.pid -cf /etc/dhcp/dhcpd.conf enx047bcb62cb4a

Setup TFTP Server

TFTP (Trivial File Transfer Protocol) is commonly used to transfer bootloader and kernel files during embedded system development.

First create a directory to host the TFTP server:

sh-host:~$ sudo mkdir /tftpboot
sh-host:~$ sudo chmod 777 /tftpboot
sh-host:~$ sudo chown nobody /tftpboot

Now we can setup our TFTP server configuration:

sh-host:~$ sudo vim /etc/default/tftpd-hpa

Edit the contents of the TFTP config file such that it reflects the following before saving and closing the file (note that we are basically pointing our TFTP daemon to open up the /tftpboot directory we just created on port 69):

# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create"

Start the TFTP daemon:

sh-host:~$ sudo systemctl restart tftpd-hpa

Now that the TFTP server is up, copy your bootloader and kernel binaries to the /tftpboot directory. The specific files required will depend on your target hardware platform.

Setup NFS

A Network Filesystem Server (NFS) allows embedded systems to mount a root filesystem over the network, enabling diskless development.

Create a directory to host the NFS:

sh-host:~$ sudo mkdir /nfsroot
sh-host:~$ sudo chmod 777 /nfsroot
sh-host:~$ sudo chown nobody /nfsroot

Now modify the NFS export table:

sh-host:~$ sudo vim /etc/exports

Add the following to the end of exports before saving and closing:

/nfsroot    192.168.100.0/24(rw,insecure,no_subtree_check,async,no_root_squash)

Start the NFS daemon:

sh-host:~$ sudo systemctl restart nfs-kernel-server

Now that the NFS is up, extract your target’s root filesystem to the /nfsroot directory. The specific root filesystem image will depend on your target hardware platform.