第4章:内核配置基础:make menuconfig界面操作、配置项分类

说实话,很多初学者第一次打开内核配置界面时,都会懵掉。

满屏的选项,密密麻麻的菜单,根本不知道从哪下手。我当年也是这样,对着屏幕发呆了好几分钟。后来做项目多了,才慢慢摸清门道——其实内核配置没那么玄乎,它就是个「搭积木」的过程。

4.1 启动 make menuconfig

进入内核源码目录,敲下这条命令:

cd linux-6.1.y/
make menuconfig

你会看到一个蓝底白字的界面。嗯,别被它的复古风格吓到,这玩意儿比很多图形界面工具都好用。

我的小习惯:每次配置前,我都会先执行 make mrproper 清理一下。避免上次的配置残留影响新配置。

4.2 界面操作速成

操作其实就几个键,我列个表给你看:

按键 作用
↑ ↓ 上下移动光标
Enter 进入子菜单 / 确认选择
Space 切换选项状态(Y/N/M)
Esc + Esc 返回上一级菜单
/ 搜索配置项(这个最常用)
? 查看当前选项的帮助信息

你可能会问:Y、N、M 分别代表什么?

  • Y:编译进内核(built-in)
  • N:不编译
  • M:编译成模块(module)

我个人建议:能编成模块的就别编进内核。为什么?因为模块可以动态加载,内核体积小,启动快。我在做嵌入式项目时,经常把驱动都编成模块,等系统起来后再按需加载。

注意:如果某个选项是 [*] 或 [ ],说明它只能选 Y 或 N,不能编成模块。比如 CPU 调度器、内存管理这些核心功能,必须编进内核。

4.3 配置项分类详解

进入 menuconfig 后,你会看到一堆分类。我挑几个重点的说说:

4.3.1 General setup — 通用设置

这里放的是内核最基础的配置。比如:

  • 内核版本号(可以自己改)
  • 是否支持动态模块加载
  • Cgroups 支持(容器技术的基础)
  • 内核压缩方式(gzip、lz4 等)

我曾经在一个项目里,为了把内核镜像压到 2MB 以内,试了好几种压缩算法。最后发现 lz4 虽然压缩率不高,但解压速度极快,适合启动时间要求高的场景。

4.3.2 Device Drivers — 设备驱动

这是最庞大的一个分类。里面包含了几乎所有硬件设备的驱动:

  • 串口、I2C、SPI 等总线驱动
  • 网卡、WiFi、蓝牙
  • USB、PCIe、MMC
  • 显示、音频、输入设备
  • ... 等等

你想想看,如果你的板子上没有某个硬件,对应的驱动就别选。选上了只会增加内核体积,没有任何好处。

避坑指南:我曾经在配置一个 ARM 板子时,忘了选串口驱动。结果内核启动后,控制台一片漆黑,啥也看不到。折腾了半天才发现是驱动没选。所以,先把串口驱动选上,这是调试的命根子。

4.3.3 File systems — 文件系统

你的根文件系统是什么格式?ext4?squashfs?还是 initramfs?

这里就要选对应的文件系统支持。我常用的组合是:

  • 根文件系统用 squashfs(只读,压缩率高)
  • 数据分区用 ext4(可读写,稳定)
  • 临时文件系统用 tmpfs(内存盘,速度快)

4.3.4 Kernel hacking — 内核调试

这个分类我建议在开发阶段全选上。比如:

  • Magic SysRq key(紧急情况下可以强制重启)
  • KGDB(内核调试器)
  • printk 时间戳

等产品发布时,再把这些关掉,能省不少空间。

4.4 知识体系结构图

下面这张图,是我自己总结的内核配置知识体系。你可以把它当作一个「导航地图」:

内核配置知识体系 make menuconfig 界面操作 ↑↓ 移动 · Enter 进入 Space 切换 Y/N/M / 搜索 · ? 查看帮助 配置分类 General setup 通用设置 Device Drivers 设备驱动 File systems 文件系统 Kernel hacking 内核调试 核心概念 Y = 编译进内核 M = 编译成模块 N = 不编译 依赖关系 · 互斥关系 三大分支:界面操作 → 配置分类 → 核心概念,层层递进

4.5 保存与加载配置

配置完成后,记得保存。默认会生成一个 .config 文件。我常用的几个命令:

# 保存当前配置
make savedefconfig    # 生成精简版配置(推荐)
cp .config myconfig   # 备份一份

# 加载已有配置
cp myconfig .config
make olddefconfig     # 用默认值填充新选项
我的经验:每次配置完,我都会用 make savedefconfig 生成一个精简版。这个文件只包含你修改过的选项,干净利落。下次换内核版本时,直接拿这个文件去 make olddefconfig,省时省力。

4.6 配置依赖关系

内核配置项之间是有依赖的。你选了 A,B 可能自动就选上了。反过来,你取消 C,D 可能也跟着没了。

为什么会这样?因为内核代码里用 depends on 和 select 定义了这些关系。比如:

config USB_STORAGE
    tristate "USB storage support"
    depends on USB
    select SCSI

意思是:要选 USB_STORAGE,必须先选 USB,同时会自动选上 SCSI。

我在项目里遇到过这种情况:明明选了某个驱动,编译时却报错说找不到依赖。后来一查,是某个底层总线驱动没选。所以,遇到编译错误时,先看看是不是依赖没满足。

好了,这一章的内容就这些。记住:内核配置不是一次就能搞定的,多试几次,慢慢就熟了。

可可精品资料库