Skip to content

USB RNDIS Network Boot (only SM2)

USB RNDIS network boot loads the boot components through the Micro-USB setup port, then uses the same link for the Linux NFS root filesystem. It is intended for development and recovery: nothing in this procedure writes the device's internal flash.

The host provides three services on an isolated USB network:

  • DHCP, including the boot file and NFS-root information;
  • TFTP for the boot components; and
  • NFS for the unpacked root filesystem.

The device disconnects and reconnects several times during a boot. A bridge on the host keeps every USB Ethernet interface in the same isolated network, so the services remain available across those reconnects and to more than one device. It also gives Wireshark one stable capture point (br-usb) for the DHCP and TFTP exchange when a boot needs diagnosis.

Prerequisite: the device needs stock firmware 15.00.20 or newer. See Prerequisites.

Security: the example NFS export uses no_root_squash, because Linux needs root access to its own root filesystem. Keep this bridge isolated from any untrusted network or client.

1. Build the artifacts

Build all four components. One machine serves every board and both processor modules; the device trees for all of them are deployed side by side.

MACHINE=libretouch-net bitbake \
  u-boot-ti-staging virtual/kernel libretouch-initramfs libretouch-image

The files below are in build/deploy-ti/images/libretouch-net/:

File Used by
u-boot-spl-rndis.bin AM335x BootROM
u-boot.img U-Boot SPL
uImage U-Boot
initramfs.bin U-Boot
*_sm2.dtb, *_scm.dtb Device trees; U-Boot asks for the one the board's own data names, and for common_<module>.dtb if that is not there
libretouch-image-libretouch-net.rootfs.tar.gz NFS server

2. Create the USB network bridge

This example uses 192.168.1.100/24 for the host and bridges every predictable USB Ethernet interface (enx*). Do not use this glob if one of your ordinary network interfaces is also named enx*; replace it with a more specific name or match after checking networkctl list.

Choose one of the following methods. Do not install both the direct systemd-networkd files and the Netplan file.

systemd-networkd

Create /etc/systemd/network/10-br-usb.netdev:

[NetDev]
Name=br-usb
Kind=bridge

[Bridge]
STP=false

Create /etc/systemd/network/10-br-usb.network:

[Match]
Name=br-usb

[Link]
RequiredForOnline=no

[Network]
Address=192.168.1.100/24
ConfigureWithoutCarrier=yes
LinkLocalAddressing=no

Create /etc/systemd/network/20-usb-rndis.network:

[Match]
Name=enx*

[Link]
RequiredForOnline=no

[Network]
Bridge=br-usb
LinkLocalAddressing=no

Enable and restart networkd, then confirm that br-usb has the address and that connected USB devices become bridge ports:

sudo systemctl enable --now systemd-networkd
sudo systemctl restart systemd-networkd
networkctl status br-usb

Netplan using networkd

Create /etc/netplan/10-libretouch-usb-rndis.yaml:

network:
  version: 2
  renderer: networkd
  ethernets:
    usb-rndis:
      match:
        name: "enx*"
      optional: true
  bridges:
    br-usb:
      interfaces: [usb-rndis]
      addresses: [192.168.1.100/24]
      link-local: []
      parameters:
        stp: false
      optional: true

Apply it locally, preferably with a console available:

sudo netplan try

3. Configure dnsmasq for DHCP and TFTP

Install dnsmasq, create /etc/dnsmasq.d/libretouch-rndis.conf, and adjust the paths if needed:

# Serve only the isolated USB bridge.
interface=br-usb
bind-interfaces

# DHCP for all connected USB-RNDIS devices.
dhcp-range=192.168.1.101,192.168.1.200,255.255.255.0,12h
dhcp-option=option:router,192.168.1.100
dhcp-option=option:dns-server,192.168.1.100

# DHCP option 17: the NFS export path. U-Boot combines this with its DHCP
# server address, so this must be a path, not "host:path".
dhcp-option=17,/srv/libretouch/nfsroot

# The AM335x asks twice before Linux: once as the BootROM and once as SPL.
# Those requests must receive different files.
dhcp-vendorclass=set:am335xrom,AM335x ROM
dhcp-vendorclass=set:am335xspl,AM335x U-Boot SPL
dhcp-boot=tag:am335xrom,u-boot-spl-rndis.bin
dhcp-boot=tag:am335xspl,u-boot.img

enable-tftp
tftp-root=/srv/libretouch/tftp

The BootROM downloads u-boot-spl-rndis.bin; SPL downloads u-boot.img. After that, U-Boot uses TFTP itself to load the kernel, device tree, and initramfs. A single dhcp-boot line is therefore not sufficient.

Check the configuration and start the service:

sudo dnsmasq --test
sudo systemctl enable --now dnsmasq

4. Publish TFTP files and the NFS root

Create the directories and copy the current build outputs. Publish every SM2 device tree: U-Boot requests the name for the device it is booting.

sudo install -d -m 0755 /srv/libretouch/tftp /srv/libretouch/nfsroot

sudo install -m 0644 \
  build/deploy-ti/images/libretouch-net/u-boot-spl-rndis.bin \
  build/deploy-ti/images/libretouch-net/u-boot.img \
  build/deploy-ti/images/libretouch-net/uImage \
  build/deploy-ti/images/libretouch-net/initramfs.bin \
  /srv/libretouch/tftp/
sudo install -m 0644 build/deploy-ti/images/libretouch-net/*.dtb \
  /srv/libretouch/tftp/

sudo tar -xpf \
  build/deploy-ti/images/libretouch-net/libretouch-image-libretouch-net.rootfs.tar.gz \
  -C /srv/libretouch/nfsroot

Publish every deployed device tree the same way -- U-Boot names the one it wants at boot, so the whole set has to be there.

Add this line to /etc/exports:

/srv/libretouch/nfsroot 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)

Then enable the export:

sudo exportfs -ra
sudo systemctl enable --now nfs-server

When a new root filesystem is built, stop any running device, replace the contents of /srv/libretouch/nfsroot, and run sudo exportfs -ra again. The next boot uses it automatically. Changing DHCP option 17 changes the root path on the next boot without entering a U-Boot command.

5. Boot and check the handoff

Connect the Micro-USB setup port before applying power. Do not connect the USB-A port at the same time; both ports share the controller.

On the host, follow the service logs:

sudo journalctl -fu dnsmasq

To capture the complete exchange, start Wireshark on br-usb before applying power. A capture filtered with bootp || tftp shows the BootROM request, the SPL request, and each TFTP file name without having to follow changing USB interface names.

The log should show separate DHCP/TFTP activity for u-boot-spl-rndis.bin and u-boot.img, followed by TFTP requests for uImage, the device tree, and initramfs.bin. Linux then reconnects as a USB Ethernet device, obtains another lease on br-usb, and mounts the NFS root.

Use the serial console for the boot log if a stage fails. The expected root source after Linux starts is the NFS export, not the initramfs.