Linux 内核的编译是一个相当复杂且困难的事情, 实际上笔者在这件事上耗费了诸多精力, 不建议直接使用真机, 使用虚拟机在绝大多数情况下都可以方便的处理问题
笔者的开发环境是 Windows11 + WMware Workstation Pro17 + Vscode. 同时 WSL2 在大部分情况下也可以很好的解决问题, 下面介绍两种方式, 笔者更倾向于第一种 WSL2 的便捷方式
license key:
MC60H-DWHD5-H80U9-6V85M-8280D
Linux发行版的选择是Ubuntu16.04.7LTS, 直接下载镜像Ubuntu Desktop image
创建虚拟机的过程比较简单这里就不赘述了, 磁盘空间给大一些40GB, 编译内核大概就需要 20GB 的中间文件, 交换区需要调整一下给8GB
这台虚拟机只是用于辅助编译的, 并不需要特别复杂的配置, 我的个人习惯是使用Vscode+SSH连接到这台虚拟机,在Windows中工作. 这部分的配置相对来说比较繁琐, 做不做都可以, 笔者这里贴出个人的一些笔记以供参考
接下来就可以正式进入编译阶段了!
The Linux Kernel Archives 提供了所有Linux内核的历史版本,你可以使用git下载一个巨大的仓库,但笔者建议使用HTTP协议选择一个Linux版本使用即可
以6.3版本Linux内核源代码为例, 可以在 Linux Kernel 找到v6.x版本, 搜索6.3.gz
即可
本文以6.3为例, 您可以使用wget下载
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.3.tar.gz
tar xf linux-6.3.tar.gz
cd linux-6.3
配合编译需要的软件程序很多, 而且特定版本的内核也可能需要特定版本的软件, 新的编译器版本也可能会带来一系列问题
另外安装软件的时候也很可能会出现依赖冲突等等问题, 内核编译的时候也会因为各种配置带来各种问题的报错, 解决起来相当之麻烦...
如果实在解决不了, 建议换 Ubuntu 的版本, 换源, 换 Linux 版本
下面的过程在 wsl2(ubuntu22.04) 和 linux6.3 上是没有问题的, 大概
sudo apt update
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison vim
make menuconfig
这里会打开一个图形化的界面方便控制选择配置, 需要做一些修改以便后面的调试
需要注意的是, 配置信息的位置可能会变化, 所以可能你的 Linux 的版本对应的位置没有下面提到的配置
为了解决这个问题 menuconfig 中有一个比较方便的搜索功能, 输入 /
进入一个搜索页面, 里面搜 GDB 可以得到相关的信息, 类似如下的一些结果, 根据结果中 Location 的信息找到对应的配置位置, 再进行修改
添加调试信息
Kernel hacking --->
[*] Kernel debugging
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info
[*] Provide GDB scripts for kernel debugging
这里的 debug info 在 Linux 6.3 中默认应该是没有开启的, 选第二个
然后再退出来就可以看到这个 Provide GDB scripts for kernel debugging
选项了
禁用随机地址
Processor type and features
-> Build a relocatable kernel (RELOCATABLE [=y])
-> Randomize the address of the kernel image (KASLR)(RANDOMIZE_BASE [=y])
sudo make -j`nproc`
编译时间不确定, 短则几分钟, 长则十几几十分钟, 取决于你的配置和开的进程数
可以得到 ./vmlinux
和 ./arch/x86/boot/bzImage
kamilu@ubuntu:~/linux file arch/x86/boot/bzImage
arch/x86/boot/bzImage: Linux kernel x86 boot executable bzImage, version 6.3.0 (root@LZX) #2 SMP PREEMPT_DYNAMIC Thu May 18 15:41:30 CST 2023, RO-rootFS, swap_dev 0XB, Normal VGA
kamilu@ubuntu:~/linux file vmlinux
vmlinux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=6c316013c1f8a649bad42cf882afd88a31e93c64, with debug_info, not stripped
vmlinux和bzImage都是Linux内核编译生成的可执行文件,它们的主要区别在于它们的文件格式和用途.
vmlinux是Linux内核编译生成的未压缩的内核镜像文件,它包含了整个内核的代码和数据,可以用来调试内核.它通常比较大,因为它没有被压缩.
bzImage是Linux内核编译生成的压缩内核镜像文件,它是用来引导启动Linux操作系统的.它是通过将vmlinux压缩成一个单独的文件,并添加一些引导代码和头部信息来生成的.
当系统引导时,bzImage首先会被加载到内存中,然后被解压缩成vmlinux形式的内核映像.因为vmlinux文件比较大,而且内核启动过程中需要加载和解压缩文件,所以bzImage文件通常比vmlinux文件小很多.
简而言之, vmlinux主要用于内核开发和调试,而bzImage用于实际的Linux操作系统启动.
如果编译出错了那么可以执行如下命令清除重试
sudo make mrproper
sudo make clean
.config 中的 CONFIG_SYSTEM_TRUSTED_KEY
改为 ""
不要在 .bashrc 中改 CPATH
BTF: .tmp_vmlinux.btf: pahole version v1.15 is too old, need at least v1.16
Failed to generate BTF for vmlinux
Try to disable CONFIG_DEBUG_INFO_BTF
make: *** [Makefile:1199: vmlinux] Error 1
在.config把CONFIG_DEBUG_INFO_BTF注释掉