CuBox-i support in Debian
Contents
This page exists to collate information about the status of support in Debian for the CuBox-i family of devices by SolidRun (CuBox-i1, CuBox-i2, CuBox-i2Ultra, CuBox-i4Pro).
General information
The CuBox-i devices are a series of small-footprint, always-on computers based on the FreeScale i.MX6 chipset.
Bootloader support
The CuBox-i uses U-Boot as a bootloader, and is supported by the U-Boot version in Debian 9/Stretch onwards.
The CuBox-i U-Boot uses SPL (allowing the same U-Boot image to be used across multiple models), and should be installed to the SD card using the layout described here. Note that this version of U-Boot will also support reading the second-stage bootloader from a FAT filesystem on the first partition of the device; however, since U-Boot also reads its environment from an offset of 384K on the SD card, there is 342K of reserved space at the front of the disk which will be otherwise unused. It is therefore recommended to install U-Boot to the embedded space at the front of the disk, and not to set up a dedicated boot partition on the SD card.
Kernel support
The CuBox-i is supported by the armmp linux kernel (4.9+) in Debian Stretch including serial console, usb, ethernet, mmc, HDMI, eSATA and ir receiver.
Installing Debian
Starting from Debian 8/Jessie, the cubox-i and hummingboard are supported through the official debian installer.
For Debian stable, instructions for pre-build images can be found in the official documentation of the Debian Installer.
- Daily images of the Debian Installer are also available for:
Be prepared to attach a serial console to your cubox-i/hummingboard, because the installer does not output on the HDMI interface. This can be done for example by installing GNU Screen and launching:
screen /dev/ttyUSB0 115200
The serial console is available both in the installer and after rebooting into a newly installed (buster) system.
An alternative to GNU Screen is busybox microcom
busybox microcom -d 20 -s 115200 /dev/ttyUSB0
An important feature to avoid characters when pasting into the u-boot shell is to be able to specify inter-character delays (-d 20 means 20 ms).
Desktop Environments
On Debian 10/Buster GNOME defaults to Wayland and works out of the box. Still it is important to boot the kernel with the cma=... parameter set, e.g. cma=256M:
# echo 'setenv bootargs ${bootargs} cma=256M' | tee /etc/flash-kernel/ubootenv.d/cma && flash-kernel
See also cma entry for the Wandboard
Ethernet HW Errata ERR004512
ERR004512 results in a risk of ethernet RX FIFO overrun on the i.MX6 chip in the Cubox-i.
A solid description of the issue and workarounds implemented in the Linux kernel is given at Boundarydevices
Good news is that is seems that Debian buster contains at least the most relevant patches. But even with these patches, it is required to enable flow control on the switch which connects to the Cubox-i. With flowcontrol I saw bandwidths of around 400 MBit/s for TX and 600 MBit/s for RX with Debian buster (measured by iperf). With Debian stretch I saw that enabling flow control also removes the overflows and increases the measured bandwidth, but it was lower than with the buster installation (even with a backports kernel).
With link level flow control enabled, there should be no RX overruns or dropped frames as shown below:
rd@home:~$ /sbin/ifconfig eth0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::d263:b4ff:fe00:325c prefixlen 64 scopeid 0x20<link> ether d0:63:b4:00:32:5c txqueuelen 1000 (Ethernet) RX packets 133763491 bytes 1832846878 (1.7 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 11202123 bytes 395662770 (377.3 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 rd@home:~$
Without link level flow control, there may be RX fifo overruns and dropped frames on the cubox ethernet network interface. I have seen bandwidth degradation down to 2 MBit/s on the RX side. I think the latency for retries determines the performance degradation...i.e. on the local networks the bandwidths are still higher if talking to a remote machine on the WAN, severe drops must be expected.
Troubleshooting the boot process
The standard U-Boot boot process executes the boot command, which expands to run bootcmd.
The boot process may be interrupted as described in U-Boot
The boot procedure can now be traced down using the definition of bootcmd and other variables, which can be shown using
=> printenv
In bullseye, this is a generic procedure which typically ends in the execution of /boot/boot.scr.
Loading a kernel is performed in u-boot consists of three essential steps:
1. setting bootargs: kernel parameters are defined in the environment variable, e.g. the root filesystem.
(Example: setenv bootargs "enable_wait_mode=off root=UUID=233113e0-67d1-409f-b2c0-57bd496213de rootfstype=ext4 ro rootwait console=ttymxc0,115200 console=tty1 break" )
2. Loading kernel, initial ramdisk (initrd.img), and the device tree (dtb) into the ram
(Example: load mmc 1:2 ${kernel_addr_r} vmlinuz-${ver} )
3. Starting the kernel
(Example: bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} )
A simple procedure to start a system installed on a microSD card manually
Determine mmc device and set local_mmcdev:
=> mmc list FSL_SDHC: 1 (SD) FSL_SDHC: 2 => mmc dev 2 Card did not respond to voltage select! : -110 => mmc dev 1 switch to partitions #0, OK mmc1 is current device => setenv local_mmcdev 1 =>
(on an alternative system I get
CuBox-i U-Boot > mmc list FSL_SDHC: 0 CuBox-i U-Boot > mmc dev 0 switch to partitions #0, OK mmc0 is current device CuBox-i U-Boot >
)
Show available mmc partitions
=> mmc part Partition Map for MMC device 1 -- Partition Type: DOS Part Start Sector Num Sectors UUID Type 1 32768 267232 8ad3fb70-01 0c 2 301056 999424 8ad3fb70-02 83 Boot 3 1300480 119515136 8ad3fb70-03 83 4 120817662 1990658 8ad3fb70-04 05 Extd 5 120817664 1990656 8ad3fb70-05 82 =>
Find boot partition (you might have to try several partitions):
=> ext4ls mmc ${local_mmcdev}:2 <DIR> 1024 . <DIR> 1024 .. <DIR> 12288 lost+found 250465 config-5.10.0-10-armmp 4960768 vmlinuz-5.10.0-10-armmp <SYM> 26 initrd.img.old <SYM> 23 vmlinuz.old <DIR> 1024 dtbs 83 System.map-5.10.0-10-armmp <SYM> 26 initrd.img <SYM> 23 vmlinuz <SYM> 40 dtb-5.10.0-10-armmp <SYM> 40 dtb 23951051 initrd.img-5.10.0-10-armmp 4499 boot.scr.bak 4512 boot.scr =>
Set boot partition number
=> setenv local_bootpart 2
Find root partition (you might have to try several partitions)
=> ext4ls mmc ${local_mmcdev}:3 <DIR> 4096 . <DIR> 4096 .. <DIR> 16384 lost+found <DIR> 4096 boot <DIR> 4096 etc <DIR> 4096 media <DIR> 4096 var <SYM> 7 bin <DIR> 4096 usr <SYM> 8 sbin <SYM> 7 lib <DIR> 4096 dev <DIR> 4096 home <DIR> 4096 proc <DIR> 4096 root <DIR> 4096 run <DIR> 4096 sys <DIR> 4096 tmp <DIR> 4096 mnt <DIR> 4096 srv <DIR> 4096 opt =>
Set root filesystem (partition number at the end)
=> setenv local_rootfs root=/dev/mmcblk${local_mmcdev}p3
Setting the block device is error prone, I have seen a system in which the mmcdev was different in u-boot (mmcdev=0) and the linux kernel (mmcdev=1). I this case the boot process ends likely in an initram debug shell. The situation there can be inspected by
ls /dev/mmcblk*
The much more robust way to set the root filesystem is to use the UUID. The UUID can be best determined on a separate system, when the partition is mounted it should be visible there in /dev/disk/by-uuid/
=> setenv local_rootfs root=UUID=08d60447-3547-4fd3-9231-33d884e139eb =>
Unfortunately, the UUID I got from "part uuid" did not work for me.
=> part uuid mmc ${local_mmcdev}:3 8ad3fb70-03 =>
Enable a console on the serial interface
=> setenv local_bootargs "console=ttymxc0,115200" =>
Define bootcmd_local (filesize is set by the load command)
=> setenv bootcmd_local 'mmc dev ${local_mmcdev} && mmc rescan && setenv bootargs ${local_rootfs} ${local_bootargs} && load mmc ${local_mmcdev}:${local_bootpart} ${kernel_addr_r} vmlinuz-${local_kver} && load mmc ${local_mmcdev}:${local_bootpart} ${fdt_addr_r} dtbs/${local_kver}/imx6q-cubox-i.dtb && load mmc ${local_mmcdev}:${local_bootpart} ${ramdisk_addr_r} initrd.img-${local_kver} && bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}' =>
Set kernel version to boot:
=> setenv local_kver "5.10.0-10-armmp" =>
Optionally save the environment on the microSD card (at any time in this sequence) and get it restored after the next boot
=> saveenv Saving Environment to MMC... Writing to MMC(1)... OK =>
load kernel, device tree, and initrd into RAM and boot Linux zImage stored in RAM
=> run bootcmd_local switch to partitions #0, OK mmc1 is current device [...]
The entire process heavily depends that the addresses you load the kernel, device tree, and initial RAM disk are correct. For my cubox-i the bullseye installer uses
=> printenv kernel_addr_r kernel_addr_r=0x12000000 => printenv fdt_addr_r fdt_addr_r=0x18000000 => printenv ramdisk_addr_r ramdisk_addr_r=0x13000000 =>
${filesize} is set by the load command to the size of the loaded data.
(in previous Debian versions, different addresses have been used
kernel_addr_r=0x10800000 ramdisk_addr_r=0x11800000 fdt_addr_r=0x18000000
This caused that my bullseye kernel failed to boot )
Further info
Thomas Bechtold's blog entry about bootstrapping a SD-Card with Debian Stretch for Cubox-4i
Gunnar Wolf's blog entry about bootstrapping a CuBox-i4
Rainer's notes on bootstrapping a CuBox-i4
The CuBox-i wiki
Armbian by Igor Pečovnik is a Debian-derived distribution