[OS] 编译 Linux 内核

编译 Linux 内核:详细教程与 Kthreads 入门结合

我们将学习如何编译 Linux 内核,同时结合 Kthreads 的知识来理解各个步骤的目的。对于虚拟环境下的开发环境配置,本文将为你提供逐步指导。

1. 下载内核源代码

首先,我们需要从官方或国内镜像站下载 Linux 内核源代码:

为什么要下载源代码呢?这是因为我们需要对内核进行自定义,添加我们的内核线程(Kthread)相关功能。内核线程是 Linux 中一个强大的工具,它可以让你创建、管理并行任务,非常适合需要实时处理的系统功能。

  1. 在主机上下载内核源代码:首先从网站下载你需要的内核版本,例如最新的稳定版本 6.11.2。

  2. 将下载的文件移至 Vagrant 虚拟机

    • 可以通过共享文件夹的方式,将下载的 .tar.xz 文件从主机系统移至虚拟机中。
    • 或者使用 scp 命令从主机传输到虚拟机。
  3. 在虚拟机中解压和编译

    • 将文件复制到你的工作目录,比如 /home/seed/work

      bash 复制代码
      mv /home/vagrant/csc3150/linux-5.15.10 /home/seed/work
    • 然后解压、配置、编译和安装内核。

共享文件夹的挂载和使用需要在 Vagrant 配置文件(Vagrantfile)中进行配置,比如:

bash 复制代码
config.vm.synced_folder "path/to/your/local/folder", "/vagrant"

2. 安装依赖和开发工具

在编译内核之前,需要安装必要的依赖包和开发工具。这些工具将帮助我们顺利完成编译过程。

bash 复制代码
sudo apt-get install libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-  dev libpci-dev libiberty-dev autoconf llvm dwarves

这些工具中的每一个都有特定用途:

  • libncurses-dev:用于支持终端用户界面(TUI),例如菜单配置。

  • flex 和 bison:是词法分析器和语法分析器生成工具,用于构建和解析内核配置。

  • openssl 和 libssl-dev:用于加密功能,确保内核中数据的安全性。

这些工具的安装是内核编译的基础,因为内核编译涉及到大量复杂的配置和依赖,少了其中任何一个都会导致编译失败。

3. 解压内核源代码

将下载的内核源代码解压到工作目录:

bash 复制代码
cp KERNEL_FILE.tar.xz /home/seed/work
cd /home/seed/work
$sudo tar xvf KERNEL_FILE.tar.xz

在这里,我们将源代码解压到 /home/seed/work,这是为了确保我们的工作环境干净且可控,避免对系统的其他部分产生影响。

4. 复制配置文件

/boot 目录中复制系统当前的配置文件,以作为内核编译的基础配置:Copy config from /boot to /home/seed/work/KERNEL_FILE

这个步骤的目的是使用现有内核的配置,确保我们在编译过程中不会遗漏关键的选项。

§Login root account and go to kernel source directory

bash 复制代码
$sudo su
$cd /home/seed/work /KERNEL_FILE

5. 开始配置和编译内核

清理之前的设置并重新配置
bash 复制代码
make mrproper
make clean
make menuconfig
  • make mrproper:清除之前编译留下的临时文件。

  • make clean:删除编译生成的对象文件,确保干净的编译环境。

  • make menuconfig:进入内核配置界面,可以在这里添加我们的模块,例如 Kthreads

  • save the config and exit

对于 Kthreads 入门,我们需要确保内核支持内核线程的调度和管理。因此,在 menuconfig 中检查线程相关的配置非常重要。

6. 编译内核和模块

使用 make bzImagemake modules 来分别编译内核镜像和模块。-j$(nproc) 表示使用所有可用的 CPU 内核来加快编译速度。

bash 复制代码
make bzImage -j$(nproc)
make modules -j$(nproc)
make --j$(nproc)

这个步骤可能需要较长时间,因为内核编译涉及大量代码。如果你对 Kthreads 有了解,这部分的内容实际上就是内核如何将各个线程(包括我们创建的内核线程)组织到内核模块中。

7. 安装模块和内核

编译完成后,安装模块和内核:

bash 复制代码
make modules_install
bash 复制代码
make install

这些命令会把编译好的内核和模块安装到系统中,以便在重启时加载新的内核版本。

8. 重启并选择新内核

重启系统并选择新编译的内核版本:

bash 复制代码
reboot

在重启过程中,你需要在引导菜单中选择新编译的内核版本,以确保加载我们新加入的 Kthreads 模块。

9. 验证内核版本

验证当前运行的内核版本:

bash 复制代码
uname -r

这样可以确认我们是否成功运行了刚刚编译的内核。

编译过程中常见问题

  • 文件或目录不存在

    • 确保在 Linux 环境中解压源代码,而不是在 Windows 或 macOS 中解压。不同的操作系统可能对文件名大小写敏感性处理不同,可能导致文件找不到。
  • 磁盘空间不足

    • 内核源代码较大,编译过程需要大量的磁盘空间,建议将源代码移动到有足够空间的目录下再继续编译。
  • 共享文件夹的问题

    • 如果你使用虚拟机进行开发,确保共享文件夹正确挂载,避免由于共享文件夹的问题导致编译失败。

EXPORT_SYMBOL 的使用

在实现 Kthreads 的过程中,我们可能需要使用一些内核函数,这些函数需要通过 EXPORT_SYMBOL() 导出,才能被其他模块使用。例如,do_wait() 函数是用于等待子进程结束的常用函数,需要先在源码中进行导出。

代码示例

编译内核的完整命令流程
  1. 下载并解压内核源代码

  2. 复制配置文件

  3. 清理设置并开始配置

  4. 编译内核镜像和模块

  5. 安装内核模块和内核

  6. 重启系统并选择新内核

  7. 验证内核版本

构建内核对象

在进行内核模块的加载和测试时,我们还需要构建内核对象。以下是一个构建内核对象的 Makefile 示例:

  • KM 是内核对象的名称。

  • 使用 make 命令来构建内核对象。

  • 使用 make clean 命令可以清除所有构建文件,只保留原始的 .c 文件和 Makefile。

当你在虚拟环境中进行开发时,使用这些命令来构建和清理内核模块可以帮助你保持代码的整洁,并确保每次构建都是从干净的环境开始。

插入和移除内核模块

在构建内核对象之后,我们需要将其插入内核进行测试,并在不需要时将其移除。

插入内核模块

在插入内核对象之前,你需要以 root 用户身份登录:

然后使用以下命令插入内核模块:

列出插入的模块

要列出当前插入的模块,可以使用以下命令:

这样可以确认我们的模块是否已经成功插入内核。

移除内核模块

在不需要使用模块时,记得将其移除:

这可以释放系统资源,确保内核的稳定性。

相关推荐
A小辣椒11 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒14 小时前
TShark:基础知识
linux
AlfredZhao17 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式