Skip to main content
Version: 6

Build Linux Kernel from Source Code

Introduction

This article describes how to build the Linux kernel without using a higher-level build system such as the Yocto Project/OpenEmbedded. This procedure mostly makes sense during Linux development.

We provide OpenEmbedded recipes that build U-Boot and Linux as part of a complete BSP image; hence if you plan to build a full BSP image, follow the Build a Reference Image with Yocto Project/OpenEmbedded article.

You might also need to compile the Linux kernel driver backports. If this is the case, see the specific article Kernel Driver Backports Integration.

The Linux kernel is available on our Git server at git.toradex.com.

This is the second article of a three-part series about building from source code. Check the following articles if you are looking for information about:

Prerequisites

Prepare the Host Machine for Cross-Compilation

Use version 9.2 of the Arm releases binary toolchains to cross-compile software for Toradex modules:

  • For 32 bit Arm: gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz
  • For 64 bit Arm: gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz

You have to choose to download either the 32 bit or 64 bit Arm cross-toolchain, according to the architecture of your Computer on Module SoC. Select the correct one from the tabs below:

To install the toolchain on your host machine, download and unpack the tar.xz file. From the command-line:

$ cd ~
$ wget -O gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz "https://developer.arm.com/-/media/Files/downloads/gnu-a/9.2-2019.12/binrel/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz?revision=fed31ee5-2ed7-40c8-9e0e-474299a3c4ac&la=en&hash=76DAF56606E7CB66CC5B5B33D8FB90D9F24C9D20"
$ tar xvf gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz
$ ln -s gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf gcc-linaro

Or you can download the toolchain from Arm website.

The U-Boot and Linux makefiles use the environment variables ARCH/CROSS_COMPILE to configure and call the compiler correctly. Therefore, these environment variables must be exported in any shell instance that will run configure/compile commands to build U-Boot or Linux for the target module.

$ export ARCH=arm
$ export DTC_FLAGS="-@"
$ export PATH=~/gcc-linaro/bin/:$PATH
$ export CROSS_COMPILE=arm-none-linux-gnueabihf-

You can put those commands into a file and source that file to export it more easily, e.g.:

$ echo "export ARCH=arm" >> ~/export_compiler
$ echo "export DTC_FLAGS='-@'" >> ~/export_compiler
$ echo "export PATH=~/gcc-linaro/bin/:$PATH" >> ~/export_compiler
$ echo "export CROSS_COMPILE=arm-none-linux-gnueabihf-" >> ~/export_compiler
$ source ~/export_compiler

Install Tools and Dependencies

Build Host

You need some essential build tools to compile the Kernel or DTC. Most are likely part of your distro's standard install.

For Fedora:

$ sudo dnf install bc gcc git ncurses-devel lzop make perl openssl-devel bison flex diffutils

For Debian/Ubuntu:

$ sudo apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev bison flex

U-Boot Tools

The uImage target of the Linux kernel compilation needs a recent mkimage tool.

One can install the Fedora package uboot-tools:

$ sudo dnf install uboot-tools

Or with the corresponding Debian/Ubuntu package u-boot-tools:

$ sudo apt-get install u-boot-tools

Alternatively, mkimage tool is also built during the U-Boot compilation. You can follow the U-Boot building instructions as explained further in this article, and after that, include it in PATH.

Kernel Version Information

The required git branch and Linux binaries to be used depend on module type and BSP version, as we will explain in this article.

For a high-level overview of the BSP Versions, check out our Embedded Linux Release Matrix. There you will find the version information of the Linux kernel, U-Boot, Yocto/OpenEmbedded, the Toradex BSP, and Linux images, along with release dates.

Upstream-based Kernel

SoCKernel ConfigurationKernel Binary
i.MX 8MM/8MPmasterdefconfig
i.MX 7masterimx_v6_v7_defconfig
i.MX 6masterimx_v6_v7_defconfig
i.MX 6ULLmasterimx_v6_v7_defconfig

For the upstream-based kernel, the Kernel Git Branch is master and the tags can be:

  • BSP 6.0.0: v6.0
  • BSP 6.1.0: v6.1

Downstream-based Kernel

SoCKernel Git BranchKernel ConfigurationKernel Binary
i.MX 8MM/8MPtoradex_5.15-2.0.x-imxtoradex_defconfigarch/arm64/boot/Image.gz

Device Tree Binaries Information

View Device Tree version information
SoCDevice Tree
i.MX 8/8X/8MM/8MPimx8qm-apalis-eval.dtb
imx8qm-apalis-ixora-v1.1.dtb
imx8qm-apalis-v1.1-eval.dtb
imx8qm-apalis-v1.1-ixora-v1.1.dtb
imx8qm-apalis-v1.1-ixora-v1.2.dtb
imx8qp-apalis-v1.1-eval.dtb
imx8qp-apalis-v1.1-ixora-v1.1.dtb
imx8qp-apalis-v1.1-ixora-v1.2.dtb
imx8mm-verdin-nonwifi-dahlia.dtb
imx8mm-verdin-nonwifi-dev.dtb
imx8mm-verdin-wifi-dahlia.dtb
imx8mm-verdin-wifi-dev.dtb
imx8mp-verdin-nonwifi-dahlia.dtb
imx8mp-verdin-nonwifi-dev.dtb
imx8mp-verdin-wifi-dahlia.dtb
imx8mp-verdin-wifi-dev.dtb
i.MX 7imx7d-colibri-aster.dtb
imx7d-colibri-emmc-aster.dtb
imx7d-colibri-emmc-eval-v3.dtb
imx7d-colibri-eval-v3.dtb
imx7s-colibri-aster.dtb
imx7s-colibri-eval-v3.dtb
i.MX 6imx6q-apalis-eval.dtb
imx6q-apalis-ixora.dtb
imx6q-apalis-ixora-v1.1.dtb
imx6q-apalis-ixora-v1.2.dtb
imx6dl-colibri-eval-v3.dtb
i.MX 6ULLimx6ull-colibri-emmc-eval-v3.dtb
imx6ull-colibri-eval-v3.dtb
imx6ull-colibri-wifi-eval-v3.dtb

Building Linux Kernel

Download the Linux Kernel Source

Obtain the kernel source code using Git:

$ mkdir -p ~/workdir
$ cd ~/workdir
$ git clone -b <branch> git://git.toradex.com/linux-toradex.git
info

Replace <branch> by the Kernel Git Branch for your specific configuration. Click below to expand the version information. Check the section Kernel Version for this specific information.

If additional patches are provided, apply them as follows: git am <patch files>.

info

If your company firewall/gateway inhibit the git protocol, you may use HTTP or HTTPS instead (e.g. git clone https://git.toradex.com/linux-toradex.git).

Kernel Configuration

Our kernel tree provides default kernel configurations for our modules:

Ensure the environment is configured for cross-compilation as explained in the toolchain chapter.

Set the default configuration:

$ cd ~/workdir/linux-toradex
$ make <defconfig>
info

Replace <defconfig> by the Kernel Configuration for your specific configuration. Check the section Kernel Version for this specific information.

At this point, one may alter the kernel configuration by either editing .config directly (e.g., setting CONFIG_* to either =y or =m aka as module) or use one of the kernel configuration utilities included, e.g.:

$ make nconfig

Kernel Compilation

Depending on the module, different kernel image types are used. Furthermore, some kernels require a device tree to describe the system's hardware (see Device Tree Customization for details).

Our kernel configurations build some drivers as kernel modules.

To assure module compatibility, the Kernel refuses to load modules with a 'vermagic' string that does not match its own. On top of that, the modules are stored under a directory named after the version string.

Thus one usually needs to compile and deploy the kernel modules together with the Kernel in order to use them.

To compile the Kernel & device tree:

$ make -j$(nproc) Image.gz 2>&1 | tee build.log
$ make DTC_FLAGS="-@" freescale/<device-tree>.dtb

Replace <device-tree> by the Device Tree for your specific configuration. Check the section Device Tree Binaries Information for this specific information.

Linux Kernel Module Compilation

info

If you compile and/or use a new kernel, you should update the kernel modules as well because they often have strong dependencies to a specific kernel build.

To compile the kernel modules as configured in .config (everything with CONFIG_*=m), run:

$ make -j$(nproc) modules

Kernel Module Deployment

If kernel modules compiled successfully, you could extract them as follows:

$ sudo -E env "PATH=$PATH" make INSTALL_MOD_PATH=<path-to-rootfs>/ modules_install

Where <path-to-rootfs>/ either points to:

  • the rootfs folder of the previously extracted update package, in which case one has to remember to re-generate and re-flash the root file system image afterward.
  • directly to a NFS rootfs location.
  • a temporary folder, after which the kernel modules must be separately installed on the target as follows:

For example:

$ mkdir modules
$ export INSTALL_MOD_PATH=modules
$ make modules_install
$ cd modules
$ tar -czf ../modules.tar.gz .

Use scp to copy the tarball into your target:

$ scp modules.tar.gz root@<target-ip>:/home/root

In your target's Linux Terminal, extract the tarball in the rootfs as follows:

# cd ~
# tar -xzf modules.tar.gz -C /

You may also integrate your kernel modules into the root file system archive inside a Toradex Easy Installer package where applicable. The Kernel and any kernel modules must be deployed as matching versions.

info

Run depmod on the target after deploying new or changed kernel modules.

Deploying the Kernel to an Image

Follow the steps below to update your Kernel using Toradex Easy Installer.

  1. Start from a Existing Sample Image: Download and extract one of the Toradex prebuild images. Choose the appropriate image for your SoM in the Reference Images for Yocto Project Software Downloads
  2. Integrate Artifacts: Integrate the above-built artifacts into the downloaded embedded Linux image by replacing the kernel binary and device tree(s) in the bootfs.tar.xz archive.
  3. Adjust image.json: Now adjust the image.json to your linking (e.g., change at least the name and description for you to distinguish it from our original package). You may, of course, also change any of the other properties as documented in the Toradex Easy Installer article on our developer website.
  4. Deploy the Toradex Easy Installer Image: You may now use the above prepared Toradex Easy Installer package with the Toradex Easy Installer.
Send Feedback!