3、内核配置工具详解:make menuconfig、make xconfig、make defconfig 的使用与对比

内核配置,说白了就是决定「我的 Linux 要支持哪些功能」。

我刚开始做嵌入式时,觉得这步就是点菜单,随便选选就行。直到有一次,我裁剪出来的内核镜像足足 8MB,而板子的 Flash 只有 4MB……嗯,从那以后我再也不敢小看配置这一步了。

今天咱们就把三种主流配置工具掰开揉碎讲清楚。你想想看,同一个 .config 文件,为什么有人用 menuconfig,有人用 xconfig,还有人直接敲 defconfig?

3.1 三种工具的核心定位

先给个总览表格,方便你快速对比:

工具 运行环境 交互方式 依赖库 适用场景
make menuconfig 终端(字符界面) 键盘方向键 + 空格/回车 ncurses SSH 远程、无图形环境、日常开发
make xconfig X Window 图形桌面 鼠标点击 + 搜索框 Qt 或 GTK+ 桌面开发机、复杂搜索、新手入门
make defconfig 终端(命令行) 无交互,直接生成 无 快速初始化、批量构建、CI 自动化

我的建议:日常开发用 menuconfig,复杂搜索用 xconfig,初始化或自动化用 defconfig。三者不冲突,可以配合使用。

3.2 make menuconfig —— 嵌入式开发者的「主力武器」

这是我在项目中最常用的工具。没有之一。

为什么?因为嵌入式开发经常要 SSH 到服务器或者开发板上操作,没有图形桌面。menuconfig 只需要一个终端和 ncurses 库,就能跑起来。

3.2.1 基本用法

# 进入内核源码根目录
cd linux-5.10.y

# 启动 menuconfig
make menuconfig

# 如果提示缺少 ncurses,安装一下
sudo apt-get install libncurses-dev

界面打开后,你会看到这样的结构:

  • 上下方向键:移动光标
  • 回车:进入子菜单
  • 空格:切换选项状态(Y/M/N)
  • ESC + ESC:返回上一级
  • /?:搜索功能,按 / 输入关键词

小技巧:按 / 搜索时,输入 CONFIG_XXX 或直接输入功能名(如 USB),会显示该选项的路径、依赖关系和当前状态。我在调试 USB 驱动时,经常靠这个快速定位配置项。

3.2.2 选项状态的含义

符号 含义 说明
[*] 编译进内核(built-in) 功能直接集成到 zImage 中,启动时自动加载
[M] 编译为模块(module) 生成 .ko 文件,需要时手动 insmod 或自动加载
[ ] 不编译 完全禁用该功能

注意:对于工业嵌入式设备,我建议把关键驱动(如串口、网卡、存储控制器)编译进内核,不要用模块。我曾经遇到过板子启动后文件系统还没挂载,模块加载失败导致网口不通的情况……嗯,从那以后我就学乖了。

3.3 make xconfig —— 图形化搜索利器

如果你在桌面 Linux 上开发,xconfig 会让你效率翻倍。

它的界面类似 Windows 的树形控件,左侧是菜单树,右侧是选项详情。最强大的功能是搜索框——支持模糊匹配和正则表达式。

3.3.1 启动与依赖

# 安装 Qt 依赖(以 Qt 版本为例)
sudo apt-get install qtbase5-dev

# 启动 xconfig
make xconfig

界面打开后,你可以:

  • 鼠标点击展开/折叠:比键盘快很多
  • 搜索框实时过滤:输入 SPI,所有 SPI 相关选项立刻显示
  • 右键查看依赖:快速了解某个选项依赖哪些其他配置

我个人习惯:在桌面开发机上先用 xconfig 做一轮全局搜索和配置,把需要的驱动和功能都勾上,保存为 .config。然后把这个文件传到服务器或板子上,再用 menuconfig 做微调。这样既享受了图形化的便利,又保留了终端的高效。

3.3.2 什么时候用 xconfig?

  • 需要同时查看多个配置项的依赖关系
  • 对内核不熟悉,需要搜索功能辅助
  • 做大规模配置修改(比如从零开始裁剪)

3.4 make defconfig —— 快速起步的「模板生成器」

defconfig 不是交互工具,而是一个命令。它根据当前架构的默认配置模板,直接生成一个 .config 文件。

3.4.1 用法

# 查看当前架构支持的 defconfig 列表
ls arch/arm/configs/

# 使用某个 defconfig
make ARCH=arm imx_v7_defconfig

# 或者直接生成当前架构的默认配置
make defconfig

执行后,内核会自动从 arch/<ARCH>/configs/ 目录下找到对应的配置文件,复制为 .config。

3.4.2 常见 defconfig 示例

架构 常用 defconfig 适用平台
ARM imx_v7_defconfig NXP i.MX 系列
ARM bcm2835_defconfig Raspberry Pi
ARM64 defconfig 通用 ARM64 平台
x86 defconfig PC/服务器

我的经验:拿到一块新板子,第一步就是找到对应的 defconfig。比如 i.MX6ULL 的板子,直接 make imx_v7_defconfig,然后在此基础上裁剪。这比从零开始配要快 10 倍。

3.5 三种工具的协作流程

在实际项目中,我不会只用一种工具。下面这张图展示了我常用的工作流:

内核配置工具协作流程 make defconfig make xconfig make menuconfig 保存 .config ① 快速初始化 基于板级模板起步 ② 全局搜索与配置 桌面端批量修改 ③ 终端微调 SSH 远程精细调整 ④ 固化配置 保存为最终 .config

流程很简单:

  1. 先用 defconfig 打底:找到板子对应的默认配置,快速生成基础 .config
  2. 再用 xconfig 做全局搜索:在桌面端把需要的驱动、文件系统、网络协议都勾上
  3. 最后用 menuconfig 微调:在终端上做最后的裁剪和优化
  4. 保存并固化:把最终的 .config 保存到版本管理,方便后续复用

3.6 避坑指南

我曾经踩过的坑:

  • 坑1:用 menuconfig 配置完后,直接 make 编译,结果报错说某个选项依赖不满足。后来发现是因为我改了某个选项,但它的依赖选项没同步更新。解决办法:配置完后执行 make olddefconfig,让内核自动补全依赖。
  • 坑2:在 xconfig 里搜索 USB,勾了一堆选项,结果编译出来的内核比原来大了 3MB。后来才意识到,很多 USB 子选项默认是 [*],我全勾成了 [M],但模块也占空间。建议:只勾你真正需要的。
  • 坑3:defconfig 生成的配置不一定完全适合你的板子。比如 imx_v7_defconfig 支持整个 i.MX7 系列,但你的板子可能只有 256MB 内存,需要手动关掉一些大内存特性。

3.7 总结对比表

维度 make menuconfig make xconfig make defconfig
交互方式 键盘导航 鼠标 + 键盘 无交互
搜索能力 按 / 搜索,支持关键词 实时搜索框,支持模糊匹配 无
依赖展示 文本提示 图形化依赖树 无
适用环境 终端/SSH 桌面图形 终端/脚本
学习成本 低 低 极低
我的推荐度 ★★★★★ ★★★★ ★★★★★

好了,三种工具就讲到这里。记住一个原则:defconfig 起步,xconfig 搜索,menuconfig 微调。下次你拿到一块新板子,试试这个流程,你会发现内核配置其实没那么复杂。