内核开发

本指南介绍了如何使用 Clear Linux* OS 开发工具获取和编译 Linux* 内核源代码。

概述

Clear Linux OS 中的 内核 追求高效和实用。在某些情况下,您可能需要根据自身的具体需求修改内核,而开发人员也可能需要修改内核来测试新的内核代码。

所有 Clear Linux OS 内核也提供了 Source RPMs (SRPMS),它可用于开发目的。

Clear Linux OS 内核中包含了请求变更

如果您需要的内核修改已经开源,并且可能对其他人也有用,请考虑提交一个请求,将其包含在 Clear Linux OS 内核中。如果您的变更请求被接受,则不需要维护自己修改过的内核。

向 GitHub* 上的 Clear Linux OS Distribution Project 提出增强请求。

设置内核开发环境

在某些情况下,您可能需要根据自身的具体需求或者为了测试新的内核代码而修改内核。

您可以构建和安装自定义内核;但是,您必须:

  • 禁用安全引导
  • 在以后维护任何内核更新

要创建自定义内核,请先从 Clear Linux OS 开发环境开始。然后修改、构建和安装内核。

安装 Clear Linux OS 开发工具框架

在 Clear Linux OS 中构建源代码所需的工作空间和工具设置操作大多数可通过设置脚本自动执行。该设置脚本使用来自 os-clr-on-clr 捆绑包的工具。

该设置脚本会在 clearlinux 文件夹(其中包含 Makefilepackagesprojects 子文件夹)中创建一个工作空间。projects 文件夹包含在 Clear Linux OS 中制作软件包的主要工具,即 autospeccommon

按照以下步骤设置构建代码所需的工作空间和工具:

  1. 安装 os-clr-on-clr 捆绑包:

    sudo swupd bundle-add os-clr-on-clr
    
  2. 下载 user-setup.sh 脚本:

    curl -O https://raw.githubusercontent.com/clearlinux/common/master/user-setup.sh
    
  3. 制作 user-setup.sh 可执行文件:

    chmod +x user-setup.sh
    
  4. 以非特权用户的身份运行脚本:

    ./user-setup.sh
    
  5. 脚本完成后,注销并再次登录以完成设置过程。

  6. 在系统上设置存储库的 Git 用户电子邮件和用户名:

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

    此全局设置由使用 Git 的 Clear Linux OS 工具使用。

克隆内核包

首先从 Clear Linux OS 克隆现有的内核包存储库。

  1. 从 Clear Linux OS 克隆 Linux 内核包。在 clearlinux/ 目录下使用 make clone_<PACKAGENAME> 命令,从 GitHub 上的 clearlinux-pkgs 存储库克隆内核包。

    cd ~/clearlinux
    make clone_linux
    
  2. 导航到克隆的内核包目录。

    cd ~/clearlinux/packages/linux
    

“linux” 包是 kernel-native 捆绑包中随 Clear Linux OS 附带的内核。您也可以使用不同的内核变体,并在其基础上进行修改。有关可以克隆的内核包名称列表,请参阅 GitHub 上的 clearlinux-pkgs 存储库。

注解

一开始先提取 Clear Linux OS 内核包的最新版本。此外可以使用 git checkout tag/<TAG_NAME>,并通过切换到不同的 git 标签来提取旧版本。

更改内核版本

Clear Linux OS 倾向于使用来自 Linux 上游 kernel.org 的最新内核。在 RPM SPEC 文件中可以更改将构建的内核版本。虽然 Clear Linux 中的大多数包通常使用 autospec 打包,但内核不是。这意味着 autospec 提供的控制文件不可用,必须手动进行更改。

  1. 在编辑器中打开 Linux 内核包 RPM SPEC 文件。

    $EDITOR linux.spec
    
  2. 修改文件顶部的 Version、Release 和 Source0 URL 条目,以更改将要编译的 Linux 内核版本。

    当前和可用内核版本的列表可在 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
    

    注解

    • 考虑在 RPM 规范文件中将 Name 从 linux 更改为更易于识别的名称,以便轻松识别修改后的内核。
    • 考虑在 RPM 规范文件中将 ktarget 从 native 更改为更易于识别的名称,以便轻松识别修改后的内核。
  3. 提交并保存对文件的更改。

提取一份 Linux 内核源代码副本

获取源代码的本地副本进行修改。

  1. 运行源代码制作操作,提取在 RPM SPEC 文件中指定的内核源代码。本例中下载了 linux-4.20.8.tar.xz 文件。

    make sources
    
  2. 提取内核源代码存档。这将创建一个可以修改的 Linux 源代码工作副本。

    tar -xvf linux-4.20.8.tar.xz
    
  3. 导航到提取的目录。本例中将源代码提取到了 linux-4.20.8 目录。

    cd linux-4.20.8/
    

自定义 Linux 内核源代码

获得内核源代码后,可以自定义内核配置或源代码,将其包含在内核构建中。这些自定义是可选的。

修改内核配置

内核源代码提供了许多配置选项,可支持不同的硬件和软件功能。

编译时必须在 .config 文件中提供这些配置值。您需要修改 .config 文件,并将其包含在内核包中。

  1. 请确保您已经执行了 提取一份 Linux 内核源代码副本 中的步骤,而且处于内核源代码工作目录下。

  2. 如果您目前有一个来自旧内核的 .config 文件,请将其复制到工作目录中进行比较。否则,请使用 Clear Linux OS 内核配置文件作为模板

    cp ~/clearlinux/packages/linux/config .config
    
  3. 使用内核配置工具对 .config 执行所需的更改。以下是一些常用选项:

    • $EDITOR .config - 可以直接编辑 .config 文件,对已知的名称进行简单更改。
    • make config - 一个基于文本的工具,通过逐步提问的方式决定配置选项。
    • make menuconfig - 一个终端用户界面,通过提供菜单来决定配置选项。
    • make xconfig - 一个图形用户界面,通过提供树视图来决定配置选项。

    使用 make help | grep config 命令查看 make help 可以找到更多配置工具

  4. 提交更改并将其保存到 .config 文件。

  5. .config 文件从内核源代码目录复制到内核包目录,以便将 .config 包含在构建中。

    cp .config ../config
    

修改内核源代码

对内核代码的更改通过补丁文件应用。补丁文件是格式化的 git 提交,可以应用于主源代码。

您需要获得源代码的副本,进行修改,生成补丁文件,然后将它们添加到 RPM SPEC 文件中,以便在内核构建期间包含在内。

如果有大量补丁或工作流程十分复杂,可考虑在 Git 之外使用 Quilt 之类补丁管理工具。

  1. 请确保您已经执行了 提取一份 Linux 内核源代码副本 中的步骤,而且处于内核源代码工作目录下。

  2. 将内核源代码目录初始化为新的 git 存储库,并使用所有现有源文件创建一个提交,以开始跟踪更改。

    git init
    git add -A
    git commit -m "Initial commit of Linux kernel source"
    
  3. 将 Clear Linux OS 内核包提供的补丁应用于工作目录中的内核源代码。

    git am ../*.patch
    
  4. 对 Linux 源代码文件执行所需的代码更改。

  5. 跟踪您的更改,并将其提交到本地 git 存储库。

    git add <FILENAME>
    git commit -m "My patch for driver A" <FILENAME>
    
  6. 基于您的 git 提交生成补丁文件。<n>表示要创建补丁文件的本地提交数量。有关使用 git format-patch 的详细信息,请参阅 git-format-patch 文档

    git format-patch -<n>
    
  7. 将补丁文件从 Linux 源代码树中的补丁目录复制到 RPM 构建目录。

    cp *.patch ~/clearlinux/packages/linux/
    
  8. 导航回 RPM 构建目录。

    cd ~/clearlinux/packages/linux/
    
  9. 在编辑器中打开 Linux 内核包 RPM SPEC 文件。

    $EDITOR linux.spec
    
  10. 找到包含现有补丁变量定义的 SPEC 文件部分,并附加补丁文件名。确保补丁编号不与现有补丁冲突。本例中的补丁文件名为 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. 进一步深入查找含有补丁应用程序的 SPEC 文件部分,并附加在上面步骤中使用的补丁文件编号。本例中添加了 patch2001。

     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. 提交并保存对 RPM SPEC 文件的更改。

修改内核引导参数

内核引导选项通过命令行参数从引导加载程序传递到内核。

虽然可以在正在运行的系统上或在引导过程中对内核参数进行临时更改,但您也可以修改随自定义内核分发并持久存在的默认参数。

  1. 在编辑器中打开内核 cmdline 文件。

    $EDITOR cmdline
    
  2. 对内核参数执行所需的更改。例如,您可以移除 quiet 参数,以便在引导过程中查看更详细的内核日志消息输出。

  3. 提交更改并将其保存到 cmdline 文件。

有关可用参数的列表,请参阅 kernel parameters 文档。

构建并安装内核

更改内核源代码和 RPM SPEC 文件后,内核就可以编译并打包成 RPM。

Clear Linux OS 开发工具使用 mock 环境来在净化的工作区中隔离内核包构建工作。

  1. 发出 make build 命令启动编译过程。此过程通常会占用大量资源,而且需要一段时间。

    make build
    

    注解

    您可以启用 mock 插件 ccache,通过缓存并重用编译器输出来加快日后执行的内核包重新构建速度。

  2. 编译后会在 rpms 目录中输出多个 .rpm 文件。

    ls rpms/
    

    内核 RPM 将命名为 linux<NAME>-<VERSION>-<RELEASE>.x86_64.rpm

  3. 内核 RPM 文件可以输入到 mixer,以创建自定义捆绑包和 Clear Linux OS 混合版。

内核 RPM 捆绑包也可以手动安装在本地计算机上进行测试。此方法对于个人开发或测试非常有效。如需使用可扩展性和可自定义性更好的方法,可考虑使用 mixer 为自定义内核提供更新。

  1. 使用 rpm2cpio 命令提取 RPM,将内核安装到本地系统上。

    rpm2cpio linux<NAME>-<VERSION>-<RELEASE>.x86_64.rpm | (cd /; sudo cpio -i -d -u -v);
    
  2. 使用 clr-boot-manager 命令更新 Clear Linux OS 引导管理器,然后重启。

    sudo clr-boot-manager list-kernels
    sudo clr-boot-manager set-kernel org.clearlinux.<TARGET>.<VERSION>-<RELEASE>
    
    sudo reboot
    
  3. 重启后,确认自定义内核是否正在运行。

    uname -a