Kernel development

This guide shows how to obtain and compile a Linux* kernel source using Clear Linux* OS development tooling.

Overview

The Kernels available in Clear Linux OS aim to be performant and practical. In some cases, it may be necessary to modify the kernel to suit your specific needs or test new kernel code as a developer.

Source RPMs (SRPMS) are also available for all Clear Linux OS kernels, and can be used for development instead.

Request changes be included with the Clear Linux OS kernel

If the kernel modification you need is already open source and likely to be useful to others, consider submitting a request to include it in the Clear Linux OS kernels. If your change request is accepted, you do not need to maintain your own modified kernel.

Make enhancement requests to the Clear Linux OS Distribution Project on GitHub*.

Set up kernel development environment

In some cases, it may be necessary to modify the kernel to suit your specific needs or to test new kernel code.

You can build and install a custom kernel; however you must:

  • Disable Secure Boot

  • Maintain any updates to the kernel going forward

To create a custom kernel, start with the Clear Linux OS development environment. Then make changes to the kernel, build it, and install it.

Install the Clear Linux OS development tooling framework

Setup of the workspace and tooling used for building source in Clear Linux OS is mostly automated for you with a setup script. It uses tools from the os-clr-on-clr bundle.

The setup script creates a workspace in the clearlinux folder, with the subfolders Makefile, packages, and projects. The projects folder contains the main tools used for making packages in Clear Linux OS autospec and common.

Follow these steps to setup the workspace and tooling for building source:

  1. Install the os-clr-on-clr bundle:

    sudo swupd bundle-add os-clr-on-clr
    
  2. Download the user-setup.sh script:

    curl -O https://raw.githubusercontent.com/clearlinux/common/master/user-setup.sh
    
  3. Make user-setup.sh executable:

    chmod +x user-setup.sh
    
  4. Run the script as an unprivileged user:

    ./user-setup.sh
    
  5. After the script completes, log out and log in again to complete the setup process.

  6. Set your Git user email and username for the repos on your system:

    git config --global user.email "you@example.com"
    git config --global user.name "Your Name"
    

    This global setting is used by Clear Linux OS tools that make use of Git.

Clone the kernel package

Clone the existing kernel package repository from Clear Linux OS as a starting point.

  1. Clone the Linux kernel package from Clear Linux OS. Using the make clone_<PACKAGENAME> command in the clearlinux/ directory clones the package from the clearlinux-pkgs repo on GitHub.

    cd ~/clearlinux
    make clone_linux
    
  2. Navigate into the cloned package directory.

    cd ~/clearlinux/packages/linux
    

The “linux” package is the kernel that comes with Clear Linux OS in the kernel-native bundle. Alternatively, you can use a different kernel variant as the base for modification. For a list of kernel package names which you can clone instead, see the clearlinux-pkgs repo on GitHub.

Note

The latest version of the Clear Linux OS kernel package is pulled as a starting point. An older version can pulled by switching to different git tag by using git checkout tag/<TAG_NAME>.

Change the kernel version

Clear Linux OS tends to use the latest kernel available from kernel.org, the Linux upstream. The kernel version that will be built can be changed in the RPM SPEC file. While most packages in Clear Linux are typically packaged using autospec, the kernel is not. This means control files provided by autospec are not available and changes must be made manually.

  1. Open the Linux kernel package RPM SPEC file in an editor.

    $EDITOR linux.spec
    
  2. Modify the Version, Release, and Source0 URL entries at the top of the file to change the version of Linux kernel that will be compiled.

    A list of current and available kernel release can be found on kernel.org.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    Name:           linux
    Version:        4.20.8
    Release:        696
    License:        GPL-2.0
    Summary:        The Linux kernel
    Url:            http://www.kernel.org/
    Group:          kernel
    Source0:        https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.20.8.tar.xz
    Source1:        config
    Source2:        cmdline
    
    %define ktarget  native
    

    Note

    • Consider changing the Name from linux in the RPM spec file to easily identify a modified kernel.

    • Consider changing the ktarget from native in the RPM spec file to easily identify a modified kernel.

  3. Commit and save the changes to the file.

Pull a copy of the Linux kernel source code

Obtain a local copy of the source code to make modifications against.

  1. Run make sources to pull the kernel source code specified in the RPM SPEC file. In the example, it downloads the linux-4.20.8.tar.xz file.

    make sources
    
  2. Extract the kernel source code archive. This will create a working copy of the Linux source that you can modify.

    tar -xvf linux-4.20.8.tar.xz
    
  3. Navigate to the extracted directory. In this example, it has been extracted into a linux-4.20.8 directory.

    cd linux-4.20.8/
    

Customize the Linux kernel source

After the kernel sources have been obtained, customizations to the kernel configuration or source code can be made for inclusion with the kernel build. These customizations are optional.

Modify kernel configuration

The kernel source has many configuration options available to pick support for different hardware and software features.

These configuration values must be provided in the .config file at compile time. You will need to make modifications to the .config file, and include it in the kernel package.

  1. Make sure you have followed the steps to Pull a copy of the Linux kernel source code and are in the kernel source working directory.

  2. If you have an existing .config file from an old kernel, copy it into the working directory as .config for comparison. Otherwise, use the Clear Linux OS kernel configuration file as template

    cp ~/clearlinux/packages/linux/config .config
    
  3. Make any desired changes to the .config using a kernel configuration tool. Below are some popular options:

    • $EDITOR .config - the .config file can be directly edited for simple changes with names that are already known.

    • make config - a text-based tool that asks questions one-by-one to decide configuration options.

    • make menuconfig - a terminal user interface that provides menus to decide configuration options.

    • make xconfig - a graphical user interface that provides tree views to decide configuration options.

    More configuration tools can be found by looking at the make help: make help | grep config

  4. Commit and save the changes to the .config file.

  5. Copy the .config file from the kernel source directory into the kernel package directory as config for inclusion in the build.

    cp .config ../config
    

Modify kernel source code

Changes to kernel code are applied with patch files. Patch files are formatted git commits that can be applied to the main source code.

You will need to obtain a copy of the source code, make modifications, generate patch file(s), and add them to the RPM SPEC file for inclusion during the kernel build.

If you have a large number of patches or a more complex workflow, consider using a patch management tool in addition to Git such as Quilt.

  1. Make sure you have followed the steps to Pull a copy of the Linux kernel source code and are in the kernel source working directory.

  2. Initialize the kernel source directory as a new git repo and create a commit with all the existing source files to begin tracking changes.

    git init
    git add -A
    git commit -m "Initial commit of Linux kernel source"
    
  3. Apply patches provided by the Clear Linux OS kernel package to the kernel source in the working directory.

    git am ../*.patch
    
  4. Make any of your desired code changes to the Linux source code files.

  5. Track and commit your changes to the local git repo.

    git add <FILENAME>
    git commit -m "My patch for driver A" <FILENAME>
    
  6. Generate a patch file based on your git commits. <n> represents the number of local commits to create patch file. See the git-format-patch documentation for detailed information on using git format-patch

    git format-patch -<n>
    
  7. Copy the patch files from the patches directory in the linux source tree to the RPM build directory.

    cp *.patch ~/clearlinux/packages/linux/
    
  8. Navigate back to the RPM build directory.

    cd ~/clearlinux/packages/linux/
    
  9. Open the Linux kernel package RPM SPEC file in an editor.

    $EDITOR linux.spec
    
  10. Locate the section of the SPEC file that contains existing patch variable definitions and append your patch file name. Ensure the patch number does not collide with an existing patch. In this example, the patch file is called 2001-my-patch-for-driver-A.patch

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    #
    # Small Clear Linux Tweaks
    #
    Patch0501: 0501-zero-extra-registers.patch
    Patch0502: 0502-locking-rwsem-spin-faster.patch
    
    #Serie1.name WireGuard
    #Serie1.git  https://git.zx2c4.com/WireGuard
    #Serie1.tag  00bf4f8c8c0ec006633a48fd9ee746b30bb9df17
    Patch1001: 1001-WireGuard-fast-modern-secure-kernel-VPN-tunnel.patch
    #Serie1.end
    
    Patch2001: 2001-my-patch-for-driver-A.patch
    
  11. Locate the section of the SPEC file further down that contains patch application and append your patch file number used in the step above. In this example, patch2001 is added.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    #
    # Small tweaks
    #
    %patch0501 -p1
    %patch0502 -p1
    
    #Serie1.patch.start
    %patch1001 -p1
    #Serie1.patch.end
    
    %patch2001 -p1
    
  12. Commit and save the changes to the RPM SPEC file.

Modify kernel boot parameters

The kernel boot options are passed from the bootloader to the kernel with command-line parameters.

While temporary changes can be made to kernel parameters on a running system or on a during boot, you can also modify the default parameters that are persistent and distributed with a customized kernel.

  1. Open the kernel cmdline file in an editor.

    $EDITOR cmdline
    
  2. Make any desired change to the kernel parameters. For example, you can remove the quiet parameter to see more verbose output of kernel log messages during the boot process.

  3. Commit and save the changes to the cmdline file.

See the kernel parameters documentation for a list of available parameters.

Build and install the kernel

After changes have been made to the kernel source and RPM SPEC file, the kernel is ready to be compiled and packaged into an RPM.

The Clear Linux OS development tooling makes use of mock environments to isolate building of packages in a sanitized workspace.

  1. Start the compilation process by issuing the make build command. This process is typically resource intensive and will take a while.

    make build
    

    Note

    The mock plugin ccache can be enabled to help speed up any future rebuilds of the kernel package by caching compiler outputs and reusing them.

  2. The result will be multiple .rpm files in the rpms directory as output.

    ls rpms/
    

    The kernel RPM will be named linux<NAME>-<VERSION>-<RELEASE>.x86_64.rpm

  3. The kernel RPM file can be input to the mixer to create a custom bundle and mix of Clear Linux OS.

Alternatively, the kernel RPM bundle can be installed manually on a local machine for testing. This approach works well for individual development or testing. For a more scalable and customizable approach, consider using the mixer to provide a custom kernel with updates.

  1. Install the kernel onto the local system by extracting the RPM with the rpm2cpio command.

    rpm2cpio linux<NAME>-<VERSION>-<RELEASE>.x86_64.rpm | (cd /; sudo cpio -i -d -u -v);
    
  2. Optionally, increase the bootloader timeout to make interrupting the boot process and choosing a different kernel easier.This can be helpful to if you encounter a kernel that does not boot gracefully.

    sudo clr-boot-manager set-timeout 20
    
  3. Update the Clear Linux OS boot manager to use the new kernel using clr-boot-manager and reboot.

    sudo clr-boot-manager update
    sudo clr-boot-manager list-kernels
    sudo clr-boot-manager set-kernel org.clearlinux.<TARGET>.<VERSION>-<RELEASE>
    
    sudo reboot
    
  4. After a reboot, verify the customized kernel is running.

    uname -a