Search by Tags

Kernel Driver Backports Integration

 
Applicable for

Article updated at 13 Dec 2019
Compare with Revision




Subscribe for this article updates

Introduction

For many off-the-shelf devices to work a suitable driver needs to be compiled into a custom Linux kernel. Not all such drivers are available in custom downstream Linux kernels in which case one can use the driver backports package including suitable drivers available from later Linux kernel versions.

In other words, backports allows the use of drivers from a newer kernel version on an older kernel version. For instance, we can use Wi-Fi drivers from mainline kernel release 4.19 into our NXP i.MX downstream based on 4.9.

Toradex provides a Git repository for backports: backports-toradex.git

Driver backports are available for the following subsystems:

  • Bluetooth
  • Ethernet
  • IEEE 802.15.4 (ZigBee & 6LoWPAN)
  • Media
  • NFC
  • Regulator
  • Wireless

Supported Embedded Linux BSP Releases

Starting from the Embedded Linux BSP 2.7b4 until 2.8, Toradex added kernel driver backports to its demo images, therefore you may want to have a look at how to build our BSP from scratch using OpenEmbedded, since the backports are already integrated there.

Backports support on Embedded Linux BSP 3.0 has been mostly dropped. See some comments about this below:

  • The downstream Linux kernel for supported NXP SoCs is recent enough (4.14 for i.MX as of December 2019).
  • We have the policy to mainline our BSP development. It conflicts with keeping the backports, which is a demanding and complex task.
  • Should backports ever be requested by customers going forward, we shall re-evaluate our current decision in the future.
  • For the downstream Apalis TK1 3.10 kernel backports 4.19 is still used unchanged from BSP 2.8.

Attention: Backports are only supported between Embedded Linux BSP 2.7b4 and 2.8 releases (with the exception of downstream Apalis TK1 in BSP 3.0).

How to Cross-Compile the Backports Drivers From Source

This section provides information on how to cross-compile the Wi-Fi backports. The instructions apply to other drivers/subsystems.

To enable support for driver backports a custom Linux kernel is required. Please refer to the following article concerning setup/compilation of the same:

Build U-Boot and Linux Kernel from Source Code

Remarks About L4T Linux Kernel

The L4T Linux kernel from NVIDIA is not based on top of a clean 3.1 kernel but rather some pre 3.2 version with further Android additions. The backports drivers integrated into the demo images already take that into consideration and have been tested with the L4T Linux kernel.

If manually building backports, one needs to disable the drivers/dependencies enabled in the L4T Linux kernel before cross-compiling the driver backports to avoid any conflicts.

For cross-compiling iwlwifi, it is necessary to disable the following configs in the L4T Linux kernel:

  • CONFIG_CFG80211
  • CONFIG_WLAN

Then just compile and deploy the custom kernel as explained in the above-mentioned article.

Obtain the Toradex BSP Backports Version

The Toradex BSP uses a specific backports version and configuration. To use it, first, you have to find out the OpenEmbedded/Yocto Codename that corresponds to the BSP version you want to build the backports for. Check the table at the beginning of the OpenEmbedded (Core) article.

Attention: Only BSP 2.7 and 2.8 (plus downstream Apalis TK1 on BSP 3.0) support backports integration.

For instance:

  • For BSP 2.7, the <codename> is morty.
  • For BSP 2.8, the <codename> is rocko.

Clone the meta-toradex-bsp-common Yocto layer from Toradex using the codename above as branch:

$ cd ~
$ git clone -b <codename> git://git.toradex.com/meta-toradex-bsp-common.git

You can check the backports version and the corresponding name from the respective backports recipe name:

$ ls meta-toradex-bsp-common/recipes-kernel/backports/

For instance, as of 2019-december-11:

# For BSP 2.7
backports_4.11.bb --> means backports from kernel 4.11

# For BSP 2.8
backports_4.19.bb --> means backports from kernel 4.19

From now on, the version will be referred to as <version>.

Obtain the Toradex BSP Backports Configuration

Copy the sample configuration file to your computer, temporarily. Erase the meta-toradex-bsp-common, as you don't need it anymore,

$ cd ~
$ cp meta-toradex-bsp-common/recipes-kernel/backports/files/config ~/toradex-bsp
$ rm -rf meta-toradex-bsp-common

Fetch the Kernel Backports Source Code

Clone the backports Git repository, side-by-side with the Linux kernel repository, to your machine and checkout the corresponding remote branch that matches the backports version found in the previous section:

$ cd ~
$ git clone -b toradex-<version> git://git.toradex.com/backports-toradex.git

You should have the following directory structure:

$ ls | grep "*-toradex"
linux-toradex
backports-toradex

Create a directory for kernel module deployment, as described in Kernel Module Compilation, if not created already:

$ mkdir -p ~/linux-toradex/modules

We will refer to linux-toradex as <kernel-build-directory> and linux-toradex/modules as module-deployment-direcory.

Additional Setup on Top of the Kernel Compilation Setup

Export a few more environment variables in addition to the ones described here.

$ export KLIB=<module-deployment-direcory>
$ export KLIB_BUILD=<kernel-build-directory>

E.g. if you have cloned both the Linux kernel and backports to your home:

$ export KLIB=~/linux-toradex/modules
$ export KLIB_BUILD=~/linux-toradex

Install the Toradex BSP Default Configuration

Move the temporary toradex-bsp file to the defconfigs directory and load the Toradex BSP configuration:

$ cd ~
$ mv ~/toradex-bsp ~/backports-toradex/defconfigs/
$ cd backports-toradex
$ make defconfig-toradex-bsp

Note: Ignore any error messages that are printed to the command-line output.

Build the Backports

The 'make install' target isn't currently sane for cross-builds. In Makefile.real, there is a rule named install: modules. See for yourself:

$ grep -nre "install: modules" Makefile*
Makefile.real:91:install: modules

Remove the commands inside the rule install: modules that are after the modules_install command. See the diff below for reference:

$ git diff Makefile.real
diff --git a/Makefile.real b/Makefile.real
index 6550802..0fb1d20 100644
--- a/Makefile.real
+++ b/Makefile.real
@@ -92,11 +92,6 @@ install: modules
        @$(MAKE) -C $(KLIB_BUILD) M=$(BACKPORT_DIR)                     \
                INSTALL_MOD_DIR=$(KMODDIR) $(KMODPATH_ARG)              \
                modules_install
-       @./scripts/blacklist.sh $(KLIB)/ $(KLIB)/$(KMODDIR)
-       @./scripts/compress_modules.sh $(KLIB)/$(KMODDIR)
-       @./scripts/check_depmod.sh
-       @/sbin/depmod -a
-       @./scripts/update-initramfs.sh $(KLIB)
        @echo
        @echo Your backported driver modules should be installed now.
        @echo Reboot.

Build the modules and install to linux-toradex/modules:

$ make -j$(nproc) modules_install

Deploy the Backports

The backports are now in the directory linux-toradex/modules, presumably, the same directory that you have previously created while following the article Build the Linux Kernel from Source Code.

Now you can go back to the section where you left off Compile the Kernel Backports - Only for BSP 2.8 and continue your journey towards building and deploying the kernel, modules and backports to your Computer on Module. But first, make sure that you read this article until the end, because additional firmware may be required for the proper operation of the backports drivers.

Attention: Before you go back to the workflow of the article Build the Linux Kernel from Source Code, read this article until the end.

Optional - Generic Backports Configuration

One can use nconfig/menuconfig to configure the driver backports package. Default configuration files are also available which can be used to build the drivers/subsystems. If you choose to use this option just use the make defconfig-option in replacement for make menuconfig.

$ make defconfig-help
Driver or subsystem configuration targets:
  defconfig-ar5523
  defconfig-ath10k
  defconfig-ath5k
  defconfig-ath6kl
  defconfig-ath9k
  defconfig-ath9k-debug
  defconfig-b43
  defconfig-b43legacy
  defconfig-brcmfmac
  defconfig-brcmsmac
  defconfig-carl9170
  defconfig-cw1200
  defconfig-hwsim
  defconfig-iwlwifi
  defconfig-rtlwifi
  defconfig-wcn36xx
  defconfig-wifi
  defconfig-wil6210
  defconfig-wwan

For example to compile Wi-Fi and Bluetooth drivers:

$ make defconfig-wifi_bt
$ make -j4 modules

Note: For BSP 2.7 only defconfig-wifi (e.g. without Bluetooth) is available.

Firmware

Most Wi-Fi hardware uses specific firmware to operate properly. Certain such firmware can easily be installed as follows:

# opkg update
# opkg --force-depends install linux-firmware

Intel 7260 mini-PCIe Wi-Fi module with backported iwlwifi driver on Apalis T30.

During boot one gets the following kernel messages:

[   13.801594] Loading modules backported from Linux version v3.11.8-0-g02709ef                                                                                      
[   13.849714] Backport generated by backports.git v3.11.8-1-0-gb22d1cd                                                                                              
[   14.638853] cfg80211: Calling CRDA to update world regulatory domain                                                                                              
[   15.068568] Intel(R) Wireless WiFi driver for Linux, in-tree:d                                                                                                    
[   15.076809] Copyright(c) 2003-2013 Intel Corporation                                                                                                              
[   15.171085] iwlwifi 0000:04:00.0: loaded firmware version 22.1.7.0 op_mode iwlmvm                                                                                 
[   16.786565] iwlwifi 0000:04:00.0: Detected Intel(R) Wireless N 7260, REV=0x144                                                                                    
[   16.800739] iwlwifi 0000:04:00.0: L1 Disabled; Enabling L0S                                                                                                       
[   16.809894] iwlwifi 0000:04:00.0: L1 Disabled; Enabling L0S                                                                                                       
[   17.038502] Registered led device: phy0-led                                                                                                                       
[   18.410483] ADDRCONF(NETDEV_UP): enp7s0: link is not ready                                                                                                        
[   18.425138] ieee80211 phy0: Selected rate control algorithm 'iwl-mvm-rs'                                                                                          
[   18.493031] iwlwifi 0000:04:00.0: L1 Disabled; Enabling L0S                                                                                                       
[   18.498950] iwlwifi 0000:04:00.0: L1 Disabled; Enabling L0S                                                                                                       
[   18.544093] ADDRCONF(NETDEV_UP): wlp4s0: link is not ready                             
....
root@apalis-t30:~# uname -a
Linux apalis-t30 3.1.10-g54d69d3 #23 SMP PREEMPT Wed Jun 10 17:46:46 IST 2015 armv7l GNU/Linux
root@apalis-t30:~# ls /lib/modules/3.1.10-g54d69d3/
modules.alias        modules.dep          modules.softdep      updates
modules.alias.bin    modules.dep.bin      modules.symbols
modules.builtin.bin  modules.devname      modules.symbols.bin
root@apalis-t30:~# lsmod
Module                  Size  Used by
iwlmvm                150786  0 
mac80211              477632  1 iwlmvm
iwlwifi               153573  1 iwlmvm
cfg80211              439297  3 iwlwifi,mac80211,iwlmvm
compat                 24552  4 cfg80211,iwlwifi,mac80211,iwlmvm