TS-4900 Debian Sections

From embeddedTS Manuals

Debian is a community run Linux distribution. Debian provides tens of thousands of precompiled applications and services. This distribution is known for stability and large community providing support and documentation.

Debian 12 - Bookworm

Debian 12 - Getting Started

This Debian release is available in 3 flavors with various packages.

Image Estimated Size Description
debian-armhf-bookworm-x11-latest.tar.bz2 925 MiB
  • Includes 5.10 kernel with tsimx6_defconfig that includes broad driver support
  • Base Debian with common utils
  • Common embedded tools (i2c, can, gpio, iio, serial tools, etc)
  • Includes hardware support
  • Networking tools (ethernet, wifi, bluetooth)
  • Includes Development tools
  • Includes X11 that launches matchbox and xterm on startup
  • Includes touchscreen support
debian-armhf-bookworm-headless-latest.tar.bz2 681 MiB
  • Includes 5.10 kernel with tsimx6_defconfig that includes broad driver support
  • Base Debian with common utils
  • Common embedded tools (i2c, can, gpio, iio, serial tools, etc)
  • Includes hardware support
  • Networking tools (ethernet, wifi, bluetooth)
  • Includes Development tools
debian-armhf-bookworm-minimal-latest.tar.bz2 223 MiB
  • Includes 5.10 kernel with tsimx6_minimal_defconfig that includes bare minimum driver support and kernel options required by Debian.
  • Includes base Debian rootfs adding only what is required for Ethernet support.

The default login is root with no password.

To write this to an SD card, first partition the SD card to have one large ext3, or ext4 partition. See the guide here for more information. Once it is formatted, extract this tar with:

# Assuming your SD card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar --numeric-owner -xjf debian-armhf-bookworm-x11-latest.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync

To rewrite the eMMC, boot to the SD card. You cannot rewrite the emmc while it is mounted elsewhere, or used to currently boot the system. Once booted to the SD, run:

mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget -qO- https://files.embeddedts.com/ts-arm-sbc/ts-7970-linux/distributions/debian/debian-armhf-bookworm-x11-latest.tar.bz2 | tar --numeric-owner -xj -C /mnt/emmc/
umount /mnt/emmc
sync


Note: The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3.

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 - WIFI

DHCP on end0. Edit the file /etc/network/interfaces and add:

auto end0
allow-hotplug end0
iface end0 inet dhcp

Static IP on end0. Edit the file /etc/network/interfaces and add:

auto 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 - WIFI 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 SBC.

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

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 - WIFI Access Point

First, hostapd needs to be installed 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 a new hostapd.conf will take effect.

Edit /etc/hostapd/hostapd.conf to include the following lines:

interface=wlan0
driver=nl80211
ssid=YourAPName
channel=1
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 WIFI 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 - 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@tsa38x:~# 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-11-dbg - Java runtime based on OpenJDK (debugging symbols)
openjdk-11-demo - Java runtime based on OpenJDK (demos and examples)
openjdk-11-doc - OpenJDK Development Kit (JDK) documentation
openjdk-11-jdk - OpenJDK Development Kit (JDK)
openjdk-11-jdk-headless - OpenJDK Development Kit (JDK) (headless)
openjdk-11-jre - OpenJDK Java runtime, using Hotspot JIT
openjdk-11-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless)
openjdk-11-jre-zero - Alternative JVM for OpenJDK, using Zero
openjdk-11-source - OpenJDK Development Kit (JDK) source files
uwsgi-app-integration-plugins - plugins for integration of uWSGI and application
uwsgi-plugin-jvm-openjdk-11 - Java plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-jwsgi-openjdk-11 - JWSGI plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-ring-openjdk-11 - Closure/Ring plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-servlet-openjdk-11 - JWSGI plugin for uWSGI (OpenJDK 11)
java-package - Utility for creating Java Debian packages

In this case, the wanted package will likely be the "openjdk-11-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-11-jre
# More than one package can be installed at a time.
apt-get install openjdk-11-jre nano vim mplayer

For more information on using apt-get refer to Debian's documentation here.

Debian 12 - Setting up SSH

Openssh is installed in our default Debian image, but by default openssh does not permit root logins, and requires a password to be set. Additionally, a host key is required if one hasn't already been created on the target board. To allow remote root login:

sed --in-place 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart ssh.service
passwd root # Set any password

If you ssh to this system it will now support ssh as root.

Debian 12 - Starting Automatically

Bookwoorm Startup Scripts

Debian 12 - Cross Compiling

Debian provides cross toolchains within their distribution for different architectures.

For best portability we recommend using a container like docker to run a Debian 12 rootfs for the toolchain. This will allow a consistent toolchain to run from almost any Linux system that can run Docker. Keep in mind that while docker does run under OSX 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 -g):$(id -u) \
	-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/hello.c:

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 11 - Bullseye

Debian 11 - Getting Started

The Debian images apply to the TS-4900, TS-7970, and TS-TPC-7990.

Image Size Kernel config Description
debian-armhf-bullseye-latest.tar.bz2 1346 MB ts4900_defconfig Contains gcc, vim, X11, slim, and will autologin to an xfce4 desktop.

Once installed the default user on either image is "root" with no password.

To prepare an SD card, use partitioning tools such as 'fdisk' 'cfdisk' or 'gparted' in linux to create a single linux partition on the SD card. Once the partition is created and formatted, extract the above tarball with:

# Assuming your SD card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar --numeric-owner -xjf debian-armhf-bullseye-latest.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync
Note: The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3.

To rewrite the eMMC the unit must be booted to SD or any other media that is not eMMC. Once booted, run the following commands.:

mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget -qO- https://files.embeddedTS.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/debian/debian-armhf-bullseye-latest.tar.bz2 | tar xj -C /mnt/emmc/
umount /mnt/emmc
sync

The same commands can be used to write a SATA drive by substituting /dev/mmcblk2p1 with /dev/sda1.

Debian 11 - Networking

The network in Debian is configured /etc/network/interfaces.d/. For complete documentation, see Debian's documentation here

Some common examples are shown below.

DHCP on eth0. Create the file: /etc/network/interfaces.d/eth0

auto eth0
allow-hotplug eth0
iface eth0 inet dhcp

Static IP on eth0. Create the file /etc/network/interfaces.d/eth0

auto eth0
iface eth0 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 11 - WIFI 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 SBC.

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

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 11 - WIFI Access Point

First, hostapd needs to be installed 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 a new hostapd.conf will take effect.

Edit /etc/hostapd/hostapd.conf to include the following lines:

interface=wlan0
driver=nl80211
ssid=YourAPName
channel=1
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 WIFI clients. A DHCP server will likely be desired to assign IP addresses. Refer to Debian's documentation for more details on DHCP configuration.

Debian 11 - 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@tsa38x:~# 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-11-dbg - Java runtime based on OpenJDK (debugging symbols)
openjdk-11-demo - Java runtime based on OpenJDK (demos and examples)
openjdk-11-doc - OpenJDK Development Kit (JDK) documentation
openjdk-11-jdk - OpenJDK Development Kit (JDK)
openjdk-11-jdk-headless - OpenJDK Development Kit (JDK) (headless)
openjdk-11-jre - OpenJDK Java runtime, using Hotspot JIT
openjdk-11-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless)
openjdk-11-jre-zero - Alternative JVM for OpenJDK, using Zero
openjdk-11-source - OpenJDK Development Kit (JDK) source files
uwsgi-app-integration-plugins - plugins for integration of uWSGI and application
uwsgi-plugin-jvm-openjdk-11 - Java plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-jwsgi-openjdk-11 - JWSGI plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-ring-openjdk-11 - Closure/Ring plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-servlet-openjdk-11 - JWSGI plugin for uWSGI (OpenJDK 11)
java-package - Utility for creating Java Debian packages

In this case, the wanted package will likely be the "openjdk-11-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-11-jre
# More than one package can be installed at a time.
apt-get install openjdk-11-jre nano vim mplayer

For more information on using apt-get refer to Debian's documentation here.

Debian 11 - Setting up SSH

Openssh is installed in our default Debian image, but by default openssh does not permit root logins, and requires a password to be set. Additionally, a host key is required if one hasn't already been created on the target board. To allow remote root login:

sed --in-place 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart ssh.service
/bin/ls /etc/ssh/ssh_host*key >/dev/null 2>&1  || ssh-keygen -A
passwd root # Set any password

If you ssh to this system it will now support ssh as root.

Debian 11 - 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.

Debian 11 - Cross Compiling

Debian only provides their cross compiler for their distribution. Our examples will set up a Docker for Debian to use for development. If using Debian 11 Bullseye directly, or through a VM then the docker usage can be skipped.

Create a file called "Dockerfile" with these contents:

FROM debian:bullseye

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 \
    locales \
    lzop \
    make \
    multistrap \
    ncurses-dev \
    pkg-config \
    python \
    python3 \
    python3-pip \
    python3-pexpect \
    qemu-user-static \
    rsync \
    socat \
    runit \
    texinfo \
    u-boot-tools \
    unzip \
    vim \
    wget \
    xz-utils

# To make a more readable PS1 to show we are in the Docker
ENV debian_chroot debian_bullseye
RUN echo "PS1='\${debian_chroot}\\[\033[01;32m\\]@\\H\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '" >> /etc/bash.bashrc

# Set up locales.  Needed by yocto.
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

In the same directory as the file named "Dockerfile" run:

docker build --tag armhf-bullseye-toolchain .

When this has finished the docker can be used with:

docker run --rm -it --volume $(pwd):/work armhf-bullseye-toolchain bash

This will map the current directory to /work.

At this point the Debian Docker is ready to compile armhf binaries. For example, create a hello world in your home folder at ~/hello.c

#include <stdio.h>
int main(){
    printf("Hello World\n");
}

To compile this enter the docker with:

docker run -it --volume $(pwd):/work armhf-bullseye-toolchain bash
# Then from the docker:
cd /work/
arm-linux-gnueabihf-gcc hello.c -o hello

Check "file hello" to verify the binary type:

debian_bullseye@b720b8ba6c1e:/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]=fc6389ca8da310bb5d0b87e5998b59894c078d9f, for GNU/Linux 3.2.0, not stripped

This can also be used to develop against dynamic libraries from Debian. The armhf packages can be installed in the Docker. For example, to link against curl:

# Enter the Docker:
docker run -it --volume $(pwd):/work armhf-bullseye-toolchain bash
cd /work/

apt-get install libcurl4-openssl-dev:armhf
# Download curl's simple.c example
wget https://raw.githubusercontent.com/bagder/curl/master/docs/examples/simple.c
arm-linux-gnueabihf-gcc simple.c -o simple -lcurl

The "simple" binary is now built for armhf and links dynamically to curl.

This will only retain the armhf libcurl package until the docker is exited. To make the changes permanent, add the package to the Dockerfile and rerun:

docker build --tag armhf-bullseye-toolchain .

Debian 10 - Buster

Debian 10 - Getting Started

The Debian images apply to the TS-4900, TS-7970, and TS-TPC-7990.

Image Size Kernel config Description
debian-armhf-buster-latest.tar.bz2 1113 MB ts4900_defconfig Contains gcc, vim, X11, slim, and will autologin to an xfce4 desktop.

Once installed the default user on either image is "root" with no password.

To prepare an SD card, use partitioning tools such as 'fdisk' 'cfdisk' or 'gparted' in linux to create a single linux partition on the SD card. Once the partition is created and formatted, extract the above tarball with:

# Assuming your SD card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar --numeric-owner -xjf debian-armhf-buster-latest.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync
Note: The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3.

To rewrite the eMMC the unit must be booted to SD or any other media that is not eMMC. Once booted, run the following commands.:

mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget -qO- ftp://ftp.embeddedTS.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/debian/debian-armhf-buster-latest.tar.bz2 | tar xj -C /mnt/emmc/
umount /mnt/emmc
sync

The same commands can be used to write a SATA drive by substituting /dev/mmcblk2p1 with /dev/sda1.

Debian 10 - Networking

The network in Debian is configured /etc/network/interfaces.d/. For complete documentation, see Debian's documentation here

Some common examples are shown below.

DHCP on eth0. Create the file: /etc/network/interfaces.d/eth0

auto eth0
allow-hotplug eth0
iface eth0 inet dhcp

Static IP on eth0. Create the file /etc/network/interfaces.d/eth0

auto eth0
iface eth0 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 10 - WIFI 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 SBC.

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

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 10 - WIFI Access Point

First, hostapd needs to be installed 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 a new hostapd.conf will take effect.

Edit /etc/hostapd/hostapd.conf to include the following lines:

interface=wlan0
driver=nl80211
ssid=YourAPName
channel=1
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 WIFI clients. A DHCP server will likely be desired to assign IP addresses. Refer to Debian's documentation for more details on DHCP configuration.

Debian 10 - 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@tsa38x:~# 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-11-dbg - Java runtime based on OpenJDK (debugging symbols)
openjdk-11-demo - Java runtime based on OpenJDK (demos and examples)
openjdk-11-doc - OpenJDK Development Kit (JDK) documentation
openjdk-11-jdk - OpenJDK Development Kit (JDK)
openjdk-11-jdk-headless - OpenJDK Development Kit (JDK) (headless)
openjdk-11-jre - OpenJDK Java runtime, using Hotspot JIT
openjdk-11-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless)
openjdk-11-jre-zero - Alternative JVM for OpenJDK, using Zero
openjdk-11-source - OpenJDK Development Kit (JDK) source files
uwsgi-app-integration-plugins - plugins for integration of uWSGI and application
uwsgi-plugin-jvm-openjdk-11 - Java plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-jwsgi-openjdk-11 - JWSGI plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-ring-openjdk-11 - Closure/Ring plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-servlet-openjdk-11 - JWSGI plugin for uWSGI (OpenJDK 11)
java-package - Utility for creating Java Debian packages

In this case, the wanted package will likely be the "openjdk-11-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-11-jre
# More than one package can be installed at a time.
apt-get install openjdk-11-jre nano vim mplayer

For more information on using apt-get refer to Debian's documentation here.

Debian 10 - Setting up SSH

Openssh is installed in our default Debian image, but by default openssh does not permit root logins, and requires a password to be set. Additionally, a host key is required if one hasn't already been created on the target board. To allow remote root login:

sed --in-place 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart ssh.service
/bin/ls /etc/ssh/ssh_host*key >/dev/null 2>&1  || ssh-keygen -A
passwd root # Set any password

If you ssh to this system it will now support ssh as root.

Debian 10 - 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.

Debian 10 - Cross Compiling

Debian only provides their cross compiler for their distribution. Our examples will set up a Docker for Debian to use for development. If using Debian 10 Buster directly, or through a VM then the docker usage can be skipped.

Create a file called "Dockerfile" with these contents:

FROM debian:buster

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 \
    locales \
    lzop \
    make \
    multistrap \
    ncurses-dev \
    pkg-config \
    python \
    python3 \
    python3-pip \
    python3-pexpect \
    qemu-user-static \
    rsync \
    socat \
    runit \
    texinfo \
    u-boot-tools \
    unzip \
    vim \
    wget \
    xz-utils

# To make a more readable PS1 to show we are in the Docker
ENV debian_chroot debian_buster
RUN echo "PS1='\${debian_chroot}\\[\033[01;32m\\]@\\H\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '" >> /etc/bash.bashrc

# Set up locales.  Needed by yocto.
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

In the same directory as the file named "Dockerfile" run:

docker build --tag armhf-buster-toolchain .

When this has finished the docker can be used with:

docker run --rm -it --volume $(pwd):/work armhf-buster-toolchain bash

This will map the current directory to /work.

At this point the Debian Docker is ready to compile armhf binaries. For example, create a hello world in your home folder at ~/hello.c

#include <stdio.h>
int main(){
    printf("Hello World\n");
}

To compile this enter the docker with:

docker run -it --volume $(pwd):/work armhf-buster-toolchain bash
# Then from the docker:
cd /work/
arm-linux-gnueabihf-gcc hello.c -o hello

Check "file hello" to verify the binary type:

user@host:~/$ file hello
hello: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=8a8cee3341d3ef76ef6796f72d5722ae9d77c8ea, not stripped

This can also be used to develop against dynamic libraries from Debian. The armhf packages can be installed in the Docker. For example, to link against curl:

# Enter the Docker:
docker run -it --volume $(pwd):/work armhf-buster-toolchain bash
cd /work/

apt-get install libcurl4-openssl-dev:armhf
# Download curl's simple.c example
wget https://raw.githubusercontent.com/bagder/curl/master/docs/examples/simple.c
arm-linux-gnueabihf-gcc simple.c -o simple -lcurl

The "simple" binary is now built for armhf and links dynamically to curl.

This will only retain the armhf libcurl package until the docker is exited. To make the changes permanent, add the package to the Dockerfile and rerun:

docker build --tag armhf-buster-toolchain .

Debian 9 - Stretch

Debian 9 - Getting Started

We provide two images for Debian Stretch which apply to our TS-4900, TS-7970, and TS-TPC-7990. If you are unsure which image to pick, use the larger image which contains more development tools and drivers.

Image Size Kernel config Description
debian-armhf-stretch-latest.tar.bz2 1279MB ts4900_defconfig Contains gcc, vim, X11, slim, and will autologin to an xfce4 desktop.
debian-armhf-stretch-minimal-latest.tar.bz2 184MB ts4900_tiny_defconfig Stripped down Debian containing bare minimal hardware support, very limited peripheral support, and only the core debian packages.

Once installed the default user on either image is "root" with no password.

To prepare an SD card, use partitioning tools such as 'fdisk' 'cfdisk' or 'gparted' in linux to create a single linux partition on the SD card. Once the partition is created and formatted, extract the above tarball with:

# Assuming your SD card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar --numeric-owner -xjf debian-armhf-stretch-latest.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync
Note: The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3.

To rewrite the eMMC the unit must be booted to SD or any other media that is not eMMC. Once booted, run the following commands.:

mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget -qO- ftp://ftp.embeddedTS.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/debian/debian-armhf-stretch-latest.tar.bz2 | tar xj -C /mnt/emmc/
umount /mnt/emmc
sync


The same commands can be used to write a SATA drive by substituting /dev/mmcblk2p1 with /dev/sda1.

Debian 9 - Networking

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 9 - WIFI 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 SBC.

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

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 9 - WIFI Access Point

First, hostapd needs to be installed 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 a new hostapd.conf will take effect.

Edit /etc/hostapd/hostapd.conf to include the following lines:

interface=wlan0
driver=nl80211
ssid=YourAPName
channel=1
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 WIFI clients. A DHCP server will likely be desired to assign IP addresses. Refer to Debian's documentation for more details on DHCP configuration.

Debian 9 - Application Development

Debian 9 - 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 9 - 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 9 - 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 9 - 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.

To start an application on bootup with X11 instead change the x-session-manager. By default the system starts xfce:

root@ts:~# ls -lah /usr/bin/x-session-manager 
lrwxrwxrwx 1 root root 35 May 26  2015 /usr/bin/x-session-manager -> /etc/alternatives/x-session-manager
root@ts:~# ls -lah /etc/alternatives/x-session-manager
lrwxrwxrwx 1 root root 19 May 26  2015 /etc/alternatives/x-session-manager -> /usr/bin/startxfce4

The x-session can be modified to only start specified processes. Create the file /usr/bin/mini-x-session with these contents:

#!/bin/bash
matchbox-window-manager -use_titlebar no &

exec xfce4-terminal

You may need to "apt-get install matchbox-window-manager." first. This is a tiny window manager which also has a few flags that simplify embedded use. Now enable this session manager and restart slim to restart x11 and show it now.

chmod a+x /usr/bin/mini-x-session
rm /etc/alternatives/x-session-manager
ln -s /usr/bin/mini-x-session /etc/alternatives/x-session-manager
service slim restart

If the x-session-manager process ever closes x11 will restart. The exec command allows a new process to take over the existing PID. In the above example xfce4-terminal takes over the PID of x-session-manager. If the terminal is closed with commands like exit the slim/x11 processes will restart.

Debian 8 - Jessie

Debian 8 - Getting Started

Once installed, the default user is "root" with no password.

Note: This is a shared image that supports the TS-4900, TS-7970, and TS-TPC-7990.


To prepare an SD card, use partitioning tools such as 'fdisk' 'cfdisk' or 'gparted' in linux to create a single linux partition on the SD card. Once the partition is set up and formatted, extract the above tarball with:

# Assuming your SD card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar --numeric-owner -xjf debian-armhf-jessie-latest.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync
Note: The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3.

To rewrite the eMMC the unit must be booted to SD or any other media that is not eMMC. Once booted, run the following commands.:

mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget -qO- https://files.embeddedTS.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/debian/debian-armhf-jessie-latest.tar.bz2 | tar xj -C /mnt/emmc/
umount /mnt/emmc
sync


The same commands can be used to write a SATA drive by substituting /dev/mmcblk2p1 with /dev/sda1.

Debian 8 - Networking

From almost any Linux system you can use 'ip' command or the 'ifconfig' and 'route' commands to initially set up the network.

# Bring up the CPU network interface
ifconfig eth0 up

# Or if you're on a baseboard with a second ethernet port, you can use that as:
ifconfig eth1 up

# Set an ip address (assumes 255.255.255.0 subnet mask)
ifconfig eth0 192.168.0.50

# Set a specific subnet
ifconfig eth0 192.168.0.50 netmask 255.255.0.0

# Configure your route.  This is the server that provides your internet connection.
route add default gw 192.168.0.1

# Edit /etc/resolv.conf for your DNS server
echo "nameserver 192.168.0.1" > /etc/resolv.conf

Most networks will offer a DHCP server, an IP address can be obtained from a server with a single command in linux:

Configure DHCP in Debian:

# To setup the default CPU ethernet port
dhclient eth0
# Or if you're on a baseboard with a second ethernet port, you can use that as:
dhclient eth1
# You can configure all ethernet ports for a dhcp response with
dhclient


Systemd provides a networking configuration option to allow for automatic configuration on startup. Systemd-networkd has a number of different configuration files, some of the default examples and setup steps are outlined below.

/etc/systemd/network/eth.network

[Match]
Name=eth*

[Network]
DHCP=yes

To use DHCP to configure DNS via systemd, start and enable the network name resolver service, systemd-resolved:

systemctl start systemd-resolved.service 
systemctl enable systemd-resolved.service
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf


For a static config create a network configuration for that specific interface.

/etc/systemd/network/eth0.network

[Match]
Name=eth0

[Network]
Address=192.168.0.50/24
Gateway=192.168.0.1
DNS=192.168.0.1

For more information on networking, see Debian and systemd's documentation:

Debian 8 - WIFI Client

If connecting to a WPA/WPA2 network, a wpa_supplicant config file must first be created:

wpa_passphrase yournetwork yournetworkpassphrase > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf


Create the file /lib/systemd/system/wpa_supplicant@.service with these contents

[Unit]
Description=WPA supplicant daemon (interface-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device

[Service]
Type=simple
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I

[Install]
Alias=multi-user.target.wants/wpa_supplicant@%i.service


Create the file /etc/systemd/network/wlan0.network with:

[Match]
Name=wlan0

[Network]
DHCP=yes

See the systemctl-networkd example for setting a static IP for a network interface. The wlan0.network can be configured the same way as an eth.network.


To enable all of the changes that have been made, run the following commands:

systemctl enable wpa_supplicant@wlan0
systemctl start wpa_supplicant@wlan0
systemctl restart systemd-networkd

Debian 8 - WIFI Access Point

First, hostapd needs to be installed 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 a new hostapd.conf will take effect.

Edit /etc/hostapd/hostapd.conf to include the following lines:

interface=wlan0
driver=nl80211
ssid=YourAPName
channel=1
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 WIFI clients. A DHCP server will likely be desired to assign IP addresses. Refer to Debian's documentation for more details on DHCP configuration.

Debian 8 - Application Development

Debian 8 - Jessie Cross Compiling

Debian Jessie previously provided cross compilers via the Emdebian project. However, Emdebian has been unmaintained for a number of years and is no longer able to provide a viable install package. In order to cross compile from a Debian Jessie workstation, a third party cross compiler is required.

A Debian Jessie install on a workstation has the ability to build for the same release on other architectures using Debian binary libraries. A PC, virtual machine, or chroot will need to be used for this. Install Debian Jessie for your workstation here.

From a Debian workstation (not the target), run the following commands to set up the cross compiler. Note that this expects a 64-bit Debian Jessie install on the workstation. 32-bit installations are not supported at this time.

# Run "lsb_release -a" and verify Debian 8.X is returned.  These instructions are not
# expected to work on any other version or distribution.

cd ~
wget http://ftp.embeddedTS.com/ftp/ts-arm-sbc/ts-7553-V2-linux/cross-toolchains/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf.tar.xz
# The above toolchain is from Linaro. Other cross compilers can be used but have not been tested.
mkdir cross_compiler
tar xvf gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf.tar.xz -C ~/cross_compiler
export PATH=$PATH:~/cross_compiler/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin/
# The 'export' command needs to be run every time the user logs in. It is possible to add this command to the user's ".bashrc" file
# in their home directory to ensure it is automatically run every time the user is logged in.
su root
dpkg --add-architecture armhf
apt-get update
apt-get install build-essential

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 Jessie 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 ".so" files. 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. Note that since the cross compiler used is 3rd party and not directly from Debian, some compile commands that include libraries will need additional arguments to tell the compiler and linker where on the workstation to find the necessary headers and libraries. Usually, the additional arguments will look like the following string, however adjustments may need to be made depending on the application.

 -I/usr/include -L/usr/lib/arm-linux-gnueabihf -L/lib/arm-linux-gnueabihf -Wl,-rpath=/usr/lib/arm-linux-gnueabihf,-rpath=/lib/arm-linux-gnueabihf


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 -I/usr/include -L/usr/lib/arm-linux-gnueabihf -L/lib/arm-linux-gnueabihf -Wl,-rpath=/usr/lib/arm-linux-gnueabihf,-rpath=/lib/arm-linux-gnueabihf 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 8 - 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.

Older Debian releases are moved to a different server to indicate it is no longer getting security updates. To download packages for these older distributions, edit /etc/apt/sources.list to only have the following lines:

Jessie:

deb http://archive.debian.org/debian/ jessie main
deb-src http://archive.debian.org/debian/ jessie main

Wheezy:

deb http://archive.debian.org/debian/ wheezy main
deb-src http://archive.debian.org/debian/ wheezy main

After modifying that file, be sure to update the package list:

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
jvm-7-avian-jre - lightweight virtual machine using the OpenJDK class library
freemind - Java Program for creating and viewing Mindmaps
icedtea-7-plugin - web browser plugin based on OpenJDK and IcedTea to execute Java applets
default-jdk - Standard Java or Java compatible Development Kit
default-jdk-doc - Standard Java or Java compatible Development Kit (documentation)
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)
icedtea-7-jre-jamvm - Alternative JVM for OpenJDK, using JamVM
openjdk-7-dbg - Java runtime based on OpenJDK (debugging symbols)
openjdk-7-demo - Java runtime based on OpenJDK (demos and examples)
openjdk-7-doc - OpenJDK Development Kit (JDK) documentation
openjdk-7-jdk - OpenJDK Development Kit (JDK)
openjdk-7-jre - OpenJDK Java runtime, using Hotspot Zero
openjdk-7-jre-headless - OpenJDK Java runtime, using Hotspot Zero (headless)
openjdk-7-jre-lib - OpenJDK Java runtime (architecture independent libraries)
openjdk-7-source - OpenJDK Development Kit (JDK) source files
uwsgi-app-integration-plugins - plugins for integration of uWSGI and application
uwsgi-plugin-jvm-openjdk-7 - Java plugin for uWSGI (OpenJDK 7)
uwsgi-plugin-jwsgi-openjdk-7 - JWSGI plugin for uWSGI (OpenJDK 7)
                                                       

In this case you will want the openjdk-7-jre package. Names of packages are on Debian's wiki or the packages site.

With the package name apt-get install can be used to install the prebuilt packages.

apt-get install openjdk-7-jre
# More than one package can be installed at a time.
apt-get install openjdk-7-jre nano vim mplayer

For more information on using apt-get refer to Debian's documentation here.

Debian 8 - Setting up SSH

To install ssh, install the package as normal with apt-get:

apt-get install openssh-server


Make sure the device is configured on the network and set a password for the remote user. SSH will not allow remote connections without a password or a valid SSH key pair.

passwd root
Note: The default OpenSSH server will not permit root to login via SSH as a security precaution. To allow root to log in via ssh anyway, edit the /etc/ssh/sshd_config file and add the line PermitRootLogin yes in the authentication section. This change will take effect after reboot or after sshd service restart.

After this setup it is now possible to connect from a remote PC supporting SSH. On Linux/OS X this is the "ssh" command, or from Windows using a client such as PuTTY.

Note: If a DNS server is not present on the target network, it is possible to save time at login by adding "UseDNS no" in /etc/ssh/sshd_config.

Debian 8 - 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.

To start an application on bootup with X11 instead change the x-session-manager. By default the system starts xfce:

root@ts:~# ls -lah /usr/bin/x-session-manager 
lrwxrwxrwx 1 root root 35 May 26  2015 /usr/bin/x-session-manager -> /etc/alternatives/x-session-manager
root@ts:~# ls -lah /etc/alternatives/x-session-manager
lrwxrwxrwx 1 root root 19 May 26  2015 /etc/alternatives/x-session-manager -> /usr/bin/startxfce4

The x-session can be modified to only start specified processes. Create the file /usr/bin/mini-x-session with these contents:

#!/bin/bash
matchbox-window-manager -use_titlebar no &

exec xfce4-terminal

You may need to "apt-get install matchbox-window-manager." first. This is a tiny window manager which also has a few flags that simplify embedded use. Now enable this session manager and restart slim to restart x11 and show it now.

chmod a+x /usr/bin/mini-x-session
rm /etc/alternatives/x-session-manager
ln -s /usr/bin/mini-x-session /etc/alternatives/x-session-manager
service slim restart

If the x-session-manager process ever closes x11 will restart. The exec command allows a new process to take over the existing PID. In the above example xfce4-terminal takes over the PID of x-session-manager. If the terminal is closed with commands like exit the slim/x11 processes will restart.