Debian Linux 11 (Bullseye)
Debian 11 - Bullseye
Debian 11 - Getting Started and writing an Image
Once installed, the default user is "root" with no password.
This image can be written to a USB drive, or to the eMMC. For development, a USB thumbdrive will be simplest. If a bootable USB drive is connected this will take priority over other boot media. Plug in a USB drive and check the last output from "dmesg" to get the USB disk. For example, this may be /dev/sdc.
# Erase all older partitions
sudo sgdisk --zap-all /dev/sdc
# Create one GPT Linux partition
sudo sgdisk -n 0:0:0 -t 0:8300 /dev/sdc
# Create a filesystem and mount
sudo mkfs.ext4 /dev/sdc1
sudo mkdir /mnt/usb/
sudo mount /dev/sdc1 /mnt/usb/
# Extract downloaded image:
sudo tar --numeric-owner -xf tsimx6ul-debian-bullseye-latest.tar.xz -C /mnt/usb/
sudo chmod 755 /mnt/usb/
sudo umount /mnt/usb/
These commands will also work while booted from a USB drive to rewrite the eMMC. Instead of /dev/sdc you would use /dev/mmcblk0, and instead of /dev/sdc1 you would use /dev/mmcblk0p1.
Debian 11 - Configuring Network
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
| 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 11 - WIFI 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. |
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 11 - 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 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 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 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 11 - Backup the image
To create backups / restore images, it is recommended to first boot to USB. A disk should not be backed up or written while it is used to boot.
If your image is a single partition it can be backed up as a tar file. This allows the media to easily expand to any disk size.
Create a backup tar
mkdir /mnt/emmc
mount /dev/mmcblk0p1 /mnt/emmc/
tar -cJf /root/backup-of-image.tar.xz -C /mnt/emmc/
umount /mnt/emmc/
Write a tar image to the eMMC
sgdisk --zap-all /dev/mmcblk0
sgdisk -n 0:0:0 -t 0:8300 /dev/mmcblk0
mkfs.ext4 /dev/mmcblk0p1
mkdir /mnt/emmc
mount /dev/mmcblk0p1 /mnt/emmc/
tar -xf /root/backup-of-image.tar.xz -C /mnt/emmc/
umount /mnt/emmc/
Debian 11 - Compile the Kernel
A compatible armhf cross compiler is needed for building the 5.10 kernel. We recommend using the cross compiler available in Debian distributions. It is also possible to use our Buildroot repository to build a compatible cross compiler.
Download and Configure
These steps assume a host Linux workstation with an appropriate cross compiler. While on most platforms the kernel can be downloaded, built, and installed all on the device, we recommend against this due to the amount of time, memory, and disk space that can be needed for a build.
Prerequisites
If using our instructions for using Docker to handle the cross compiler, then the Docker environment needs to be entered first:
# Create a place to store the kernel:
mkdir -p ~/Projects/tsimx6ul/kernel/
cd ~/Projects/tsimx6ul/kernel/
docker-debian-bookworm
If the Docker container is not being used, a number of host tools are required to be installed on the workstation:
# Install dependencies for kernel build
# The following command is for Ubuntu / Debian workstations. If using a different
# distribution, please consult distribution docs for the proper commands to install
# new packages/tools/libraries/etc.
apt-get install git fakeroot build-essential ncurses-dev xz-utils lzop libssl-dev bc flex libelf-dev bison
| Note: | The above prerequisite libraries and tools may not be the complete list, depending on the workstation's distribution and age. It may be necessary to install additional packages to support kernel compilation. |
Download kernel repo on a host Linux workstation:
# Do a shallow clone of the sources
git clone --depth 1 -b linux-5.10.y https://github.com/embeddedTS/linux-lts
cd linux-lts/
Configure environment variables needed for building. This specifies the architecture, the cross compiler that is being used, and to set up building the kernel modules for the WILC3000 Wi-Fi/BLE module:
export CROSS_COMPILE=arm-linux-gnueabihf- # This may be different if using a different compiler!
export ARCH=arm
export WILC=y
The WILC3000 Wi-Fi/BLE drivers are maintained and built externally out of the kernel tree. Clone this tree inside of the linux-lts/ directory (this is built later):
git clone -b linux4microchip-2021.10-1 https://github.com/embeddedTS/wilc3000-external-module/
Next, set the default configuration for this platform. Note that a minimal defconfig and a full-feature defconfig are available. The minimal defconfig contains options for supporting the device and a few common peripherals and technologies. While the full defconfig includes much more support for things like USB devices, a more broad range of netfilter/iptables filter module support, etc.
make tsimx6ul_defconfig
# The minimal defconfig can alternately be used with:
# make tsimx6ul_minimal_defconfig
Build and Install
| Note: | If using the Docker container to cross compile, be sure to exit the container after the build script below completes! The tarball will be located in the linux-lts/ folder that was created.
|
The following will build the kernel and modules, and install the kernel, modules, and headers to a folder and create a tarball from that. This tarball can be unpacked to bootable media, e.g. microSD, eMMC, USB, etc., to update an existing bootable disk.
The script below is most easily saved as a text file and run from the command line as a script. Most terminal emulators will accept the whole script copy/pasted in to the terminal. But it is also possible to copy paste each line of text in to a terminal. In any case, the following is an example of how to compile the kernel. The script or commands used can be modified as needed to suit a specific build pipeline.
The script assumes the following environment variables are set before it is run. See the above sections for what these variables should be set to for this specific platform.
ARCH- Used to indicate the target CPU architecture.
CROSS_COMPILE- Used to point to an appropriate cross toolchain for the target platform.
LOADADDR[Optional]- Used on some platforms to tell U-Boot where to load the file.
WILC[Optional]- Set to "y" to build and install the WILC3000 Wi-Fi/BLE external modules.
#!/bin/bash -e
# Always build zImage, most common. If LOADADDR is set, then uImage is also built
TARGETS="zImage"
if [ -n "${LOADADDR}" ]; then TARGETS+=" uImage"; fi
# Build the actual kernel, binary files, and loadable modules.
# Use as many CPUs to do this as possible.
make -j"$(nproc)" && make ${TARGETS} && make modules
# Create a temporary directory to install the kernel to in order to use that as a base directory for a tarball.
# Also creates a temporary file that is used as the tarball name.
TEMPDIR=$(mktemp -d)
TEMPFILE=$(mktemp)
mkdir "${TEMPDIR}/boot/"
# Adds "arch/arm/boot/" path prefix to each TARGET
cp $(for i in ${TARGETS}; do echo arch/arm/boot/$i; done) "${TEMPDIR}"/boot/
# Copy the full .config file to the target, this is optional and can be removed
cp .config "${TEMPDIR}"/boot/config
# Copy all of the generated FDT binary files to the target
find arch/arm/boot/dts -name "*ts*.dtb" -exec cp {} "${TEMPDIR}/boot" \;
# Install kernel modules to the target
INSTALL_MOD_PATH="${TEMPDIR}" make modules_install
# Install kernel headers to the target, this is optional in most cases and can be removed to save space on the target
make headers_install INSTALL_HDR_PATH="${TEMPDIR}"
# If WILC is set to "y", then build the external module for the WILC300 Wi-Fi/BLE device.
# Note that this expects the source to be available as a subfolder in the kernel. See the above sections
# for details on getting the driver source if it is used on this specific platform.
if [ "${WILC}" == "y" ]; then
CONFIG_WILC_SPI=m INSTALL_MOD_PATH="${TEMPDIR}" make M=wilc3000-external-module modules modules_install
fi
# Use fakeroot to properly set permissions on the target folder as well as create a tarball from this.
fakeroot sh -c "chmod 755 ${TEMPDIR};
chown -R root:root ${TEMPDIR};
tar czf ${TEMPFILE}.tar.gz -C ${TEMPDIR} .";
# Create a final output tarball and cleanup all of the temporary files and folder.
cp ${TEMPFILE}.tar.gz embeddedTS-linux-lts-"$(date +"%Y%m%d")"-"$(git describe --abbrev=8 --dirty --always)".tar.gz
rm -rf "${TEMPDIR}" "${TEMPFILE}"
At this point, the tarball can be unpacked to a bootable media for the device. This can be done from a booted device, or by mounting removable media from a host Linux workstation. For example, if the root folder of the target filesystem to be updated is mounted to /mnt/, the following can be used to unpack the above tarball:
# Ensure the target filesystem is mounted to /mnt first!
# Extract kernel tarball to target filesystem,
tar xhf embeddedTS-linux-lts-*.tar.gz -C /mnt
| Note: | The h argument to tar is necessary on recent distributions that use paths with symlinks. Not using it can potentially render the whole filesystem no longer bootable.
|
This will correctly unpack the kernel, modules, and headers to the target filesystem which can then be booted as normal.