1. 内核编译与启动:从源码下载到内核启动的全流程
说实话,很多搞内核开发的朋友,第一步就卡在编译上。不是缺依赖,就是配置选项选错,折腾半天连个内核都起不来。我当年刚入行时也踩过不少坑,有一次编译出来的内核直接 panic,连错误日志都没来得及看——嗯,从那以后我养成了几个好习惯,今天一并分享给你。
1.1 源码下载:选对版本,少走弯路
内核源码的获取方式有好几种,我个人最推荐用 git 拉取主线仓库。为什么?因为你可以随时切换分支、查看历史提交,调试时特别方便。
推荐源码获取方式
- Git 主线仓库:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git - 稳定版 tarball:从
kernel.org下载linux-x.y.z.tar.xz - 发行版源码包:Ubuntu 用
apt-get source linux-image-$(uname -r)
我的习惯:调试用主线最新 RC 版,生产环境用 LTS 版本。曾经有一次我图省事直接用了发行版自带的源码包,结果发现打了大量补丁,跟主线对不上,调试时各种诡异行为——从那以后我再也不偷懒了。
1.2 内核配置:选项多到眼花,怎么选?
内核配置选项有上万个,你不可能一个个看完。我一般分三步走:
- 基于当前系统配置:
make oldconfig或make localmodconfig - 按需微调:
make menuconfig图形化界面 - 保存 .config:备份一份,方便回退
localmodconfig 这个命令特别实用。它会扫描你当前系统加载的模块,只保留这些模块的配置项。我第一次用的时候,配置项从一万多个直接降到两千多,编译时间从半小时缩短到五分钟。你想想看,省下来的时间干点啥不好?
注意:localmodconfig 生成的配置只包含当前硬件支持的驱动。如果你换了机器或者加了新设备,记得重新跑一遍。我曾经在笔记本上编译完内核,换到台式机上启动时发现网卡驱动没编进去——尴尬不?
1.3 编译:耐心等待,但别干等
配置搞定后,编译就简单了。核心命令就几个:
# 清理旧编译产物
make clean
# 编译内核和模块
make -j$(nproc)
# 编译模块
make modules
# 安装模块
sudo make modules_install
# 安装内核
sudo make install
-j$(nproc) 这个参数很关键。它会让 make 用你 CPU 的所有核心并行编译。我见过有人用单核编译 5.10 内核,等了快一个小时。用并行编译,16 核机器上也就 3-5 分钟。
| 编译阶段 | 耗时(16核) | 常见问题 |
|---|---|---|
| 配置生成 | 几秒 | 依赖缺失(如 flex、bison) |
| 内核编译 | 3-5 分钟 | 内存不足(建议 4GB+) |
| 模块编译 | 1-2 分钟 | 头文件路径错误 |
| 模块安装 | 几秒 | 权限不足(需 sudo) |
| 内核安装 | 几秒 | /boot 空间不足 |
1.4 GRUB 配置:让新内核跑起来
内核安装完成后,GRUB 会自动检测并添加新条目。但有时候它不听话,你得手动更新:
# 更新 GRUB 配置
sudo update-grub
# 或者手动编辑 /etc/default/grub
# 修改 GRUB_DEFAULT 指定默认启动项
# 修改 GRUB_TIMEOUT 调整等待时间
# 应用修改
sudo grub-mkconfig -o /boot/grub/grub.cfg
避坑指南:我曾经在调试时同时装了 5 个内核版本,结果 GRUB 菜单长得跟购物清单似的。后来我养成了两个习惯:一是编译前用 make kernelrelease 确认版本号,二是装完新内核后立即删掉旧内核(sudo apt-get autoremove)。
1.5 启动验证:确认内核跑起来了
重启后,用以下命令确认新内核是否生效:
# 查看当前内核版本
uname -r
# 查看内核启动参数
cat /proc/cmdline
# 查看内核日志(dmesg)
dmesg | grep "Linux version"
# 查看模块加载情况
lsmod | head -20
如果系统起不来,别慌。重启时按住 Shift(或 Esc)进入 GRUB 菜单,选择旧内核启动。然后检查 /var/log/kern.log 或 dmesg 输出,看看是哪个驱动炸了。
1.6 全流程知识图谱
下面这张图把整个流程串起来了,建议你保存下来对照着操作:
1.7 常见问题与避坑
最后,我把这些年遇到过的典型问题列出来,你碰到了可以直接对照:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
编译报错 flex: command not found |
缺少 flex、bison 等工具 | sudo apt-get install flex bison |
| 启动时 kernel panic | 驱动配置错误或模块缺失 | 用旧内核启动,检查 dmesg |
| GRUB 菜单没有新内核 | 未执行 update-grub | sudo update-grub |
| 模块加载失败 | 内核版本与模块版本不匹配 | 重新编译模块或检查 depmod |
| /boot 空间不足 | 旧内核太多 | sudo apt-get autoremove 清理 |
嗯,这一章的内容就到这里。内核编译这件事,说白了就是熟能生巧。多编译几次,你自然就知道哪些选项该开、哪些该关、哪些坑要绕开。下次遇到问题,记得先看 dmesg,它比任何文档都诚实。