Embedded,  Linux,  uboot,  ubuntu

Configuring Ubuntu to deal with an ARM board with U-Boot via USB

Abstract

We have a board on which an AllWinner ARM processor is running Linux. The bootloader is U-boot and we have to use the USB port to flash it.

When flashing the device for the first time, after loading the bootloader via FEL protocol, we need to use tftp to load the SPL (Secondary program Loader) image and the uboot version for use with the spl.

Unfortunately, a couple of issues in the default Ubuntu configuration prevent us from doing this apparently simple operation in a straight way, and we need to tweak some system configuration file.

The issue

After using the sunxi-fel tool to run the bootloader in memory, we need to use the tftp protocol to load the uboot image and other files in order to flash them into the NAND memory.

Uboot can use different ways to do this, but in our setup we have only have the USB cable between the host pc and the device.

Uboot has been compiled with support for usb device, ethernet over usb and tftp protocol.

When launching the tftp command from uboot, a ethernet over usb interface is enabled and the linux kernel on the host pc assign a network device to it.

Since systemd 196, the usual “usbX” name aren’t used anymore, but instead a “predictable network name” is used instead, so the new interface will take a name like “enp0s34e66c2”. Not very predictable, from the user perspective.

If we don’t want to install a DHCP server (it can screw the local network if not properly installed), the problems arises. Since the use of NetworkManager applet, we can’t assign an IP to a network device anymore, because the NetworkManager configure it based on the Mac Address, and sometimes uboot assigns a random mac address to the new device.

So, we the only option I found so far is to disable the NetworkManager completely, but that doesn’t seem a big deal.

The solution

The solution requires three steps:

  1. disable the NetworkManager for the usb device only.
    This way, we prevent NetworkManager from trying to configure the interface.
  2. disable the “predictable network name” for the specific usb device.
    So, even if we change the Usb port, the name will be really “predictable”, something like “usbX” instead of “enpXYZ“.
  3. configure a static ip address for the ethernet device
    Using /etc/network/interfaces as we used to do before systemd 196.

Disable NetworkManager

Our “non predictable” device name will be “usbX”, so we’re going to disable the NetworkManager for “usb?” device patterns. Let’s change the /etc/NetworkManager/NetworkManager.conf file, by adding this to the “[device]” section:

[devices]
match-device=interface-name:usb
managed=0

Disable the “predictable network names” for the device

We’re going to use udev to change this configuration. I have a special udev rule file for my device, that is identified by ProductId 0x1234 and VendorId 0x5678.

So let’s create the udev rule in /etc/udev/rules.d/99-mydevice.rules

SUBSYSTEM=="net", ACTION=="add", ATTRS{idVendor}=="5678", ATTRS{idProduct}=="1234", NAME="usb0"

There might be other lines, if for example you need to assign groups to the newly created device nodes. This is beyond the scope of this article, of course.

Configuring the network

This is the old way to configure networks before systemd 196.

So let’s add the following lines to the /etc/network/interfaces file.

iface usb0 inet static
    address 10.0.0.1
    netmask 255.0.0.0

Note that we could have used a dhcp server bound to the usb network interface instead. But usb0 doesn’t exists until it has been enabled by the board itself, so it might be difficult to configure the dhcp server without binding it to all the networks (0.0.0.0), and this may screw up the local network, if you don’t filter out responses using netfilter.

So I guess this is the easiest way to allow booting the board.

%d bloggers like this: