Linux 内核从获取源码到编译安装的完整路线图:基于内核官方 README 的实战指南
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
本文以 Linux 内核仓库中的 Documentation/admin-guide/README.rst(即内核树根目录 README 的管理指南版本)为主体,系统讲解内核发行说明、源码获取与补丁升级、分离构建目录、Kconfig 配置全家桶、编译安装与启动器配置,以及出问题后的排查路径;读完后你将能够独立完成一次“解压源码 → 打补丁 → make 配置 → 编译安装 → 引导启动”的完整流程,并能理解每个make目标背后的构建系统实现(如 Makefile 中的 config 规则、清理目标与 defconfig 发现逻辑)。
一、Linux 内核是什么:发行说明中的定位
README 开宗明义地说明了内核的定位:Linux 是由 Linus Torvalds 从零开始、借助全球松散的 hacker 团队编写的 Unix 克隆,目标是向 POSIX 和 Single UNIX Specification 靠拢。它具备现代 Unix 的全部核心能力:真正的多任务、虚拟内存、共享库、按需加载、共享的写时复制(copy-on-write)可执行文件、完善的内存管理,以及包含 IPv4 和 IPv6 的多栈网络。内核以 GNU General Public License v2 发布,详见 COPYING。
关于硬件支持,README 指出内核最初面向 32 位 x86 PC(386 及以上)开发,如今已移植到大量架构上。从本仓库的 arch/ 目录可以直接验证当前仍在维护的架构端口,包括 alpha、arc、arm、arm64、csky、hexagon、loongarch、m68k、microblaze、mips、nios2、openrisc、parisc、powerpc、riscv、s390、sh、sparc、um、x86、xtensa 等。README 同时给出了移植的一般性前提:
- 目标是大多数通用的 32/64 位架构,要求有分页内存管理单元(PMMU)和 GCC 的对应移植;
- 内核也被移植到无 PMMU 的架构上,但功能受限;
- 内核还可以“移植到自身”——以用户态应用形式运行,即 UserMode Linux(UML),对应 arch/um/ 目录。
二、获取内核源码:完整源码包与补丁升级
2.1 解压完整源码
README 建议将内核 tarball 放到有权限的目录(如主目录)再解压:
xz -cd linux-6.x.tar.xz | tar xvf -这里有一个关键警告:不要使用 /usr/src/linux 目录存放源码。该区域存放的是系统库头文件所依赖的(通常是不完整的)内核头文件集合,它们应与系统库版本匹配,而不应该被“当下最新版内核”所污染。
2.2 用补丁升级 6.x 系列
也可以不重新下载,而是用 xz 格式的官方增量补丁升级版本:进入源码顶层目录后依次执行
xz -cd ../patch-6.x.xz | patch -p1其中所有高于当前版本号的补丁必须按顺序(in order)依次应用。应用后要清理备份文件(some-file-name~、some-file-name.orig),并确认没有失败补丁(some-file-name#、some-file-name.rej)。
2.3 stable(6.x.y)补丁的特殊规则
README 特别强调:6.x.y 的 -stable 补丁不是相对于上一个 stable 版本的增量补丁,而是直接基于 6.x 基础版本制作。因此:
- 若基础内核是 6.0,要应用 6.0.3 补丁,不能先打 6.0.1、6.0.2;
- 若当前运行 6.0.2 想跳到 6.0.3,必须先反打6.0.2 补丁(
patch -R),再打 6.0.3 补丁。
更完整的说明见 Documentation/process/applying-patches.rst。
2.4 自动化升级:scripts/patch-kernel
README 提到的patch-kernel脚本真实存在于 scripts/patch-kernel,用法为:
scripts/patch-kernel linux从脚本头部注释看,其完整参数形式是patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]:源目录默认为/usr/src/linux,补丁目录默认为当前目录;它会自动判断当前内核版本并应用补丁目录中找到的补丁,还可以指定 stopversion 停留在某个版本。README 补充的语义是:第一个参数是内核源码位置,补丁从当前目录应用,也可以用第二个参数指定其他补丁目录。
2.5 清理陈旧产物:make mrproper
源码就位后,README 要求确保没有陈旧的.o文件和依赖文件残留:
cd linux make mrproper从源码结构看,Makefile 中把清理分为三个层次,正好对应补丁流程中产生的临时文件:
make clean:删除大部分生成文件,但保留构建外部模块所需内容;make mrproper:在 clean 基础上再删除配置与全部生成文件,其MRPROPER_FILES列表明确包含.config、.config.old、include/config、include/generated、Module.symvers等;make distclean:在 mrproper 基础上再用find删除编辑器备份(*.orig、*.rej、*~、*.bak、#*#、*%)等文件——这正是 README 提示你手动清理备份文件的那一类产物。
三、软件需求:不要假设“出问题再升级”即可
README 告诫:编译和运行内核需要较新版本的各类软件包,最低版本要求应查阅 Documentation/process/changes.rst。特别要警惕包版本过旧导致的间接错误——这类错误极难追踪,不要等到构建或运行出现明显问题才去升级包,那时往往难以定位根因。
编译器的最低要求是 gcc 8.1。结合当前仓库可以进一步印证构建系统对工具链的硬约束:Makefile 中直接检查 GNU Make 版本,低于 4.0 会立即报错GNU Make >= 4.0 is required。这说明“工具链过旧”在内核构建中不是警告而是直接失败,与 README 的提醒一致。
四、分离构建目录:make O=output/dir
默认情况下,所有编译产物与内核源码混放在同一目录。使用make O=output/dir可以把产物(包括.config)放到别处。README 给出的典型场景:
kernel source code: /usr/src/linux-6.x build directory: /home/name/build/kernel完整的配置与构建序列:
cd /usr/src/linux-6.x make O=/home/name/build/kernel menuconfig make O=/home/name/build/kernel sudo make O=/home/name/build/kernel modules_install install一条硬性规则:一旦使用O=output/dir,所有make 调用都必须带上该选项,否则构建系统会找不到之前的产物与配置。从源码结构看,Kconfig 的配置入口也在顶层 Makefile 中统一实现(Makefile 的config与%config规则),这也是make O=... menuconfig与make menuconfig必须配套使用的原因。
五、配置内核:make 配置命令全表
README 强调:即使是小版本升级也不要跳过配置步骤。每个发布都会新增配置项,配置不符合预期时会冒出各种怪问题。如果希望以最小代价沿用现有配置,用make oldconfig,它只会针对新增配置项提问。
以下是 README 列出的全部替代配置命令,完整保留:
| 命令 | 作用 |
|---|---|
make config | 纯文本交互界面 |
make menuconfig | 基于文本的颜色菜单、单选列表与对话框 |
make nconfig | 增强版文本颜色菜单 |
make xconfig | 基于 Qt 的配置工具 |
make gconfig | 基于 GTK 的配置工具 |
make oldconfig | 以现有./.config为默认值,只对新增符号提问 |
make olddefconfig | 同 oldconfig,但新符号直接取默认值、不提问 |
make defconfig | 使用arch/$ARCH/configs/defconfig或arch/$ARCH/configs/${PLATFORM}_defconfig的默认值生成.config |
make ${PLATFORM}_defconfig | 使用arch/$ARCH/configs/${PLATFORM}_defconfig生成.config;用make help可查看当前架构所有可用平台 |
make allyesconfig | 尽可能把所有符号设为y |
make allmodconfig | 尽可能把所有符号设为m |
make allnoconfig | 尽可能把所有符号设为n |
make randconfig | 随机取值 |
make localmodconfig | 基于当前配置与已加载模块(lsmod)生成配置,关闭未被加载模块需要的选项 |
make localyesconfig | 类似 localmodconfig,但把模块选项转为内建(=y) |
make kvm_guest.config | 开启 KVM 来宾内核所需的附加选项 |
make xen.config | 开启 Xen dom0 来宾内核所需的附加选项 |
make tinyconfig | 配置尽可能小的内核 |
其中localmodconfig支持两个进阶用法,README 原文给出了跨机器(含交叉编译)场景的完整示例:
# 在目标机上导出模块列表 target$ lsmod > /tmp/mylsmod target$ scp /tmp/mylsmod host:/tmp # 在构建机上指定 LSMOD 与需要保留的目录 host$ make LSMOD=/tmp/mylsmod \ LMC_KEEP="drivers/usb:drivers/gpu:fs" \ localmodconfigLMOD指向别的机器的lsmod输出,LMC_KEEP用冒号分隔、指定要强制保留的模块路径或 Kconfig 文件路径。
关于make config的三条注意事项(README 原话的要点):
- 塞入不必要的驱动会让内核变大,且可能引发问题——对不存在的控制卡做探测(probing)可能干扰其他控制器;
- 编入数学模拟(math-emulation)的内核在有协处理器时仍会优先使用协处理器,模拟代码只是用不上;内核略大,但无论机器有无数学协处理器都能工作;
- “kernel hacking”(开发/实验/调试)类选项通常使内核变大变慢,甚至通过主动“搞坏”坏代码(如针对
kmalloc()的路径)来暴露内核问题,生产环境一般应回答n。
更多 Kconfig 细节见 Documentation/kbuild/kconfig.rst。从源码结构看,make help中列出的${PLATFORM}_defconfig目标来自 Makefile:构建系统通过$(wildcard $(srctree)/arch/$(SRCARCH)/configs/*_defconfig)动态发现当前架构目录下所有平台默认配置并生成对应 make 目标,因此可用平台列表完全由arch/<架构>/configs/的实际文件决定。
六、编译与安装内核
6.1 基本编译与安装步骤
- 确认至少具备 gcc 8.1(详见 Documentation/process/changes.rst);
- 执行
make生成压缩内核镜像;若系统装有 LILO 或发行版提供内核安装器可识别的安装脚本,还可以直接make install。多数主流发行版都带有被识别的安装脚本,建议先确认发行版配置; - 真正安装需要 root 权限,但正常构建过程不应需要——README 原话:“Don't take the name of root in vain”(别把 root 之名滥用);
- 若把部分组件配置为模块,还需执行
make modules_install。
6.2 详细构建输出:V=1 / V=2
内核构建系统默认较安静(但非全静默)。需要看到编译、链接等命令的真实执行形态时,使用 verbose 模式:
make V=1 all # 显示每条编译/链接命令V=2会进一步解释每个目标为何被重建;默认是V=0。这是定位“为什么这个文件又被重编了”问题的第一手工具。
6.3 备份内核与 LOCALVERSION
README 要求手边常备一个可用的备份内核,尤其对开发版(每个发布都包含未经充分调试的新代码)。安装与在运内核同版本号的新内核前,先备份其模块目录再执行make modules_install。
更优雅的做法是配置LOCALVERSION选项给内核版本追加独特后缀(在 General Setup 菜单中设置)。从源码结构看,该后缀的生成逻辑集中在 scripts/setlocalversion,它会把用户在.config中设置的CONFIG_LOCALVERSION与 SCM 后缀拼接进最终kernel.release。
6.4 引导新内核:bzImage、EFISTUB 与 LILO 现状
- 编译后需要把内核镜像(x86 下即
arch/x86/boot/bzImage)复制到常规可启动内核所在位置才能启动; - 不再支持在 BIOS(非 EFI)系统上不经引导器直接从存储设备启动内核;UEFI/EFI 系统可以使用 EFISTUB 让主板直接引导内核,现代工作站/桌面仍建议用引导器,因为多内核管理与安全启动(secure boot)会带来麻烦,EFISTUB 细节见 Documentation/admin-guide/efi-stub.rst;
- 自 2016 年起 LILO 不再积极开发,但因其历史流行度仍频繁出现在文档中;流行的替代方案包括 GRUB2、rEFInd、Syslinux、systemd-boot 或 EFISTUB。README 明确不推荐使用已停止活跃开发的软件;
- 发行版通常自带安装脚本,直接
make install即可;否则需要自行确认引导器并参考其文档,或配置 EFI。
6.5 遗留 LILO 操作(原文保留)
如果仍在使用 LILO:
- 内核镜像在
/etc/lilo.conf中指定,镜像文件通常是/vmlinuz、/boot/vmlinuz、/bzImage或/boot/bzImage。使用新内核前,先保存旧镜像副本,再覆盖新镜像,然后必须重跑 LILO更新加载映射表,否则新内核无法启动; - 重新安装 LILO 通常是运行
/sbin/lilo;可编辑/etc/lilo.conf为旧内核镜像(如/vmlinux.old)保留一个条目,以防新内核不可用; - 重装 LILO 后关机重启即可;
- 若需要修改内核镜像内的默认 root 设备、视频模式等参数,用引导器的启动参数即可,无需重编内核。
七、出了问题怎么办:内核 bug 报告的排查路径
README 的最后部分给出了四条排查路线,全部对应仓库中真实存在的文档:
- 怀疑是内核 bug 时,按 Documentation/admin-guide/reporting-issues.rst 的指引提交问题报告;
- 理解内核 bug 报告的方法见 Documentation/admin-guide/bug-hunting.rst;
- 用 gdb 调试内核见 Documentation/process/debugging/gdb-kernel-debugging.rst;
- 内核态调试(KGDB)见 Documentation/process/debugging/kgdb.rst。
八、适用前提小结
- 本指南内容以 Documentation/admin-guide/README.rst 为准,文中版本号写作 6.x;当前仓库 Makefile 显示内核版本为
7.3.0-rc1(代号 Baby Opossum Posse),但“获取源码 → 配置 → 编译 → 安装 → 排查”的主流程与命令形式在各版本间保持一致,O=分离构建、V=1/V=2、localmodconfig、stable 补丁规则等机制在构建系统中均可验证; - 构建系统硬性要求 GNU Make ≥ 4.0(Makefile),编译器最低 gcc 8.1,最低版本要求以 Documentation/process/changes.rst 为准;
- 所有配置、编译、安装命令均在源码树顶层执行;
O=output/dir一旦使用须贯穿所有 make 调用。
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考