Host Setup (Container)

This guide provides instructions for configuring network services in a generic setup. While similar to the standard “Host Setup” guide, this approach runs most services within Podman containers rather than installing them directly on the host system. Services such as DHCP and TFTP will run in containers, though the NFS server remains installed natively. This configuration facilitates diskless booting and development workflows.

Install Required Packages

Begin by updating your package repository and installing podman:

sh-host:~$ sudo apt update
sh-host:~$ sudo apt install podman

Note

You may optionally install firewalld to manage iptables rules if your system has an active firewall. Note that Ubuntu’s default firewall manager (UFW) is disabled by default.

# 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

You’ll need to determine your Host Machine’s IPv4 address. Run ip addr to view your Host’s IP configuration:

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

The example output above shows that this Host Machine’s USB-to-Ethernet adapter is identified by the network interface name enx047bcb62cb4a.

Start by bringing up the network interface:

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

After the interface is activated, assign an IP address using the following command:

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

Note

Additional considerations may apply when establishing a network connection between your Host Machine and Target hardware, depending on your LAN configuration, IT department routing policies, and whether your Host Machine runs on a virtual or physical installation.

Typically, your Target device and Host Machine must reside on the same subnet (meaning they should have similar IPv4 addresses, such as 192.168.100.X, where only the final digit differs between the two devices). This is generally straightforward when both devices connect to the same network switch.

If your Ubuntu Host Machine operates as a virtual machine (VM), you may need to adjust the VM’s network configuration:

  • Network Address Translation (NAT) mode is frequently the default VM networking setup and causes the underlying host to route traffic between the VM and network (making the VM essentially invisible to other network devices). While NAT mode provides convenient anonymous network access for your VM, it prevents other devices like embedded development boards from seeing it, thereby breaking Network Boot functionality.

  • Bridged mode enables your VM to connect directly to the network as if it were a physical device. This mode is generally required when your VM runs network services, allowing other devices to access it.

Setup DHCP Server

The AM62x needs a DHCP server capable of responding to BOOTP requests to assign an IP address to the phyCORE-AM62x.

Create a file named Container.dhcp containing the following:

FROM debian:bookworm-slim

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        isc-dhcp-server \
        iproute2 \
        ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# Create necessary directories
RUN mkdir -p /var/lib/dhcp /var/run

COPY dhcpd.conf /etc/dhcp/dhcpd.conf

# Create empty leases file
RUN touch /var/lib/dhcp/dhcpd.leases

# Expose DHCP ports
EXPOSE 67/udp 68/udp

# Start dhcpd in foreground
# -f: Run in foreground
# -d: Log to stderr
# -cf: Config file location
CMD ["dhcpd", "-4", "-f", "-d", "-cf", "/etc/dhcp/dhcpd.conf", "-lf", "/var/lib/dhcp/dhcpd.leases", "enxc8a36204e3ac"]

As well as a file named dhcpd.conf containing the following content:

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

allow booting;
allow bootp;

option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.100.1;
option routers 192.168.100.254;
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 for BOOTP
  range dynamic-bootp 192.168.100.10 192.168.100.31;

   # Conditional filename assignments based on the vendor-class-identifier
   if substring (option vendor-class-identifier, 0, 16) = "TI K3 Bootp Boot"
   {
      filename "tiboot3.bin-ethboot";
   } elsif substring (option vendor-class-identifier, 0, 20) = "AM62X U-Boot R5 SPL"
   {
      filename "tispl.bin";
   } elsif substring (option vendor-class-identifier, 0, 21) = "AM62X U-Boot A53 SPL"
   {
      filename "u-boot.img";
   }

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

   # The IP address of the TFTP server (this could be the DHCP server itself)
   next-server 192.168.100.1;
}

Construct the container image with the DHCP server.

sh-host:~$ sudo podman build -t dhcp-server -f Containerfile.dhcp .

Then, launch the dhcp server as a background daemon with automatic port mapping between the container and host system.

sh-host:~$ sudo podman run -d --name dhcp --network host --cap-add=NET_RAW --cap-add=NET_ADMIN dhcp-server

Setup TFTP Server

TFTP (Trivial File Transfer Protocol) provides a standard method for transferring bootloader and kernel files during embedded system development workflows.

Create a file named Container.tftp with this content:

FROM debian:bookworm-slim

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        tftpd-hpa \
        wget \
        iproute2 \
        ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# Create directory for TFTP files
RUN mkdir -p /tftpboot && \
    chmod 777 /tftpboot

WORKDIR /tftpboot

# Latest release image. Can be replaced with custom images.
RUN wget -q https://download.phytec.de/Software/Linux/BSP-Yocto-AM62x/BSP-Yocto-Ampliphy-AM62x-PD25.1.0/images/ampliphy/phyboard-lyra-am62xx-3/tiboot3.bin-ethboot
RUN wget -q https://download.phytec.de/Software/Linux/BSP-Yocto-AM62x/BSP-Yocto-Ampliphy-AM62x-PD25.1.0/images/ampliphy/phyboard-lyra-am62xx-3/tispl.bin
RUN wget -q https://download.phytec.de/Software/Linux/BSP-Yocto-AM62x/BSP-Yocto-Ampliphy-AM62x-PD25.1.0/images/ampliphy/phyboard-lyra-am62xx-3/u-boot.img
RUN wget -q https://download.phytec.de/Software/Linux/BSP-Yocto-AM62x/BSP-Yocto-Ampliphy-AM62x-PD25.1.0/images/ampliphy/phyboard-lyra-am62xx-3/fitImage
RUN wget -q https://download.phytec.de/Software/Linux/BSP-Yocto-AM62x/BSP-Yocto-Ampliphy-AM62x-PD25.1.0/images/ampliphy/phyboard-lyra-am62xx-3/net_boot_fit.scr.uimg

RUN chmod 644 /tftpboot/*

# Expose port 69
EXPOSE 69/udp

# Start TFTP server
# -L: Run in standalone mode
# -a :69: Listen on all interfaces, port 69
# -c: Allow new files to be created
# -s: Secure mode (chroot to directory)
# -v: Verbose logging
CMD ["/usr/sbin/in.tftpd", "-L", "-a", ":69", "-c", "-s", "/tftpboot", "-v"]

Build the container image with the TFTP server and pre-configured images.

sh-host:~$ podman build -t tftp-server -f Containerfile.tftp .

Then, start the tftp server as a background daemon with port 69 mapped between the container and host system.

sh-host:~$ podman run -d --name tftp -p 69:69/udp tftp-server

As an alternative, you can create a local tftpboot directory and serve images from there instead. This allows the container to use images from Yocto’s deploy directory, giving you access to your latest builds or custom images rather than the pre-installed release images.

sh-host:~$ mkdir ./tftpboot/
sh-host:~$ podman run -d --name tftp -p 69:69/udp -v ./tftpboot:/tftpboot:Z tftp-server

Setup NFS

A Network Filesystem Server (NFS) provides embedded systems with the ability to mount a root filesystem over the network, supporting diskless development scenarios.

Note

Running an NFS server in a rootless container currently lacks reliable support. If you only require U-Boot functionality without booting fully into Linux, you can skip this section.

First, install the NFS server package.

sh-host:~$ sudo apt install nfs-kernel-server

Create a directory to serve as the NFS export location:

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

Next, edit the NFS export configuration:

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

Append the following line to the exports file before saving and exiting:

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

Launch the NFS service:

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

With the NFS server running, extract your target platform’s root filesystem into the /nfsroot directory. The appropriate root filesystem image will vary based on your specific target hardware.