Introduction

After designing a custom carrier board for a Variscite System on Module / Computer on Module, one of the first software tasks is to add support for new devices to the Linux kernel. This consists of:

  1. Adding a new device tree file to the Linux kernel
  2. Adding devices to the device tree file
  3. Enabling drivers in the kernel configuration for each device

This guide shows how to enable device drivers in the Linux kernel. Please visit Variscite’s “Getting Started with Variscite Device Trees” guide to learn how to add new device nodes to the device tree.

Kernel defconfig

The defconfig file is a minimal representation of the kernel configuration. It contains a list of drivers that will be compiled as built-in or as modules. Built-in drivers are included in the kernel binary (Image.gz/zImage/uImage). Driver modules are compiled to .ko files and are installed to the root filesystem under “/lib/modules/…”.

The location of the defconfig file in the Linux kernel source tree depends on the SoC architecture:

For 32-bits processors:

arch/arm/configs

For 64-bits processors:

arch/arm64/configs

For example, the defconfig for Variscite’s NXP i.MX8M Mini is located at:

arch/arm64/configs/imx8_var_defconfig

The defconfig contains a list of available drivers. For example:

# CONFIG_CXD2880_SPI_DRV is not set
CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC7=m
CONFIG_DMA_CMA=y

There are three configuration options for each driver:

“is not set” Will not be compiled
“=m” Will be compiled and installed as module (.ko file)
“=y” Will be compiled and installed as built-in

Note that as mentioned before, the defconfig file is a minimal representation of the kernel configuration, so it does not explicitly list all available drivers, but it relies on default values and driver dependencies to represent the complete configuration.

 

NXP iMX 8M Mini System on Module

NXP iMX 8M Mini System on Module

 

Editing the Configuration

    1. It is not recommended to edit the defconfig directly. Instead, the kernel should be configured using the “menuconfig” Make target.
      The following demonstrates the process for configuring the kernel for Variscite’s DART-MX8M-MINI / VAR-SOM-MX8M-MINI:
      Visit https://variwiki.com, click on the SOM and the Yocto release you want to use, and then click on the “Build the Linux kernel from source code” link.
      Follow the instructions on that page to download the kernel source code, change the branch, and configure the cross-compiler.

      For example, the link for the DART-MX8M-MINI / VAR-SOM-MX8M-MINI Yocto Hardknott release:
      https://variwiki.com/index.php?title=Yocto_Build_Linux&release=RELEASE_HARDKNOTT_V1.0_DART-MX8M-MINI
    2. Configure the kernel using the default defconfig for the target board. In this example, use:
      $ make imx8_var_defconfig

      This command will create a complete configuration file called .config, based on imx8_var_defconfig, at the root of the Linux kernel source tree.
      All changes now will be made to the .config file.

    3. Changes are made to the config file by using menuconfig:
      $ make menuconfig
      The following menu will be opened in the terminal window

      Variscite Kernel Configuration Guide_Figure 1

      Figure 2: Kernel menuconfig screen

      Inside the “Device Drivers” item, all available drivers are listed with a check box in the left of each driver.
      These are the options:
      [ ] – Will not be compiled
      [M] – Will be compiled and installed as module
      [*] – Will be compiled and installed as built-in
      After changing the driver’s selection, save and exit the configuration.
      The new configuration will be written to the .config file.

    4. Build the kernel with the make command. This will build the kernel image, modules and device trees.
      $ make -j$(nproc)


      After building the kernel, the binary (Image.gz/zImage/uImage) will be located at arch/arm64/boot/.

      And the compiled device tree blobs (.dtb files) will be located at arch/arm64/boot/dts/freescale/imx8*.

      To install the modules to the root file system, run:

      $ make modules_install INSTALL_MOD_PATH=path_to_the_target_rootfs


      5. Save the changes to the defconfig file.

      After making changes using menuconfig, the new configuration will be saved to .config.
      To make the changes permanent, update arch/arm64/configs/imx8_var_defconfig and commit to Git:

      $ make savedefconfig
      $ mv defconfig arch/arm64/configs/imx8_var_defconfig
      $ git add arch/arm64/configs/imx8_var_defconfig
      $ git commit –m “commit message”

 

VAR-SOM-MX8M-MINI System on Module (SoM)

VAR-SOM-MX8M-MINI SoM

 

Finding and enabling drivers in the defconfig

To find drivers in the kernel, it is best to start by searching the drivers and Documentation directories for the device model. The driver filename can be used to find the kernel configuration option.

The following example demonstrates how to find and enable the driver for the ds1337 real time clock used on some Variscite evaluation kits:

1. Search the “drivers” directory for the device:

$ grep -ir --include "*.c" "ds1337" ./drivers

This produces many matches for:

drivers/rtc/rtc-ds1307.c

2. Find the configuration string by searching the Makefile in the same directory as the .c file:

$ grep "rtc-ds1307" drivers/rtc/Makefile
obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o

3. Enable CONFIG_RTC_DRV_DS1307 using menuconfig

$ make menuconfig

Variscite Kernel Configuration Guide_Figure 2
Search the kernel config options by typing ‘/’

Variscite Kernel Configuration Guide_Figure 3

Type CONFIG_RTC_DRV_DS1307 and select Ok, you will be presented with the search results:

Variscite Kernel Configuration Guide_Figure 4

To select the first search result, type ’1’, and verify that the driver is enabled:

Variscite Kernel Configuration Guide_Figure 5

If the driver is not enabled, select [*] or [M] and exit and save. All necessary dependencies will also be selected, and the new configuration will be written to .config

4. Save the changes to

arch/arm64/configs/imx8_var_defconfig
$ make savedefconfig
$ mv defconfig arch/arm64/configs/imx8_var_defconfig

5. Build the kernel image, modules and device trees

$ make -j$(nproc)

Next Steps

For devices that can be automatically discovered, such as a USB device, enabling the driver in the kernel configuration may be all that is necessary. However, many devices will require one or more nodes to be added to the device tree. To learn more about how to edit the Linux device tree, please visit Variscite’s “Getting Started with Variscite Device Trees” guide, or Variscite’s software wiki, which provides detailed guides for each of Variscite’s modules and supported operating systems.

 

Related Resources

Webinar: Getting Started with Device Tree on Variscite SOMs
Blog post: i.MX Device Tree Pinmux Settings
Blog post: Getting Started with Variscite Device Trees
Blog post: Creating a Custom Yocto BSP Layer
Blog post: Disabling Unused Drivers and Peripherals in Linux