Skip to main content
In some instances, we have found that changes to the Linux kernel may be required in order to connect particular instruments to the system. The challenge for the embeddedTS-7970 SBC is the limited memory space available on the onboard SPI flash—8 MiB. The entire kernel, as well as U-boot (the bootloader that initialises the system), must fit in the available space. EmbeddedTS maintain a version of the Linux kernel source with many of the required module flags enabled in the default config. This config can then be adjusted to enable any additional drivers, providing these drivers do not cause the final kernel image to exceed the aforementioned size. It is easiest to build the kernel image on same system to which it will be deployed, but it is also possible to cross-compile the kernel using a different system. In this tutorial, we will assume you are building the new kernel image on an embeddedTS-7970 single-board computer.

Pre-requisites

In order to build a new kernel image, you will need the following:
  • an SD card with an already functioning version of the Linux kernel and an OS such as Debian 12 (bookworm);
  • the ability to connect to the device, either in headless mode via serial or ethernet or by attaching peripherals (monitor, keyboard, mouse) to the board;
  • an internet connection (see section on networking if you need to set this up) if you wish to clone the kernel sourcecode from the online repository (alternatively, you could copy the source repository onto the SD card before mounting to the board);
  • the following packages installed from the Debian package repository: u-boot-tools, <FIND FULL LIST>.

Building the new kernel image

Get the kernel source

If you did not copy the source repository to the SD card, you will need to clone the repository containing the tuned Linux kernel from the embeddedTS GitHub:
git clone https://github.com/embeddedts/linux-lts
This may take some time, as it is a few GB.

Create a staging directory

Rather than building everything directly inside the cloned repository, we will specify a new directory to collect the outputs of each stage of the kernel build. This helps to keep everything organised in case you need to rebuild the kernel in the future.
mkdir kernel-build<suffix>
export KERNEL_BUILD_OUT=~/kernel-build<suffix>
where you should replace <suffix> with some unique identifier for the kernel build, e.g., -avert. This suffix will be used again when configuring the kernel.
If, for any reason, you do not complete all of these steps in a single session, you may need to re-export the KERNEL_BUILD_OUT variable.

Create an initial configuration file

Navigate to the directory containing the kernel source code (likely ~/linux-lts). Create a new config for the specific i.MX6 processor used on the TS board:
cd ~/linux-lts
make O=$KERNEL_BUILD_OUT tsimx6_defconfig

Edit the configuration file

This is the point when you can select which additional modules/utilities you would like to enable in the kernel. In addition, you should specify the CONFIG_LOCALVERSION here to match the suffix you chose above (e.g., -avert).
make O=$KERNEL_BUILD_OUT nconfig
This will open up a menu in the terminal window that you can navigate with the arrow keys. You can use the search function to find relevant modules to enable/disable (using the function keys as specified at the bottom of the terminal). With the configuration now set, we can propagate these changes. This isn’t strictly necessary, as we will be building the entire kernel from scratch, but for completeness, run the following:
make O=$KERNEL_BUILD_OUT modules_prepare

Build the kernel image and modules

This stage can take a significant amount of time (> 1 hour). In order to ensure this proceeds as quickly as possible, be sure to include the -j flag, which sets the number of cores to be used while compiling the image. For example, for the quad-core model of the 7970, we can use -j 4.
make O=$KERNEL_BUILD_OUT -j 4 Image
Once complete, we have our new kernel image, which can be found at $KERNEL_BUILD_OUT/arch/arm/boot/Image. However, this image is both too large and not directly compatible with U-boot. In order to get the required uImage (and zImage), run:
make O=$KERNEL_BUILD_OUT -j 4 uImage LOADADDR=0x12000000
The important thing here is to specify the LOADADDR, which is a memory address used by the U-boot bootloader to find the image. This can be checked by booting into U-boot (hold down the reset pin while powering the 7970). Repeat the process to build the modules:
make O=$KERNEL_BUILD_OUT -j 4 modules

Install the new image and modules

Once complete, you should have everything needed, the last thing to do is to install the new image and modules. Navigate to the directory containing the freshly built image and modules and install with elevated privileges:
cd ~/$KERNEL_BUILD_OUT
sudo make modules_install
sudo make install
This installs everything except the uImage/zImage files. Make a backup of the current files (found in /boot), then copy the two files with elevated privileges:
mkdir ~/image-backups
sudo cp /boot/zImage ~/image-backups/.
sudo cp /boot/uImage ~/image-backups/.
sudo cp ~/$KERNEL_BUILD_OUT/arch/arm/boot/zImage /boot/.
sudo cp ~/$KERNEL_BUILD_OUT/arch/arm/boot/uImage /boot/.
Finally—reboot the system. Any issues can be diagnosed over the serial connection. If the system fails to boot, you can revert back to the previous kernel image by mounting the SD card on another Linux system and manually moving the uImage and zImage files back to the /boot directory. If everything boots, you can check the new kernel has been correctly loaded by running:
uname -r
This should return the kernel version with the suffix defined in CONFIG_LOCALVERSION.