User Container
The user container setup is designed to support all the included hardware. A number of external devices will also be supported by the USB host controller. The initial support will be for audio, video, mass storage devices and Kvaser USB CAN devices.
Device information
Device information can be retrieved from the device tree under kvaser-parameters.
Examples:
# Read serial number
$ cat /proc/device-tree/kvaser-parameters/serial-number
1234
# Read EAN code
$ cat /proc/device-tree/kvaser-parameters/ean
73-30130-99999-9
USB Mass Storage Devices
Any FAT-formatted partition of a connected USB mass storage is automatically
mounted under /host/mnt/<mountpoint>, where <mountpoint> is either
the partition label, or if no label exists the device's USB iProduct string.
Note
Every partition on all connected devices must use unique labels (or have
unique USB iProduct strings), otherwise the resulting behavior is
undefined.
Multicolor LED Handling
The system groups red, green, and blue LEDs into multicolor LEDs using the LED class multicolor interface. This makes it convenient to manage each RGB LED as a single logical unit.
Examples:
# Check which color channels are available
$ cat /sys/class/leds/multi\:led1/multi_index
red green blue
# Set individual RGB values
$ echo 50 100 200 > /sys/class/leds/multi\:led1/multi_intensity
# Set overall brightness
$ echo 100 > /sys/class/leds/multi\:led1/brightness
Each multicolor LED "owns" the underlying color LEDs, meaning they cannot be controlled directly while bound.
If direct control of individual channels is needed, you can unbind the multicolor LED:
$ echo led1-multi > /sys/bus/platform/drivers/leds_group_multicolor/unbind
$ echo 50 > /sys/class/leds/green\:led1/brightness
Note
Unbinding disables grouped control, so RGB values can no longer be set together via the multicolor interface.
GPIO
The available GPIO pins can be found in gpiochip5 (/dev/gpiochip5). They can
be accessed with libgpiod. If you are building your own custom container image you can
add gpiod to the package list (see mkosi),
otherwise see the build instructions
for libgpiod.
To list all available GPIO lines and their properties:
$ gpioinfo
To monitor an input pin:
$ gpiomon NAME_OF_GPIO_LINE
Note
On distros with libgpiod older than v2.0, the libgpiod tools doesn't
resolve GPIO line names. Use gpiochip name and offset instead i.e
"$ gpiomon gpiochip5 0". Or resolve the name with gpiofind i.e
"$ gpiomon $(gpiofind NAME_OF_GPIO_LINE)"
To set and get the value of gpio lines:
$ gpioset NAME_OF_GPIO_LINE=1
$ gpioget NAME_OF_GPIO_LINE
For further information and examples check the libgpiod documentation.
IMU
The available devices are an accelerometer, lsm6dso_accel, and a gyroscope,
lsm6dso_gyro. Use iio_info to list available devices and their properties:
$ iio_info
libiio
provides tools and utilities to interact with the IMU devices, there is a command
line tool, libiio-util, there is also a C service library, libiio-dev. It is
also possible to access the raw device, /dev/iio:deviceX and it's correponding
sysfs attributes in /sys/bus/iio/devices/iio:deviceX, but the device numbers
may change between boots and updates.
Polling mode
In polling mode the values of the device is read directly, this can be done using
iio-attr from libiio-utils. Hardware timestamping is not supported in this
mode.
Gyroscope example:
$ iio_attr -c lsm6dso_gyro anglvel_x raw
This would get the raw value for the x-axis of the gyroscope.
Accelerometer example:
$ iio_attr -c lsm6dso_accel accel_z raw
$ iio_attr -c lsm6dso_accel accel_z scale
The z-axis value can then be multiplied by the scale value and the result should be around 9.81 m/s^2, when the unit is lying flat on a table.
Buffer mode
In buffer mode iio_readdev is used to specify which channels to sample and
iio_attr can be used to change device and channel attributes before hand, use
iio_info to find the available attributes. Hardware timestamping is supported
in this mode.
The sampling frequency can be adjusted to one of the available frequencies. When using smaller sampling frequencies the buffer needs to be adjusted to a smaller size to not run into buffer errors.
# Get the available frequencies of the device
$ iio_attr -d lsm6dso_accel sampling_frequency_available
# Set the desired frequency
$ iio_attr -d lsm6dso_accel sampling_frequency 26
Example:
$ iio_readdev -b 1 -s 4 lsm6dso_gyro anglvel_x anglvel_y anglvel_z timestamp > data.dat
The example would write four samples of the angle velocity in the x-, y- and z-axises, as well as the timestamp, to data.dat.
The output is binary data. hexdump can be used for inspecting the samples.
$ hexdump -d data.dat
GPS/GNSS
The GPS device can be found at /dev/gnss0, to monitor geo-location data gpsd
can be used. gpsd supplies many different tools to interface with the GNSS
receiver, below are some quick examples, to see the full extent check the documentation.
To enable the GNSS device the default configuration need to be edited. Edit
the file /etc/defult/gpsd and change the settings to match what is given below:
GPSD_OPTIONS="-n"
DEVICES="/dev/gnss0"
cgps is a terminal client for gpsd and can be used to view data from the GNSS
device:
$ cgps
gpsmon can be used to monitor the packets coming from the device and how the
packets are displayed can be configured. The full extend can be seen in the
documentation.
There is also a C service library, libgps, which enables communication with
the daemon. Information and examples can be found
here.
Workarounds
The following table shows some limitations when running in a container and the workarounds.
Regulatory domain control from container
Normally, changing the wireless regulatory domain is restricted to users with
CAP_NET_ADMIN in the initial (root) user namespace. This restriction
prevents unprivileged containers from managing Wi-Fi region settings.
Workaround
A kernel patch has been applied to allow setting the regulatory domain from
any user namespace, as long as the process has CAP_NET_ADMIN inside its
namespace.
This makes the following now work from inside the container:
$ iw reg set SE
Warning
Because of this, only trusted code should be granted CAP_NET_ADMIN inside
containers. Misuse could lead to regulatory violations or disrupt wireless
behavior on the system.
System reboot and suspend
A reboot inside the user container will only restart the container. The container does not have the required privileges for controlling the system power state.
Workaround
Use the hostctl CLI to control host functions.
LED triggers
LED timer trigger control for delay_on/delay_off is created with wrong
user/group id. The user/group id is changed by an udev script running in the
host system.
Workaround
Add a short delay before accessing the trigger control:
echo timer > /sys/class/leds/\*/trigger
sleep 0.1
echo 100 > /sys/class/leds/\*/delay_on
System time
System time can not be set from the container.
Workaround
An ntpd service is running with privileges for setting system time. The
status of the service can be checked with commands such as ntpstat or ntpq.
No udevd
In the user container there is no udev. Standard services containing device
unit configurations wont work, i.e.
Requires=sys-subsystem-net-devices-%i.device.
Workaround
Comment out the device dependency:
$ systemctl edit --full wpa_supplicant-nl80211@.service
$ systemctl cat wpa_supplicant-nl80211@.service
# /etc/systemd/system/wpa_supplicant-nl80211@.service
[Unit]
Description=WPA supplicant daemon (interface- and nl80211 driver-specific version)
#Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
Before=network.target
Wants=network.target
...