Linux Kernel 编译

Table of Contents

最后更新:2015-06-16

1 相关工具

1.1 内核模块相关命令

  • modinfo:查看已加载的内核模块信息
  • rmmod:卸载已加载的内核模块
  • insmod:加载新的内核模块.ko文件
  • lsmod:列出所有已加载的内核模块

2 内核编译

Linux 内核分开发版和稳定版,早期里,版本号为偶数的是稳定版;版本号为奇数的是开发版。如 2.5 是开发版,2.6 是可以用在生产线上的稳定版。

下载内核代码:

  • 方法1,从 www.kernel.org 上下载
  • 方法2,从软件源中下载

3 配置内核

内核的配置信息保存在内核源码根目录的 .config 文件中。

配置内核的几种方式:

  • make config:需要每项都交互式输入 y、n 和 m(编译成内核模块)
  • make menuconfig:终端界面的配置
  • make xconfig:Qt 界面配置
  • make gconfig:GTK 界面配置
  • make defconfig:默认配置,据说是 Linus 的默认配置,但配置项比较随意

一般我常用 make menuconfig,在 menuconfig 配置界面中,可以按“/”键,对配置项进行字符串查找。

编译内核

$ make oldconfig # 用当前的 .config 覆盖默认的内核配置,在编译以前,最好先运行 make oldconfig 验证一下配置文件 .config 的正确性,如无错误,再编译
$ make menuconfig # 配置内核选项
$ make -j3 # 编译内核源码,-j 参数指定多线程编译

4 安装内核

方法1:

$ sudo make modules_install # 安装内核模块
$ sudo make install # 安装内核相关文件
$ grub2-mkconfig # 更新 Grub 内容,不写入文件,只是检查下配置是否有问题
$ grub2-mkconfig -O /boot/grub/grub.cfg # 如果检查没问题,就覆盖掉旧的配置

方法2,将内核打包成 RPM,方便管理:

$ make rpm

生成的 .rpm 包在 ~/rpmbuild/RPMS/ 中,直接用 rpm/dnf 命令安装即可。

更多高级配置,可见 Documentation/kbuild 下的文档,或者运行 make help 命令获得编译帮助

5 一些配置项

5.1 Kernel .config support

在 General setup 中找到,配置该项的内核,会将配置文件保存到 /proc/config.gz 中,方便了解当前运行中的内核配置情况,以及复用配置文件。

6 升级内核源码

可对内核源码进行增加补丁,但是注意不能跨版本,比如当前源码树是 4.9.10,要升级到 4.9.13,就要先从 4.9.10 升级到 4.9.11,再从 4.9.11 升级到 4.9.12,最后才能升级到 4.9.13。

升级补丁从 kernel.org 下载,比如 4.x 内核的补丁在 https://www.kernel.org/pub/linux/kernel/v4.x/incr/ 找到。

现在,下载增加补丁:

patch-4.9.10-11.xz
patch-4.9.11-12.xz
patch-4.9.12-13.xz

然后用 unxz 命令解压补丁,接下来在 4.9.10 源码目录开始打补丁:

$ cd linux-4.9.10
$ patch -p1 < /tmp/patch-4.9.10-11
$ patch -p1 < /tmp/patch-4.9.10-12
$ patch -p1 < /tmp/patch-4.9.10-13

源码升级完毕后,执行以下命令确认是否升级到 4.9.13:

$ head -4 Makefile
VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 13
EXTRAVERSION =

从 SUBLEVEL 可见升级成功。在更新内核源码后编译之前,记得执行 make oldconfig 更新并验证配置文件。

7 编译某个模块

一般忘记编译某个独立的内核模块,或是该模块有 bug,才需要重新编译。

比如,上次遇到 rtl8192ce 驱动频繁断线的 bug,关注几日内核进展后,发现在 4.9.10 中得到修复(https://bugzilla.redhat.com/show_bug.cgi?id=1391987#c26 ),但是 Fedora 仓库里最新的内核还没有到 4.9.10(已经到 4.9.9了,还差一点点),从 Fedora Update System(https://bodhi.fedoraproject.org/updates/FEDORA-2017-0054c7b1f0 )看到 4.9.10 还有 3 个问题没解决,所以应该还需要一段时间才会释放出 4.9.10 的内核更新,由于平时在家需要连 Wifi,极不方便,所以需要手动来解决。

从 kernel.org 上下载 4.9.10 的源码,然后单独编译 rtl8192ce 模块来临时用着,直到 4.9.10 的更新出现为止。

找到 rtl8192ce 模块的路径:

$ find ./ -name 'rtl8192ce*'

位于 drivers/net/wireless/realtek/rtlwifi/rtl8192ce,进入该目录,然后编译模块:

$ cd ./drivers/net/wireless/realtek/rtlwifi/rtl8192ce
$ sudo make -C /lib/modules/4.9.9-200.fc25.x86_64/build M=`pwd` modules

参数 M 表示编译内核模块;

-C 表示先切换到指定目录去,再执行 make 操作

成功后安装模块:

$ sudo make -C /lib/modules/4.9.9-200.fc25.x86_64/build M=`pwd` modules_install

安装后.ko文件在 /lib/modules/4.9.9-200.fc25.x86_64/extra 目录中。先从内存中移除旧的模块:

$ sudo rmmod rtl8192ce

然后再挂载新的模块:

$ sudo insmod /lib/modules/4.9.9-200.fc25.x86_64/extra/rtl8192ce.ko