24.1 编译前的任务:认识核心与取得核心源代码
一般使用者不需要编译核心。只有在:新硬件驱动未进入当前核心、嵌入式系统精简、特定功能需求、学习核心原理时才需要。
24.1.1 什么是核心(Kernel)
核心就是系统上的一个文件(/boot/vmlinuz-xxx),包含驱动所有硬件的侦测程序与驱动模块。
开机流程中:BIOS → MBR(loader) → 载入核心到内存 → 核心侦测硬件 → 挂载根目录 → 载入核心模块 → 调用 systemd 启动服务。
核心模块 (kernel module):
| 概念 | 说明 |
|---|---|
| 为什么需要模块 | 硬件更新太快,如果每次新硬件都要重编整个核心太麻烦 |
| 模块是什么 | 将不常用的驱动程序独立出核心,编译成 .ko 文件,系统运行时动态载入 |
| 模块位置 | /lib/modules/$(uname -r)/kernel/ |
驱动程序开发是硬件厂商的责任——厂商要提供消费者能用的驱动,无论是 Windows 还是 Linux。
24.1.2 更新核心的目的
核心编译的重点:你的 Linux 要做什么? 不必要的功能就别编译进去——越精简越稳定。
编译核心的时机:
| 场景 | 说明 |
|---|---|
| 新功能需求 | 新核心才有的功能(如新版 iptables、新主板芯片组支持) |
| 核心太过臃肿 | 追求稳定性——移除不需要的功能 |
| 硬件搭配稳定性 | 原核心针对 Intel CPU 优化,AMD 可能需要重编;新硬件无驱动 |
| 嵌入式系统 | 需要小而美的精简核心(如树莓派、香蕉派) |
| 性能优化 | 针对特定 CPU 优化,但效益不大 |
💡 如果系统已运行很久没问题,也不增加冷门硬件 → 不需要重编核心。distribution 的默认核心已经很适合一般使用。
24.1.3 核心的版本
CentOS 7 使用 3.10.x 长期维护版。升级建议:
- 使用长期维护版本的最新版(如 3.10.89),而非主线最新版(如 4.2.1)
- 跨版本升级(如 3.10→4.x)可能造成软件兼容性问题,后果自负
鸟哥曾为 VGA PCI passthrough 将 CentOS 7.1 的 3.10.x 升级到 4.2.3——有特殊需求时可以,但要自行承担风险。
24.1.4 核心源代码的取得方式
| 来源 | 说明 | 地址 |
|---|---|---|
| CentOS SRPM | 含默认设置值,编译难度低 | http://vault.centos.org/ |
| kernel.org 最新稳定版 | 支持新硬件,但无 distro 默认值 | http://www.kernel.org/ |
| patch 升级 | 从旧版逐版打补丁升级 | kernel.org 的 patch 文件 |
💡 推荐使用 distribution 的 SRPM——保留原默认设置,在此基础上微调即可。
24.1.5 核心源代码的解压缩/安装/观察
tar -Jxvf linux-3.10.89.tar.xz -C /usr/src/kernels/
cd /usr/src/kernels/linux-3.10.89源代码目录结构:
| 目录 | 内容 | 目录 | 内容 | |
|---|---|---|---|---|
arch/ | CPU 架构(x86, x86_64…) | kernel/ | 核心程序、调度、信号 | |
block/ | 区块设备、文件系统 | lib/ | 函数库 | |
crypto/ | 加密技术(md5, des) | mm/ | 内存管理、swap | |
Documentation/ | 核心说明文档 | net/ | 网络协定、防火墙 | |
drivers/ | 硬件驱动程序 | security/ | SELinux 等安全设置 | |
firmware/ | 旧硬件固件 | sound/ | 音效模块 | |
fs/ | 文件系统(vfat, nfs…) | virt/ | KVM 虚拟化 | |
include/ | 头文件(header) |
24.2 核心编译的前处理与核心功能选择
24.2.1 硬件环境检视与核心功能要求
编译前必须了解自己的硬件和需求。查看硬件:
cat /proc/cpuinfo # CPU 信息
lspci # PCI 设备(网卡、显卡等)
lsusb # USB 设备24.2.2 保持干净源代码:make mrproper
| 命令 | 作用 | 使用时机 |
|---|---|---|
make mrproper | 清除所有编译残留 + 配置文件 | 首次编译前 |
make clean | 仅清除目标文件(.o),保留配置文件 | 重复编译时 |
⚠️
make mrproper会删除.config!如果已用cp /boot/config-xxx .config复制了配置文件,不要再执行它。
24.2.3 开始挑选核心功能:make XXconfig
| 命令 | 说明 |
|---|---|
make menuconfig | 最常用——文字模式类图形界面,不需 X Window |
make oldconfig | 使用已有 .config 为默认值,只列出新功能选项(升级用) |
make xconfig | Qt 图形界面(需 KDE) |
make gconfig | Gtk 图形界面(需 GNOME) |
make config | 逐条问答式(最古老,不推荐) |
懒人方法——以 CentOS 默认配置为基础微调:
cp /boot/config-$(uname -r) .config # 以系统当前核心配置为底
make menuconfig # 在此基础上微调menuconfig 操作:方向键移动、空格键选择、Enter 进入子菜单。
| 符号 | 含义 |
|---|---|
[*] / <*> | 编译进核心(核心功能) |
<M> | 编译为模块(按需加载) |
[ ] / < > | 不编译 |
选择原则:
- 肯定要用的 → 编译进核心
- 可能未来会用到 → 编译成模块
- 看不懂的 → 保留默认值,或编译成模块
24.2.4 核心功能细项选择
General setup:
| 项目 | 建议 |
|---|---|
| Local version | 自定义版本后缀(如 3.10.89.vbird) |
| Kernel compression mode | 选 Bzip2(压缩比高) |
| initramfs support | 必须勾选 |
| Optimize for size | 桌面/服务器不用选(嵌入式才选) |
Loadable module + Block layer:
| 项目 | 说明 |
|---|---|
| Enable loadable module support | 必选——支持动态加载模块 |
| Forced module unloading | 建议勾选——强制卸载顽固模块 |
| I/O Scheduler | 建议选 Deadline 并设为核心功能(服务器场景) |
CPU (Processor type and features):
| 项目 | 建议 |
|---|---|
| Processor family | 选 Generic-x86-64(除非是老硬件) |
| Preemption Model | Server 选 No Forced Preemption |
| Timer frequency | Server 选 300Hz,Desktop 选 1000Hz |
| KVM Guest support | 虚拟化相关,建议勾选 |
Power management:
| 项目 | 建议 |
|---|---|
| ACPI Support | 桌面/服务器都选 |
| CPU Frequency scaling | Default governor 选 ondemand |
Bus options:PCI Express 支持必选,否则新显卡可能无法工作。
Executable file formats:ELF、#! scripts 必选;建议启用 32 位仿真(IA32 Emulation)以兼容旧软件。
Networking support:防火墙相关全部编译为模块。Network packet filtering framework (Netfilter) 是 iptables 的基础,必须启用。
Device Drivers——最重要的部分:
| 类别 | 关键项 |
|---|---|
| SATA/ATA | Serial ATA and Parallel ATA → 编为模块 |
| RAID/LVM | Multiple devices driver support → 必选 |
| Network | 网卡驱动、Bonding、Virtio 网络 → 编为模块 |
| Graphics | 桌面机需要,服务器可选 |
| Sound | 桌面机需要 |
| USB | xHCI (USB3.0)、EHCI (USB2.0)、OHCI、UHCI 全部编入核心 |
| Virtio drivers | 虚拟机环境很重要 |
| VFIO | VGA passthrough 用(需 KVM 虚拟化) |
File systems:
| 项目 | 建议 |
|---|---|
| ext2/ext3/ext4 | 全选为模块 |
| XFS | 必选(CentOS 7 默认) |
| Btrfs | 建议支持 |
| Quota support | 选为核心功能 |
| NTFS | 选为模块 + 开启写入 |
| FAT 中文支持 | Default codepage=950, Default iocharset=utf8 |
| NFS client/server | 选为模块 |
| CIFS (Samba) | 选为模块 |
Security + Crypto:SELinux 保持默认;加密 API 保持默认。
Virtualization:KVM 编入核心(Intel + AMD processor support 都选)。
设置完后 Save → 文件名 .config → OK → Exit。
24.3 核心的编译与安装
24.3.1 编译核心与核心模块
# 主要编译命令
make bzImage # 编译压缩后的核心
make modules # 编译核心模块
make -j N clean bzImage modules # 清理 + 并行编译-j N:并行编译,N = CPU 核心数。$(nproc)自动获取- 编译后核心位于
arch/x86/boot/bzImage
24.3.2 实际安装模块
避免同版本冲突的方法:在 General setup → Local version 中加上自定义后缀(如 3.10.89vbird)。
make modules_install
ll /lib/modules/ # 看到 3.10.89vbird 目录24.3.3 开始安装新核心与多重核心菜单(grub)
保留旧核心:确保新核心有问题时能用旧核心开机恢复。
# 1. 复制核心和相关文件到 /boot
cp arch/x86/boot/bzImage /boot/vmlinuz-3.10.89vbird
cp .config /boot/config-3.10.89vbird
cp System.map /boot/System.map-3.10.89vbird
gzip -c Module.symvers > /boot/symvers-3.10.89vbird.gz
restorecon -Rv /boot
# 2. 创建 initramfs
dracut -v /boot/initramfs-3.10.89vbird.img 3.10.89vbird
# 3. 重建 grub 菜单(自动检测 /boot 下所有核心)
grub2-mkconfig -o /boot/grub2/grub.cfg
# 4. 重启 → 选择新核心 → 验证
reboot
uname -a # Linux ... 3.10.89vbird ...24.4 额外(单一)核心模块编译
24.4.1 编译前注意事项
模块编译需要核心源代码。/lib/modules/$(uname -r)/ 下的两个关键链接:
ls -l /lib/modules/3.10.89vbird/
# build -> /usr/src/kernels/linux-3.10.89 ← 头文件 + 编译工具
# source -> /usr/src/kernels/linux-3.10.89 ← 源代码编译模块需要:
make,gcc,kernel-devel(或核心源代码)。
24.4.2 单一模块编译
场景一:硬件厂商提供的额外驱动
# 1. 下载、解压、编译
tar -zxvf driver.tar.gz && cd driver/
make # 利用核心 build 链接自动找到源代码
# 产生 driver.ko
# 2. 安装
cp driver.ko /lib/modules/$(uname -r)/kernel/drivers/xxx/
depmod -a # 更新模块相依性
# 3. 测试载入
modprobe driver
# 4. 如果需要开机时载入,重做 initramfs
dracut --force -v --add-drivers driver /boot/initramfs-xxx.img $(uname -r)场景二:用已有核心源代码补编遗漏的模块
cd /usr/src/kernels/linux-3.10.89
make menuconfig # 勾选遗漏的功能 → 设为 <M>
make fs/ntfs/ # 只编译该目录的模块
cp fs/ntfs/ntfs.ko /lib/modules/$(uname -r)/kernel/fs/ntfs/
depmod -a24.4.3 核心模块管理
关键认知:核心、核心模块、驱动程序模块、核心源代码、头文件是环环相扣的。核心更新后,之前自行编译的模块会失效,需重新编译。modprobe 依赖 modules.dep 解析模块相依性。
24.5 以最新核心版本编译 CentOS 7.x 的核心
使用 ELRepo 提供的 SRPM 编译最新核心(示例:升级到 4.2.3):
# 1. 下载并安装 SRPM
wget http://elrepo.org/linux/kernel/el7/SRPMS/kernel-ml-4.2.3-1.el7.elrepo.nosrc.rpm
rpm -ivh kernel-ml-4.2.3-1.el7.elrepo.nosrc.rpm
# 2. 下载核心源代码
cd ~/rpmbuild/SOURCES
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.2.3.tar.xz
# 3. 修改功能(如开启 VFIO VGA 支持)
vim config-4.2.3-x86_64
# CONFIG_VFIO_PCI_VGA is not set → 改为 CONFIG_VFIO_PCI_VGA=y
# 4. 修改 .spec 文件(指定本地源代码文件)
cd ../SPECS
vim kernel-ml-4.2.spec
# Source0 改为: Source0: linux-%{LKAver}.tar.xz
# 5. 编译打包(可能需要数小时!)
rpmbuild -bb kernel-ml-4.2.spec
# 产生: /root/rpmbuild/RPMS/x86_64/kernel-ml-4.2.3-*.rpm
# 6. 安装
yum install /root/rpmbuild/RPMS/x86_64/kernel-ml-4.2.3-1.el7.centos.x86_64.rpm
reboot
uname -a # 4.2.3!命令速查表
| 命令 | 用途 |
|---|---|
uname -r | 查看当前核心版本 |
tar -Jxvf linux-xxx.tar.xz -C /usr/src/kernels/ | 解压核心源代码 |
make mrproper | 清除所有残留 + 配置文件(首次编译前) |
make clean | 仅清除目标文件(保留 .config) |
cp /boot/config-$(uname -r) .config | 以当前核心配置为基础 |
make menuconfig | 文字模式菜单选择核心功能 |
make oldconfig | 升级用——只提示新功能 |
make -j $(nproc) bzImage | 编译压缩核心 |
make -j $(nproc) modules | 编译核心模块 |
make modules_install | 安装模块到 /lib/modules/ |
cp arch/x86/boot/bzImage /boot/vmlinuz-xxx | 复制核心文件 |
dracut -v /boot/initramfs-xxx.img 版本号 | 创建 initramfs |
grub2-mkconfig -o /boot/grub2/grub.cfg | 重建 grub 菜单 |
depmod -a | 更新模块相依性数据库 |
make fs/ntfs/ | 仅编译 ntfs 模块 |
rpmbuild -bb kernel-ml.spec | 从 SRPM 编译打包 RPM 核心 |