TS-4100 Debian Sections
Debian 13 - Trixie
Debian 13 - Getting Started
This Debian release is available in 2 flavors with various packages. See our Debian releases in the Software Images section for links to the latest images available.
| Image | Description |
|---|---|
| Headless |
|
| Minimal |
|
The default login is root with no password.
Debian 13 - Networking
The network in Debian is configured with /etc/network/interfaces. For complete documentation, see Debian's documentation here
Some common examples are shown below. On this release network interfaces follow the predictible network interface names. Run ip addr show to get a list of the network interfaces.
Most commonly:
- end0 - Ethernet device 0 (CPU Ethernet)
- enp1s0 - Ethernet PCIe port 1 slot 0 Ethernet
- usb<mac> - USB Ethernet
- wlan0 - Wi-Fi
DHCP on end0. Create the file /etc/network/interfaces.d/end0 with the contents:
allow-hotplug end0 iface end0 inet dhcp
Static IP on end0. Create the file /etc/network/interfaces.d/end0 with the contents:
allow-hotplug end0
iface end0 inet static
address 192.0.2.7/24
gateway 192.0.2.254
These will take effect on the next boot, or by restarting the networking service:
service networking restart
Debian 13 - Wi-Fi Client
Wireless interfaces are also managed with configuration files in /etc/network/interfaces.d/. For example, to connect as a client to a WPA network with DHCP. Note some or all of this software may already be installed on the target.
Install wpa_supplicant:
apt-get update && apt-get install wpasupplicant -y
Run:
wpa_passphrase youressid yourpassword
This command will output information similar to:
network={
ssid="youressid"
#psk="yourpassword"
psk=151790fab3bf3a1751a269618491b54984e192aa19319fc667397d45ec8dee5b
}
Use the hashed PSK in the specific network interfaces file for added security. Create the file /etc/network/interfaces.d/wlan0 with the contents:
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid youressid
wpa-psk 151790fab3bf3a1751a269618491b54984e192aa19319fc667397d45ec8dee5b
To have this take effect immediately:
service networking restart
For more information on configuring Wi-Fi, see Debian's guide here.
Debian 13 - Wi-Fi Access Point
hostapd needs to be installed if it is not already in order to manage the access point on the device:
apt-get update && apt-get install hostapd -y
| Note: | The install process will start an unconfigured hostapd process. This process must be killed and restarted before new hostapd.conf contents will take effect.
|
Edit /etc/hostapd/hostapd.conf to include the following lines:
interface=wlan0
ssid=YourWiFiName
wpa_passphrase=Somepassphrase
interface=wlan0
channel=7
driver=nl80211
logger_stdout=-1 # Print all module output to standard out
logger_stdout_level=2 # Print informational messages to standard out
wpa=2
wpa_key_mgmt=WPA-PSK
| Note: | Refer to the kernel's hostapd documentation for more wireless configuration options. |
To start the access point launch hostapd:
hostapd /etc/hostapd/hostapd.conf &
This will start up an access point that can be detected by Wi-Fi clients. A DHCP server will likely be desired to assign IP addresses. Refer to Debian's documentation for more details on DHCP configuration.
Debian 13 - Wi-Fi Concurrent Client / Access Point
The Wi-Fi device on this platform supports concurrent operation of client and access point (STA and AP). Please see the "Wi-Fi Client" section above first to connect the Wi-Fi module, in STA mode, to an external AP. This demo showcases the Wi-Fi module starting its own AP mode via hostapd with a simple static IP address while also being concurrently connected to a separate AP.
The hostapd utility is used to manage the access point mode. This is usually installed by default, but can separately be installed with:
apt-get update && apt-get install hostapd -y
| Note: | The install process may start an unconfigured 'hostapd' process. This process must be killed before moving forward. |
Modify the file /etc/hostapd/hostapd.conf to have the following lines:
ssid=YourWiFiName
wpa_passphrase=Somepassphrase
interface=p2p0
auth_algs=3
channel=<channel>
driver=nl80211
logger_stdout=-1
logger_stdout_level=2
wpa=2
wpa_key_mgmt=WPA-PSK
| Note: | The channel used for AP must match the channel the STA is using! Be sure to set 'channel=...' in the above file to a proper channel number. |
| Note: | Refer to the kernel's hostapd documentation for more wireless configuration options. |
In order for the concurrent modes to work, a separate virtual wireless device must first be created. Note that hostapd.conf above lists interface=p2p0, a virtual interface with this name must be created:
iw wlan0 interface add p2p0 type managed
The access point can then be started and tested by hand:
hostapd /etc/hostapd/hostapd.conf &
An IP address can be set to p2p0:
ifconfig p2p0 192.168.0.1
From this point, other Wi-Fi clients can connect to the SSID YourWiFiName with the WPA2 key Somepassphrase with a static IP in the range of 192.168.0.0/24, and will be able to access the platform at 192.168.0.1. More advanced configurations are also possible, including bridging, routing/NAT, or simply separate networks with the Wi-Fi module connecting to a network and hosting its own private network with DHCP.
Debian 13 - Installing New Software
Debian uses the Advanced Package Tool (APT) suite to manage installation of prebuilt applications. The APT tools require a network connection to the internet in order to automatically download and install new software. The update command will download a list of the current versions of available packages:
apt-get update
A common example is installing a simple web server like nginx. Find the package name first with search, and then install it:
root@host:~# apt-cache search nginx ... nginx - small, powerful, scalable web/proxy server nginx-common - small, powerful, scalable web/proxy server - common files nginx-core - nginx web/proxy server (standard version) nginx-dev - nginx web/proxy server - development headers nginx-doc - small, powerful, scalable web/proxy server - documentation nginx-extras - nginx web/proxy server (extended version) nginx-full - nginx web/proxy server (standard version with 3rd parties) nginx-light - nginx web/proxy server (basic version) nginx-confgen - nginx configuration file macro language and preprocessor ...
In this case, the wanted package will likely be the nginx package itself. Names of packages can be found on Debian's wiki pages or the Debian packages site.
With the package name apt-get install can be used to install the prebuilt packages.
apt-get install nginx
# More than one package can be installed at a time.
apt-get install nginx nano vim vbindiff
For more information on using the various APT tools, refer to Debian's APT documentation.
Debian 13 - Controlling GPIO
This distribution uses the gpiod (version 2.2.x) suite of tools and libraries for GPIO control.
In the 2.2.x releases, GPIO control revolves around GPIO line labels. Every GPIO present on the platform can be listed with gpioinfo:
root@host:~# gpioinfo
gpiochip0 - 32 lines:
line 0: unnamed input
line 1: unnamed input
line 2: unnamed output active-low consumer=red:status
...
gpiochip1 - 32 lines:
...
line 11: "USB_HUB_RESET#" output
...
line 19: "EN_MODBUS_24V" input
line 22: "EN_USB_5V" output
...
The first column, gpiochipX - YY lines lists the GPIO chip number and how many lines are connected to it. The second column, line xx:, lists the line number. The third column lists the name/label of that line. And the fourth column lists if the line is an input, output, polarity, and if it is actively being consumed.
GPIO pins can be set to an input state and their state read via gpioget:
root@host:~# gpioget "<line label>" "<line label>"=<state>
Where <line label> is replaced with a valid line label.
GPIO output states can be set with the gpioset tool. For example, to disable and then re-enable USB 5 V power (on compatible platforms
root@host:~# timeout 0.1 gpioset "EN_USB_5V"=0 root@host:~# timeout 0.1 gpioset "EN_USB_5V"=1
Note that "EN_USB_5V" may be different on some platforms. See the output of gpioinfo on a platform for the full list of GPIO pins, or look at the GPIO section for the list of line names. Additionally, timeout 0.1 is used as the 2.2.x version of gpiod will run in the foreground to consume the GPIO pin to ensure no other process can change its state.
See the gpiod 2.2.x documentation for more detail on the command line tools, as well as its various APIs.
Debian 13 - Setting up SSH
OpenSSH is installed in our Debian images, but by default OpenSSH does not permit logging in as the root user as a security measure. Even if logging in as root is enabled, a password must be set for the root account. Additionally, an SSH host key is required if one hasn't already been created (though this should automatically be created on the first boot).
It is generally discouraged to allow the root user to log in directly. Instead, a user account should be created, with a password set on it. No changes are needed to the OpenSSH configuration file to allow a non-root user to log in.
However, in order to login to a device as root via SSH, the following steps must occur:
sed --in-place 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart ssh.service
passwd root # Set any password
Debian 13 - Starting Automatically
A systemd service can be created to start up various applications. Create the file /etc/systemd/system/yourapp.service with the contents:
[Unit]
Description=Run an application on startup
# Uncomment the following line if networking is a dependency of the application being run
# After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/your_app_or_script
[Install]
WantedBy=multi-user.target
The service can be started immediately and enableed on future boots with the following:
# Start the app on startup, but will not start it now
systemctl enable yourapp.service
# Start the app now, but doesn't change auto startup
systemctl start yourapp.service
See the systemd documentation for more information on how systemd services can be set up and configured.
Debian 13 - Cross Compiling
Debian provides cross toolchains within their distribution for different architectures.
For best portability, we recommend using a containerized environment like Docker to run a Debian 13 environment for toolchain access. This will allow a consistent build environment to run from almost any Linux system that can run Docker. Keep in mind that while docker does run under macOS and Windows, these are run under a case insensitive filesystem which will cause problems with complex builds like the Linux kernel so a Linux host is still recommended.
- Ubuntu/Debian:
sudo apt-get install docker.io -y
- Fedora
sudo dnf install docker -y
After installing docker on any distribution make sure your user is in the docker group:
# Add your user to the docker group. You may need to logout/log back in.
sudo usermod -aG docker $USER
Make sure you can run docker's hello world image as your user to verify it is working:
docker run hello-world
Now create a file Dockerfile:
sudo mkdir -p /opt/docker-toolchain/docker-debian-trixie-armhf
# Use any preferred editor, vim/emacs/nano/etc
sudo nano /opt/docker-toolchain/docker-debian-trixie-armhf/Dockerfile
# syntax = docker/dockerfile:1.2
FROM debian:trixie
RUN dpkg --add-architecture armhf
RUN apt-get update && apt-get install -y \
autogen \
automake \
bash \
bc \
bison \
build-essential \
bzip2 \
ca-certificates \
ccache \
chrpath \
cpio \
curl \
diffstat \
fakeroot \
file \
flex \
gawk \
gcc-arm-linux-gnueabihf \
git \
gzip \
kmod \
libgpiod-dev:armhf \
libncurses-dev \
libssl-dev \
libtool \
libyaml-dev \
locales \
lz4 \
lzop \
make \
pkg-config \
python3 \
python3-cbor \
python3-pexpect \
python3-pip \
qemu-user-static \
rsync \
runit \
socat \
srecord \
swig \
texinfo \
u-boot-tools \
zstd \
unzip \
vim \
wget \
xz-utils
# Provide a more friendly name
ENV debian_chroot debian_trixie
RUN echo "PS1='\${debian_chroot}\\[\033[01;32m\\]@\\H\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '" >> /etc/bash.bashrc
# Set up locales
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
echo 'LANG="en_US.UTF-8"'>/etc/default/locale && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8
ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
Next make a shell script to enter into this docker container. Create /usr/local/bin/docker-debian-trixie:
# Use any preferred editor, vim/emacs/nano/etc
sudo nano /usr/local/bin/docker-debian-trixie
#!/bin/bash -e
# Enters a docker running Debian 13 Trixie
# Any arguments are run in the docker, or if no arguments it runs a shell
export TAG=debian-trixie-armdev
SCRIPTPATH=$(readlink -f "$0")
DOCKERPATH=/opt/docker-toolchain/docker-debian-trixie-armhf/
DOCKER_BUILDKIT=1 docker build --tag "$TAG" "$DOCKERPATH" --quiet
exec docker run --rm \
-it \
--volume "$(pwd)":/work \
--user $(id -u):$(id -g) \
-w /work \
-e HOME=/tmp \
"$TAG" \
$@;
Make this executable, and call it:
sudo chmod a+x /usr/local/bin/docker-debian-trixie
# dont run as root
docker-debian-trixie
The first time this runs it will download a base Debian image, and run the above apt-get commands which may take around 10 or so minutes depending on your internet connection and disk speed. After it has run once, it will stay cached and adds almost no overhead to run.
This Docker container can be thought of as a very low overhead virtual machine that only has access to the directory where it is run.
For example, to build a simple c project, create a ~/Desktop/hello-world/ directory:
mkdir -p ~/Desktop/hello-world/
In ~/Desktop/hello-world/hello.c:
#include <stdio.h>
int main() {
printf("Hello world!\n");
return 0;
}
We can now use the docker in that directory to use Debian's cross compiler to create a binary that targets armhf:
user@hostname:~$ cd ~/Desktop/hello-world/ user@hostname:~/Desktop/hello-world$ docker-debian-trixie sha256:a92e70c3d7346654b34c0442da20ae634901fd25d1a89dd26517e7d1c1d00c47 debian_trixie@a8ddfa54989f:/work$ ls hello.c debian_trixie@a8ddfa54989f:/work$ arm-linux-gnueabihf-gcc hello.c -o hello debian_trixie@a8ddfa54989f:/work$ arm-linux-gnueabihf-strip hello debian_trixie@a8ddfa54989f:/work$ file hello hello: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=ffda981721a1531418ed1da27238707851ae0126, for GNU/Linux 3.2.0, stripped
Debian 12 - Bookworm
Debian 12 - Getting Started
This Debian release is available in 2 flavors with various packages. See our Debian releases in the Software Images section for links to the latest images available.
| Image | Description |
|---|---|
| Headless |
|
| Minimal |
|
The default login is root with no password.
Debian 12 - Networking
The network in Debian is configured with /etc/network/interfaces. For complete documentation, see Debian's documentation here
Some common examples are shown below. On this release network interfaces follow the predictible network interface names. Run ip addr show to get a list of the network interfaces.
Most commonly:
- end0 - Ethernet device 0 (CPU Ethernet)
- enp1s0 - Ethernet PCIe port 1 slot 0 Ethernet
- usb<mac> - USB Ethernet
- wlan0 - Wi-Fi
DHCP on end0. Create the file /etc/network/interfaces.d/end0 with the contents:
allow-hotplug end0 iface end0 inet dhcp
Static IP on end0. Create the file /etc/network/interfaces.d/end0 with the contents:
allow-hotplug end0
iface end0 inet static
address 192.0.2.7/24
gateway 192.0.2.254
These will take effect on the next boot, or by restarting the networking service:
service networking restart
Debian 12 - Wi-Fi Client
Wireless interfaces are also managed with configuration files in /etc/network/interfaces.d/. For example, to connect as a client to a WPA network with DHCP. Note some or all of this software may already be installed on the target.
Install wpa_supplicant:
apt-get update && apt-get install wpasupplicant -y
Run:
wpa_passphrase youressid yourpassword
This command will output information similar to:
network={
ssid="youressid"
#psk="yourpassword"
psk=151790fab3bf3a1751a269618491b54984e192aa19319fc667397d45ec8dee5b
}
Use the hashed PSK in the specific network interfaces file for added security. Create the file /etc/network/interfaces.d/wlan0 with the contents:
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid youressid
wpa-psk 151790fab3bf3a1751a269618491b54984e192aa19319fc667397d45ec8dee5b
To have this take effect immediately:
service networking restart
For more information on configuring Wi-Fi, see Debian's guide here.
Debian 12 - Wi-Fi Access Point
hostapd needs to be installed if it is not already in order to manage the access point on the device:
apt-get update && apt-get install hostapd -y
| Note: | The install process will start an unconfigured hostapd process. This process must be killed and restarted before new hostapd.conf contents will take effect.
|
Edit /etc/hostapd/hostapd.conf to include the following lines:
interface=wlan0
ssid=YourWiFiName
wpa_passphrase=Somepassphrase
interface=wlan0
channel=7
driver=nl80211
logger_stdout=-1 # Print all module output to standard out
logger_stdout_level=2 # Print informational messages to standard out
wpa=2
wpa_key_mgmt=WPA-PSK
| Note: | Refer to the kernel's hostapd documentation for more wireless configuration options. |
To start the access point launch hostapd:
hostapd /etc/hostapd/hostapd.conf &
This will start up an access point that can be detected by Wi-Fi clients. A DHCP server will likely be desired to assign IP addresses. Refer to Debian's documentation for more details on DHCP configuration.
Debian 12 - Wi-Fi Concurrent Client / Access Point
The Wi-Fi device on this platform supports concurrent operation of client and access point (STA and AP). Please see the "Wi-Fi Client" section above first to connect the Wi-Fi module, in STA mode, to an external AP. This demo showcases the Wi-Fi module starting its own AP mode via hostapd with a simple static IP address while also being concurrently connected to a separate AP.
The hostapd utility is used to manage the access point mode. This is usually installed by default, but can separately be installed with:
apt-get update && apt-get install hostapd -y
| Note: | The install process may start an unconfigured 'hostapd' process. This process must be killed before moving forward. |
Modify the file /etc/hostapd/hostapd.conf to have the following lines:
ssid=YourWiFiName
wpa_passphrase=Somepassphrase
interface=p2p0
auth_algs=3
channel=<channel>
driver=nl80211
logger_stdout=-1
logger_stdout_level=2
wpa=2
wpa_key_mgmt=WPA-PSK
| Note: | The channel used for AP must match the channel the STA is using! Be sure to set 'channel=...' in the above file to a proper channel number. |
| Note: | Refer to the kernel's hostapd documentation for more wireless configuration options. |
In order for the concurrent modes to work, a separate virtual wireless device must first be created. Note that hostapd.conf above lists interface=p2p0, a virtual interface with this name must be created:
iw wlan0 interface add p2p0 type managed
The access point can then be started and tested by hand:
hostapd /etc/hostapd/hostapd.conf &
An IP address can be set to p2p0:
ifconfig p2p0 192.168.0.1
From this point, other Wi-Fi clients can connect to the SSID YourWiFiName with the WPA2 key Somepassphrase with a static IP in the range of 192.168.0.0/24, and will be able to access the platform at 192.168.0.1. More advanced configurations are also possible, including bridging, routing/NAT, or simply separate networks with the Wi-Fi module connecting to a network and hosting its own private network with DHCP.
Debian 12 - Installing New Software
Debian uses the Advanced Package Tool (APT) suite to manage installation of prebuilt applications. The APT tools require a network connection to the internet in order to automatically download and install new software. The update command will download a list of the current versions of available packages:
apt-get update
A common example is installing a simple web server like nginx. Find the package name first with search, and then install it:
root@host:~# apt-cache search nginx ... nginx - small, powerful, scalable web/proxy server nginx-common - small, powerful, scalable web/proxy server - common files nginx-core - nginx web/proxy server (standard version) nginx-dev - nginx web/proxy server - development headers nginx-doc - small, powerful, scalable web/proxy server - documentation nginx-extras - nginx web/proxy server (extended version) nginx-full - nginx web/proxy server (standard version with 3rd parties) nginx-light - nginx web/proxy server (basic version) nginx-confgen - nginx configuration file macro language and preprocessor ...
In this case, the wanted package will likely be the nginx package itself. Names of packages can be found on Debian's wiki pages or the Debian packages site.
With the package name apt-get install can be used to install the prebuilt packages.
apt-get install nginx
# More than one package can be installed at a time.
apt-get install nginx nano vim vbindiff
For more information on using the various APT tools, refer to Debian's APT documentation.
Debian 12 - Setting up SSH
OpenSSH is installed in our Debian images, but by default OpenSSH does not permit logging in as the root user as a security measure. Even if logging in as root is enabled, a password must be set for the root account. Additionally, an SSH host key is required if one hasn't already been created (though this should automatically be created on the first boot).
It is generally discouraged to allow the root user to log in directly. Instead, a user account should be created, with a password set on it. No changes are needed to the OpenSSH configuration file to allow a non-root user to log in.
However, in order to login to a device as root via SSH, the following steps must occur:
sed --in-place 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart ssh.service
passwd root # Set any password
Debian 12 - Starting Automatically
A systemd service can be created to start up various applications. Create the file /etc/systemd/system/yourapp.service with the contents:
[Unit]
Description=Run an application on startup
# Uncomment the following line if networking is a dependency of the application being run
# After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/your_app_or_script
[Install]
WantedBy=multi-user.target
The service can be started immediately and enableed on future boots with the following:
# Start the app on startup, but will not start it now
systemctl enable yourapp.service
# Start the app now, but doesn't change auto startup
systemctl start yourapp.service
See the systemd documentation for more information on how systemd services can be set up and configured.
Debian 12 - Cross Compiling
Debian provides cross toolchains within their distribution for different architectures.
For best portability, we recommend using a containerized environment like Docker to run a Debian 12 environment for toolchain access. This will allow a consistent build environment to run from almost any Linux system that can run Docker. Keep in mind that while docker does run under macOS and Windows, these are run under a case insensitive filesystem which will cause problems with complex builds like the Linux kernel so a Linux host is still recommended.
- Ubuntu/Debian:
sudo apt-get install docker.io -y
- Fedora
sudo dnf install docker -y
After installing docker on any distribution make sure your user is in the docker group:
# Add your user to the docker group. You may need to logout/log back in.
sudo usermod -aG docker $USER
Make sure you can run docker's hello world image as your user to verify it is working:
docker run hello-world
Now create a file Dockerfile:
sudo mkdir -p /opt/docker-toolchain/docker-debian-bookworm-armhf
# Use any preferred editor, vim/emacs/nano/etc
sudo nano /opt/docker-toolchain/docker-debian-bookworm-armhf/Dockerfile
# syntax = docker/dockerfile:1.2
FROM debian:bookworm
RUN dpkg --add-architecture armhf
RUN apt-get update && apt-get install -y \
autogen \
automake \
bash \
bc \
bison \
build-essential \
bzip2 \
ca-certificates \
ccache \
chrpath \
cpio \
curl \
diffstat \
fakeroot \
file \
flex \
gawk \
gcc-arm-linux-gnueabihf \
git \
gzip \
kmod \
libgpiod-dev:armhf \
libncursesw5-dev \
libssl-dev \
libtool \
libyaml-dev \
locales \
lz4 \
lzop \
make \
multistrap \
ncurses-dev \
pkg-config \
python3 \
python3-cbor \
python3-pexpect \
python3-pip \
qemu-user-static \
rsync \
runit \
socat \
srecord \
swig \
texinfo \
u-boot-tools \
zstd \
unzip \
vim \
wget \
xz-utils
# Provide a more friendly name
ENV debian_chroot debian_bookworm
RUN echo "PS1='\${debian_chroot}\\[\033[01;32m\\]@\\H\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '" >> /etc/bash.bashrc
# Set up locales
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
echo 'LANG="en_US.UTF-8"'>/etc/default/locale && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8
ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
Next make a shell script to enter into this docker container. Create /usr/local/bin/docker-debian-bookworm:
# Use any preferred editor, vim/emacs/nano/etc
sudo nano /usr/local/bin/docker-debian-bookworm
#!/bin/bash -e
# Enters a docker running Debian 12 Bookworm
# Any arguments are run in the docker, or if no arguments it runs a shell
export TAG=debian-bookworm-armdev
SCRIPTPATH=$(readlink -f "$0")
DOCKERPATH=/opt/docker-toolchain/docker-debian-bookworm-armhf/
DOCKER_BUILDKIT=1 docker build --tag "$TAG" "$DOCKERPATH" --quiet
exec docker run --rm \
-it \
--volume "$(pwd)":/work \
--user $(id -u):$(id -g) \
-w /work \
-e HOME=/tmp \
"$TAG" \
$@;
Make this executable, and call it:
sudo chmod a+x /usr/local/bin/docker-debian-bookworm
# dont run as root
docker-debian-bookworm
The first time this runs it will download a base Debian image, and run the above apt-get commands which may take around 10 or so minutes depending on your internet connection and disk speed. After it has run once, it will stay cached and adds almost no overhead to run.
This docker can be thought of as a very low overhead virtual machine that only has access to the directory where it is run.
For example, to build a simple c project, create a ~/Desktop/hello-world directory:
mkdir -p ~/Desktop/hello-world/
In ~/Desktop/hello-world/hello.c:
#include <stdio.h>
int main() {
printf("Hello world!\n");
return 0;
}
We can now use the docker in that directory to use Debian's cross compiler to create a binary that targets armhf:
user@hostname:~$ cd ~/Desktop/hello-world/ user@hostname:~/Desktop/hello-world$ docker-debian-bookworm sha256:a92e70c3d7346654b34c0442da20ae634901fd25d1a89dd26517e7d1c1d00c47 debian_bookworm@a8ddfa54989f:/work$ ls hello.c debian_bookworm@a8ddfa54989f:/work$ arm-linux-gnueabihf-gcc hello.c -o hello debian_bookworm@a8ddfa54989f:/work$ arm-linux-gnueabihf-strip hello debian_bookworm@a8ddfa54989f:/work$ file hello hello: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=ffda981721a1531418ed1da27238707851ae0126, for GNU/Linux 3.2.0, stripped
Debian Stretch(9)
Getting Started
The stock image uses a Debian Stretch distribution and Linux kernel version 4.9. The latest image can be downloaded below.
This image can then be written to a microSD card or the on-board eMMC flash in order to be booted on the TS-4100.
Debian Networking
| Note: | The first physical port on the TS-4100 (or on Baseboards with a single port) is given the name "eth1", while the second port is "eth0". |
By default, Debian Stretch does not configure or bring up any interfaces.
Debian can automatically set up the networking based on the contents of "/etc/network/interfaces.d/" files. For example, to enable DHCP for "eth0" by default on startup:
echo "auto eth0
iface eth0 inet dhcp" > /etc/network/interfaces.d/eth0
To set up a static IP:
echo "auto eth0
iface eth0 inet static
address 192.168.0.50
netmask 255.255.255.0
gateway 192.168.0.1" > /etc/network/interfaces.d/eth0
echo "nameserver 1.1.1.1" > /etc/resolv.conf
To make this take effect immediately for either option:
service networking restart
To configure other interfaces, replace "eth0" with the other network device name. Some interfaces may use predictable interface names. For example, the traditional name for an ethernet port might be "eth1", but some devices may use "enp1s0" for PCIe, or "enx00D069C0FFEE" (the MAC address appended) for USB ethernet interfaces. Run 'ifconfig -a' or 'ip a' to get a complete list of interfaces, including the ones that are not configured.
Debian Wi-Fi Client
| Note: | The latest image for this platform as of April 28th, 2022 has known issues with the Wi-Fi driver due to incompatibility with cfg80211 powersave modes.
If using Wi-Fi, it is strongly recommended to bring up the Wi-Fi interface, and then run This issue will be addressed in future images and has already been addressed in our kernel sources. We will continue to provide updates as we receive them from the Wi-Fi module manufacturer. |
Wireless interfaces are also managed with configuration files in /etc/network/interfaces.d/. For example, to connect as a client to a WPA network with DHCP. Note some or all of this software may already be installed on the target.
Install wpa_supplicant:
apt-get update && apt-get install wpasupplicant -y
Run:
wpa_passphrase youressid yourpassword
This command will output information similar to:
network={
ssid="youressid"
#psk="yourpassword"
psk=151790fab3bf3a1751a269618491b54984e192aa19319fc667397d45ec8dee5b
}
Use the hashed PSK in the specific network interfaces file for added security. Create the file /etc/network/interfaces.d/wlan0 with the contents:
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid youressid
wpa-psk 151790fab3bf3a1751a269618491b54984e192aa19319fc667397d45ec8dee5b
To have this take effect immediately:
service networking restart
For more information on configuring Wi-Fi, see Debian's guide here.
Debian Wi-Fi Access Point
| Note: | The latest image for this platform as of April 28th, 2022 has known issues with the Wi-Fi driver due to incompatibility with cfg80211 powersave modes.
If using Wi-Fi, it is strongly recommended to bring up the Wi-Fi interface, and then run This issue will be addressed in future images and has already been addressed in our kernel sources. We will continue to provide updates as we receive them from the Wi-Fi module manufacturer. |
This section will discuss setting up the WiFi device as an access point that is bridged to an ethernet port. That is, clients can connect to the AP and will be connected to the ethernet network through this network bridge. The ethernet network must provide a DHCP server; this will be passed through the bridge to WiFi client devices as they connect.
It is also possible to run a DHCP client on the platform itself. In this case the hostapd.conf file needs to be set up without bridging and a DHCP server needs to be configured. Refer to Debian's documentation for more details on DHCP server configuration.
The 'hostapd' utility is used to manage the access point of the device. This is usually installed by default, but can be installed with:
apt-get update && apt-get install hostapd -y
| Note: | The install process may start an unconfigured 'hostapd' process. This process must be killed before moving forward. |
Modify the file "/etc/hostapd/hostapd.conf" to have the following lines:
ssid=YourWiFiName
wpa_passphrase=Somepassphrase
interface=wlan0
channel=7
driver=nl80211
logger_stdout=-1
logger_stdout_level=2
wpa=2
wpa_key_mgmt=WPA-PSK
| Note: | Refer to the kernel's hostapd documentation for more wireless configuration options. |
The access point can be started and tested by hand:
hostapd /etc/hostapd/hostapd.conf
Systemd auto-start with bridge to eth0
It is possible to configure the auto-start of 'hostapd' through systemd. The configuration outlined below will set up a bridge with "eth0", meaning the Wi-Fi connection is directly connected to the ethernet network. The ethernet network is required to have a DHCP server present and active on it to assign Wi-Fi clients an IP address. This setup will allow Wi-Fi clients access to the same network as the ethernet port, and the bridge interface will allow the platform itself to access the network.
Set up hostapd
First, modify the hostapd configuration to understand the bridge interface:
echo "bridge=br0" >> /etc/hostapd/hostapd.conf
Create the file "/etc/systemd/system/hostapd_user.service" with the following contents:
[Unit]
Description=Hostapd IEEE 802.11 AP
Wants=network.target
Before=network.target
Before=network.service
After=sys-subsystem-net-devices-wlan0.device
After=sys-subsystem-net-devices-br0.device
BindsTo=sys-subsystem-net-devices-wlan0.device
BindsTo=sys-subsystem-net-devices-br0.device
[Service]
Type=forking
PIDFile=/run/hostapd.pid
ExecStart=/usr/sbin/hostapd /etc/hostapd/hostapd.conf -P /run/hostapd.pid -B
[Install]
WantedBy=multi-user.target
Then enable this in systemd:
systemctl enable hostapd_user.service
systemctl enable systemd-networkd
Set up bridging
Create the following files with the listed contents.
"/etc/systemd/network/br0.netdev"
[NetDev]
Name=br0
Kind=bridge
"/etc/systemd/network/br0.network"
[Match]
Name=br0
[Network]
DHCP=yes
"/etc/systemd/network/bridge.network"
[Match]
Name=eth0
[Network]
Bridge=br0
Debian Wi-Fi Concurrent Client / Access Point
| Note: | The latest image for this platform as of April 28th, 2022 has known issues with the Wi-Fi driver due to incompatibility with cfg80211 powersave modes.
If using Wi-Fi, it is strongly recommended to bring up the Wi-Fi interface, and then run This issue will be addressed in future images and has already been addressed in our kernel sources. We will continue to provide updates as we receive them from the Wi-Fi module manufacturer. |
The Wi-Fi device on this platform supports concurrent operation of client and access point (STA and AP). Please see the "Wi-Fi Client" section above first to connect the Wi-Fi module, in STA mode, to an external AP. This demo showcases the Wi-Fi module starting its own AP mode via hostapd with a simple static IP address while also being concurrently connected to a separate AP.
The hostapd utility is used to manage the access point mode. This is usually installed by default, but can separately be installed with:
apt-get update && apt-get install hostapd -y
| Note: | The install process may start an unconfigured 'hostapd' process. This process must be killed before moving forward. |
Modify the file /etc/hostapd/hostapd.conf to have the following lines:
ssid=YourWiFiName
wpa_passphrase=Somepassphrase
interface=p2p0
auth_algs=3
channel=<channel>
driver=nl80211
logger_stdout=-1
logger_stdout_level=2
wpa=2
wpa_key_mgmt=WPA-PSK
| Note: | The channel used for AP must match the channel the STA is using! Be sure to set 'channel=...' in the above file to a proper channel number. |
| Note: | Refer to the kernel's hostapd documentation for more wireless configuration options. |
In order for the concurrent modes to work, a separate virtual wireless device must first be created. Note that hostapd.conf above lists interface=p2p0, a virtual interface with this name must be created:
iw wlan0 interface add p2p0 type managed
The access point can then be started and tested by hand:
hostapd /etc/hostapd/hostapd.conf &
An IP address can be set to p2p0:
ifconfig p2p0 192.168.0.1
From this point, other Wi-Fi clients can connect to the SSID YourWiFiName with the WPA2 key Somepassphrase with a static IP in the range of 192.168.0.0/24, and will be able to access the platform at 192.168.0.1. More advanced configurations are also possible, including bridging, routing/NAT, or simply separate networks with the Wi-Fi module connecting to a network and hosting its own private network with DHCP.
Debian Application Development
Debian Stretch Cross Compiling
Debian Stretch provides cross compilers from the Debian apt repository archive for Debian Stretch. An install on a workstation can build for the same release on other architectures. A Linux desktop or laptop PC, virtual machine, or chroot will need to be used for this. Debian Stretch for a workstation can be downloaded from here.
From a Debian workstation (not the target), run these commands to set up the cross compiler:
# Run "lsb_release -a" and verify Debian 9.X is returned. These instructions are not
# expected to work on any other version or distribution.
su root
# Not needed for the immediate apt-get install, but used
# so we can install package:armhf for cross compiling
dpkg --add-architecture armhf
apt-get update
apt-get install curl build-essential crossbuild-essential-armhf -y
This will install a toolchain that can be used with the prefix "arm-linux-gnueabihf-". The standard GCC tools will start with that name, eg "arm-linux-gnueabihf-gcc".
The toolchain can now compile a simple hello world application. Create hello-world.c on the Debian workstation:
#include <stdio.h>
int main(){
printf("Hello World\n");
}
To compile this:
arm-linux-gnueabihf-gcc hello-world.c -o hello-world
file hello-world
This will return that the binary created is for ARM. Copy this to the target platform to run it there.
Debian Stretch supports multiarch which can install packages designed for other architectures. On workstations this is how 32-bit and 64-bit support is provided. This can also be used to install armhf packages on an x86 based workstation.
This cross compile environment can link to a shared library from the Debian root. The package would be installed in Debian on the workstation to provide headers and libraries. This is included in most "-dev" packages. When run on the arm target it will also need a copy of the library installed, but it does not need the -dev package.
apt-get install libcurl4-openssl-dev:armhf
# Download the simple.c example from curl:
wget https://raw.githubusercontent.com/bagder/curl/master/docs/examples/simple.c
# After installing the supporting library, curl will link as compiling on the unit.
arm-linux-gnueabihf-gcc simple.c -o simple -lcurl
Copy the binary to the target platform and run on the target. This can be accomplished with network protocols like NFS, SCP, FTP, etc.
If any created binaries do not rely on hardware support like GPIO or CAN, they can be run using 'qemu'.
# using the hello world example from before:
./hello-world
# Returns Exec format error
apt-get install qemu-user-static
./hello-world
Debian Installing New Software
Debian provides the apt-get system which allows management of pre-built applications. The apt tools require a network connection to the internet in order to automatically download and install new software. The update command will download a list of the current versions of pre-built packages.
apt-get update
A common example is installing Java runtime support for a system. Find the package name first with search, and then install it.
root@ts:~# apt-cache search openjdk default-jdk - Standard Java or Java compatible Development Kit default-jdk-doc - Standard Java or Java compatible Development Kit (documentation) default-jdk-headless - Standard Java or Java compatible Development Kit (headless) default-jre - Standard Java or Java compatible Runtime default-jre-headless - Standard Java or Java compatible Runtime (headless) jtreg - Regression Test Harness for the OpenJDK platform libreoffice - office productivity suite (metapackage) openjdk-8-dbg - Java runtime based on OpenJDK (debugging symbols) openjdk-8-demo - Java runtime based on OpenJDK (demos and examples) openjdk-8-doc - OpenJDK Development Kit (JDK) documentation openjdk-8-jdk - OpenJDK Development Kit (JDK) openjdk-8-jdk-headless - OpenJDK Development Kit (JDK) (headless) openjdk-8-jre - OpenJDK Java runtime, using Hotspot JIT openjdk-8-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless) openjdk-8-jre-zero - Alternative JVM for OpenJDK, using Zero/Shark openjdk-8-source - OpenJDK Development Kit (JDK) source files uwsgi-app-integration-plugins - plugins for integration of uWSGI and application uwsgi-plugin-jvm-openjdk-8 - Java plugin for uWSGI (OpenJDK 8) uwsgi-plugin-jwsgi-openjdk-8 - JWSGI plugin for uWSGI (OpenJDK 8) uwsgi-plugin-ring-openjdk-8 - Closure/Ring plugin for uWSGI (OpenJDK 8) uwsgi-plugin-servlet-openjdk-8 - JWSGI plugin for uWSGI (OpenJDK 8) java-package - Utility for creating Java Debian packages
In this case, the wanted package will likely be the "openjdk-8-jre" package. Names of packages can be found on Debian's wiki pages or the packages site.
With the package name apt-get install can be used to install the prebuilt packages.
apt-get install openjdk-8-jre
# More than one package can be installed at a time.
apt-get install openjdk-8-jre nano vim mplayer
For more information on using apt-get refer to Debian's documentation here.
Debian Setting up SSH
To install the SSH server, install the package with apt-get:
apt-get install openssh-server
Debian Stretch by default disallows logins directly from the user "root". Additionally, SSH will not allow remote connections without a password or valid SSH key pair. This means in order to SSH to the device, a user account must first be created, and a password set:
useradd --create-home --shell /bin/bash newuser
passwd newuser
After this setup it is now possible to connect to the device as user "newuser" from a remote PC supporting SSH. On Linux/OS X this is the "ssh" command, or from Windows using a client such as PuTTY.
Debian Starting Automatically
A systemd service can be created to start up headless applications. Create a file in /etc/systemd/system/yourapp.service
[Unit]
Description=Run an application on startup
[Service]
Type=simple
ExecStart=/usr/local/bin/your_app_or_script
[Install]
WantedBy=multi-user.target
If networking is a dependency add "After=network.target" in the Unit section. Once you have this file in place add it to startup with:
# Start the app on startup, but will not start it now
systemctl enable yourapp.service
# Start the app now, but doesn't change auto startup
systemctl start yourapp.service
| Note: | See the systemd documentation for in depth documentation on services. |