Device-Type enablement
This guide will quickly explain how to enable a new Device-Type in LAVA using an LAA.
Hardware support
In this guide, we suppose that the LAA does provide the right hardware feature to automate the new device-type.
For example, the board can be powered by 1v8, 3v3, 5v or 12v or from USB PD.
laam laacli
In order to use this guide, you should already be familiar with the laam tool.
Choosing the MIB
Start by choosing the MIB that will allow to automate your new DUT.
Unless your Device-Type is already supported by an existing MIB, use the flylead MIB.
Connect the chosen MIB to the SIB using the SIB header.
Powering the DUT
USB powered
If the DUT is powered via USB, connect the LAA USB port 1 to the right port on the DUT.
The DUT can now be powered-on and off using:
laam laacli usb 1 on
laam laacli usb 1 off
Power rails
If the DUT can be powered via a pin or a jack port, connect the DUT pin to one of the power rails on the MIB.
The DUT can now be powered-on and off using:
laam laacli power <RAIL> on
laam laacli power <RAIL> off
Where RAIL would be 1v8
, 3v3
, 5v
or 12v
.
Serial console
In order to interact with the DUT, LAVA will need to have access to the serial console.
Direct UART
Connect the UART to one of the available UARTs on the MIB or the sib-header
UART port
We advice you to use SIB_UART4
as this is already fully configured to be used
by LAVA with telnet localhost 2000
.
You can use laam
to interact with the console from your laptop using laam serial connect ttymxc3
.
Serial over USB
Connect the USB cable to the LAA USB port 2.
ser2net configuration
Currently, the following serials are supported by the ser2net configuration:
Device |
Type |
Baud rates |
Configs |
Port |
Name |
---|---|---|---|---|---|
/dev/ttymxc3 |
SIB_UART4 |
115200 |
n81 |
2000 |
ttymxc3 |
/dev/ttyUSB0 |
USB |
115200 |
n81 |
2010 |
ttyUSB0 |
/dev/ttyUSB1 |
USB |
115200 |
n81 |
2011 |
ttyUSB1 |
/dev/ttyACM0 |
USB |
115200 |
n81 |
2020 |
ttyACM0 |
/dev/ttyACM1 |
USB |
115200 |
n81 |
2021 |
ttyACM1 |
You can connect to the device using laam serials connect <NAME>
.
LAVA Support
If the above commands are enough to get the DUT to boot into the bootloader, then LAVA will be able to use your DUT to test the OS or user space applications.
You will need to write to jinja2 files:
device-type template: device-type generic information
device dictionary: DUT specific configuration
laam dut
helper
The laam
utility provide an helper to generate the device-type template and
the device dictionary from a simple configuration file.
See laam dut helper.
Device-type template
The device-type template is a jinja2 template that explains to LAVA the supported features for the device-type.
The list of upstream device-type is available in LAVA sources.
Depending on the bootloader on the DUT, the device-type template and the device dictionary will differt.
u-boot
If using u-boot, the device-type template will look something like:
{# set device_type = "<DTB_NAME>" #}
{% extends 'base-uboot.jinja2' %}
{% set booti_kernel_addr = booti_kernel_addr|default('<BOOTI_KERNEL_ADDR>') %}
{% set booti_ramdisk_addr = booti_ramdisk_addr|default('<BOOTI_RAMDISK_ADDR>') %}
{% set booti_dtb_addr = booti_dtb_addr|default('<BOOTI_DTB_ADDR>') %}
{% set bootm_kernel_addr = bootm_kernel_addr|default('<BOOTM_KERNEL_ADDR>') %}
{% set bootm_ramdisk_addr = bootm_ramdisk_addr|default('<BOOTM_RAMDISK_ADDR>') %}
{% set bootm_dtb_addr = bootm_dtb_addr|default('<BOOTM_DTB_ADDR>') %}
{% set uboot_mkimage_arch = 'arm64' %}
{% set bootloader_prompt = bootloader_prompt|default('U-Boot>') %}
{% set console_device = console_device|default('ttyS1') %}
Adapting the template
Set the variables to the right values for your device-type.
Device-dictionary
The device dictionary is DUT specific and indicate to LAVA how to power on/off/reset the DUT or access the serial console. Based on the initial part of the guide, you should have the list of commands ready now.
{% extends '<DTB_NAME>.jinja2' %}
{% set hard_reset_command = [
'<LAACLI_POWER_OFF>',
'<LAACLI_POWER_ON>'
] %}
{% set power_off_command = [
'<LAACLI_POWER_OFF>'
] %}
{% set power_on_command = [
'<LAACLI_POWER_ON>'
] %}
{% set connection_command = 'telnet localhost <SERIAL_PORT>' %}
{% set usbg_ms_commands = {
'disable': ['laacli', 'usbg-ms', 'off'],
'enable': ['laacli', 'usbg-ms', 'on', '{IMAGE}']
} %}
{% set docker_shell_extra_arguments = [
'--volume=/usr/bin/laacli:/usr/bin/laacli:ro',
'--volume=/usr/bin/lsibcli:/usr/bin/lsibcli:ro',
'--volume=/run/dbus/system_bus_socket:/run/dbus/system_bus_socket:rw'
] %}
laam dut
helper
The laam
tool provides a dut helper to create and test LAVA device-type
template and device dictionary. The tool is using a custom configuration file
that is used to auto-generate the LAVA files.
RPi4
For this guide, we will use an RPi4B as DUT.
Configuration file
Start by creating a new configuration file with:
$ laam dut new rpi4.yaml
Create a new device configuration (u-boot only)
dtb name> bcm2711-rpi-4-b
device-type name
By convention, LAVA uses the dtb filename as device-type name. Following the convention will make upstreaming easier.
The file now contains:
bootloader: u-boot
interrupt: true
name: bcm2711-rpi-4-b
power:
'off': []
'on': []
reset: []
prompt: '=> '
serial: ttymxc3
The parameters are:
bootloader
: should always beu-boot
for the momentinterrupt
: should u-boot be interruptedname
: dtb filenamepower
: dictionary of power commands. Should use laam laacli commandsprompt
: u-boot promptserial
: name of the serial console
Power commands
Add the power commands (and the bootloader prompt) to the configuration file:
bootloader: u-boot
interrupt: true
name: bcm2711-rpi-4-b
power:
'off': ["laam laacli power 3v3 off", "laam laacli power 5v off"]
'on': ["laam laacli power 5v on", "laam laacli power 3v3 on"]
reset: ["laam laacli power 5v reset", "laam laacli power 3v3 on"]
prompt: 'U-Boot> '
serial: ttymxc3
Boot test
Based on this configuration file, laam can try to boot the DUT:
$ laam dut test rpi4.yaml --usbg-ms boot-rpi4.img
Connect to serial
=> ttymxc3
Push USBG-MS file
Reset the DUT
=> laam laacli power 5v reset
power 5v off
sleep 5
power 5v on
=> laam laacli power 3v3 on
Interrupt bootloader
<serial> Connecting to ws://laa-00006.local/ws/ port 2000
<serial> [Telnet] connected to 127.0.0.1:2000
<serial>
<serial> ser2net port telnet(rfc2217),tcp,localhost,2000,172.17.0.1,2000 device keepopen,serialdev, /dev/ttymxc3, 115200n81,local [115200N81,CLOCAL,HANGUP_WHEN_DONE]
<serial>
<serial>
<serial>
<serial> U-Boot 2024.01 (Apr 10 2025 - 11:24:17 +0000)
<serial>
<serial> DRAM: 947 MiB (effective 3.9 GiB)
<serial> RPI 4 Model B (0xc03114)
[...]
<serial> scanning bus xhci_pci for devices... 3 USB Device(s) found
<serial> scanning usb for storage devices... 1 Storage Device(s) found
Wait for prompt 'U-Boot> '
<serial> Hit any key to stop autoboot: 0
Test USB support
<serial> U-Boot> usb start; usb info
<serial> 1: Hub, USB Revision 3.0
[...]
<serial> 2: Hub, USB Revision 2.10
[...]
<serial> 3: Mass Storage, USB Revision 2.1
<serial> - LAA USB Mass Storage Gadget 123456
<serial> - Class: (from Interface) Mass Storage
<serial> - PacketSize: 64 Configurations: 1
<serial> - Vendor: 0x1d6b Product 0x0104 Version 0.1
<serial> Configuration: 1
<serial> - Interfaces: 1 Bus Powered 500mA
<serial> - String: "1xMass Storage"
<serial> Interface: 0
<serial> - Alternate Setting 0, Endpoints: 2
!!! USB ok !!!
<serial> - Class Mass Storage, Transp. SCSI, Bulk only
<serial> - String: "Mass Storage"
<serial> - Endpoint 1 In Bulk MaxPacket 512
<serial> - Endpoint 1 Out Bulk MaxPacket 512
<serial>
Test network support
<serial> U-Boot> dhcp; ping 198.18.0.1
<serial> ethernet@7d580000 Waiting for PHY auto negotiation to complete.... done
[...]
<serial> host 198.18.0.1 is alive
!!! Network ok !!!
Power off the DUT
=> laam laacli power 3v3 off
=> laam laacli power 5v off
USBG-MS
For this specific DUT, the bootloader is provided via USB mass storage
emulation so we have to provide an image via
--usbg-ms
.
This image comes from https://firmwares.lavacloud.io/rpi-4-b/boot.img.zst.
LAVA templates
Based on the configuration file, laam
can now generate a device-type template
and a device dictionary to use with the LAA:
$ laam dut render rpi4.yaml bcm2711-rpi-4-b.jinja2 rpi4-laa.jinja2
Device-type template: 'bcm2711-rpi-4-b.jinja2' (should be called 'bcm2711-rpi-4-b.jinja2')
Device dictionary: 'rpi4-laa.jinja2'
A simple device-type template as been generated and can be used by LAVA:
{% extends 'base-uboot.jinja2' %}
{% set uboot_needs_interrupt = uboot_needs_interrupt | default(True) %}
{% set bootloader_prompt = bootloader_prompt | default('U-Boot> ') %}
The corresponding device-dictionary that can be used with LAVA and an LAA:
{% extends 'bcm2711-rpi-4-b.jinja2' %}
{% set hard_reset_command = [
'laacli power 5v reset',
'laacli power 3v3 on'
] %}
{% set power_off_command = [
'laacli power 3v3 off',
'laacli power 5v off'
] %}
{% set power_on_command = [
'laacli power 5v on',
'laacli power 3v3 on'
] %}
{% set connection_command = 'telnet localhost 2000' %}
{% set usbg_ms_commands = {
'disable': ['laacli', 'usbg-ms', 'off'],
'enable': ['laacli', 'usbg-ms', 'on', '{IMAGE}']
} %}
{% set docker_shell_extra_arguments = [
'--add-host=lava-worker.internal:host-gateway',
'--volume=/usr/bin/laacli:/usr/bin/laacli:ro',
'--volume=/usr/bin/lsibcli:/usr/bin/lsibcli:ro',
'--volume=/run/dbus/system_bus_socket:/run/dbus/system_bus_socket:rw'
] %}
Recovery
Recovering from a bad firmware is not considered in the guide yet as this involved more complex setup.