编译安装调试Linux内核
本文最后更新于:2023年8月6日 晚上
编译安装内核
下载内核
Linux内核下载The Linux Kernel Archives
安装依赖
1 |
|
更改.config
1 |
|
1 |
|
- 打开
.config
更改CONFIG_SYSTEM_TRUSTED_KEYS
和CONFIG_SYSTEM_REVOCATION_KEYS
1 |
|
- 更改
CONFIG_DEBUG_INFO_BTF
1 |
|
- 注释掉CONFIG_X86_X32
1 |
|
编译内核
1 |
|
安装
首先安装模块
这里加上INSTALL_MOD_STRIP=1
是为了避免内核启动时卡在 loading initial ramdisk
1 |
|
安装内核
1 |
|
更改引导
1 |
|
更改grub
修改文件
1 |
|
1 |
|
更新
1 |
|
重启
1 |
|
在GRUB
页面选择Advanced options for Ubuntu
选择需要启动的内核版本
其他操作
清理内核源目录
1 |
|
卸载安装的内核
获取所有安装的内核版本
1 |
|
选择要卸载的版本,卸载下列安装包
1 |
|
卸载源码版本
1 |
|
更新启动引导
1 |
|
修改内核配置菜单实现对新加入内核源码的控制
将源码拷贝到内核对应的文件夹下
为配置界面添加控制新加入源代码的内容
在加入源码的目录下创建
Kconfig
文件,便添加相应控制内容修改上层
Kconfig
文件,包含新加入源码的Kconfig
文件。修改
Makefile
文件修改上一级目录的Makefile
1 |
|
1 |
|
1 |
|
解决方法
1 |
|
常见问题
1. Module.symvers is missing
1 |
|
执行
1 |
|
2. No rule to make target ‘debian/canonical-certs.pem‘, needed by ‘certs/x509_certificate_list‘
可以修改config:
vim .config
修改CONFIG_SYSTEM_TRUSTED_KEYS
,将其置空: CONFIG_SYSTEM_TRUSTED_KEYS=””也可能需要设置CONFIG_SYSTEM_REVOCATION_KEYS为空。
3. FAILED:load BTF from vmlinux:No such file or directory
vim .config
修改CONFIG_DEBUG_INFO_BTF
,将其置n
4. 安装完内核之后无法显示GRUB
用以选择内核启动
进入命令行之后执行
1 |
|
注释掉
1 |
|
修改
1 |
|
执行
1 |
|
5. 内核启动卡在loading initial ramdisk
编译内核过程中,当安装内核模块时未使用
1 |
|
标注,会导致initrd
文件过大,Ubuntu 20.04所用的Grub 2.04无法支持过大的initrd文件(如500M),导致内核启动时卡在“loading initial ramdisk”(Can’t allocate initrd)
。
可行的办法:
安装模块时加上INSTALL_MOD_STRIP=1
1 |
|
6. sign-file: : No such file or directory
报错信息:
解决方法:
将.config
的 CONFIG_MODULE_SIG_KEY="cert/signing_key.pem"
恢复后解决。
1 |
|
7. zstd: not found
1 |
|
解决方法
在配置内核时更改Kernel compression mode
为LZMA
1 |
|
保存后重新编译安装即可。
单独编译Linux内核的某一个模块
找到对应的模块文件夹,找到需要编译的文件,确认编译的config文件
1 |
|
qemu+gdb调试linux内核
安装qemu
1 |
|
配置调试版内核
对内核进行调试需要解析符号信息,所以得编译一个调试版内核。
1 |
|
这里需要开启内核参数CONFIG_DEBUG_INFO
和CONFIG_GDB_SCRIPTS
。GDB提供了Python接口来扩展功能,内核基于Python接口实现了一系列辅助脚本,简化内核调试,开启CONFIG_GDB_SCRIPTS
参数就可以使用了。
1 |
|
构建initramfs根文件系统
Linux系统启动阶段,boot loader加载完内核文件vmlinuz后,内核紧接着需要挂载磁盘根文件系统,但如果此时内核没有相应驱动,无法识别磁盘,就需要先加载驱动,而驱动又位于/lib/modules
,得挂载根文件系统才能读取,这就陷入了一个两难境地,系统无法顺利启动。于是有了initramfs根文件系统,其中包含必要的设备驱动和工具,boot loader加载initramfs到内存中,内核会将其挂载到根目录/
,然后运行/init
脚本,挂载真正的磁盘根文件系统。
这里借助BusyBox构建极简initramfs,提供基本的用户态可执行程序。
编译BusyBox,配置CONFIG_STATIC
参数,编译静态版BusyBox,编译好的可执行文件busybox
不依赖动态链接库,可以独立运行,方便构建initramfs。
1 |
|
1 |
|
1 |
|
会安装在_install
目录:
1 |
|
创建initramfs,其中包含BusyBox可执行程序、必要的设备文件、启动脚本init
。这里没有内核模块,如果需要调试内核模块,可将需要的内核模块包含进来。init
脚本只挂载了虚拟文件系统procfs
和sysfs
,没有挂载磁盘根文件系统,所有调试操作都在内存中进行,不会落磁盘。
1 |
|
init文件的内容
1 |
|
打包initramfs
1 |
|
调试
1 |
|
-s
是-gdb tcp::1234
的缩写,监听1234端口,在GDB中通过target remote localhost:1234
连接;-kernel
指定编译好的调试内核vmlinux
路径;initrd
指定制作好的initramfs
;-nographic
取消图形输出窗口,试qemu成简单的命令行程序。-append "console=ttyS0"
将输出重定向到console,将会显示在标准输出stdio。
启动后的根目录
1 |
|
参考
Linux下使用内核源码单独编译某一模块 - tycoon3 - 博客园 (cnblogs.com)
Linux 内核 下载 编译 安装 2021 ubuntu_yaoxinJJJ的博客-CSDN博客
内核Module.symvers文件揭秘 - Linux内核编程 | 宅学部落 (zhaixue.cc)
如何编译安装Linux内核 - LightningStar - 博客园 (cnblogs.com)
ubuntu上更新和卸载Linux内核 - 广漠飘羽 - 博客园 (cnblogs.com)
关于Ubuntu内核(更新和卸载内核、取消自动更新) · Issue #1 · chiwent/blog (github.com)
自行编译内核,启动内核卡在“loading initial ramdisk”_启动卡在initrd_奇妙之二进制的博客-CSDN博客
linux——编译内核(ubuntu18.04+linux-5.6.4)
中文翻译 — The Linux Kernel documentation Linux内核中文文档。
[arch/x86/boot/compressed/vmlinux.bin.lzma] Error 1_sustwct的博客-CSDN博客