Linux 内核裁剪的核心是“精准取舍”——在满足功能需求的前提下,最大化移除冗余。以下是经过实践验证的实用技巧,涵盖配置、依赖处理、验证等关键环节,适用于嵌入式、物联网、专用设备等场景。

一、配置工具的高效使用技巧

内核配置是裁剪的基础,熟练掌握配置工具的进阶用法可大幅提升效率。

  1. 基于现有系统快速生成基础配置
    若目标设备已有可运行的 Linux 系统,可直接基于当前加载的模块生成最小配置,避免从零开始:

    # 生成仅包含当前加载模块的配置(模块为m,其他为n)
    make localmodconfig  
    # 生成仅包含当前加载模块且全部编译为内置的配置(所有为y)
    make localyesconfig  
    

    这两个命令会扫描 /proc/modules/sys,自动禁用未使用的功能,适合作为裁剪的起点。

  2. 用“搜索”定位配置项
    make menuconfig 中按 / 键可搜索配置项(支持关键词或符号),快速定位目标功能。例如:

    • 搜索“wifi”可找到所有无线相关配置;
    • 搜索“CONFIG_USB”可列出所有 USB 相关选项。
      搜索结果会显示选项路径(如 Device Drivers -> USB support),直接跳转修改。
  3. 批量修改配置项
    scripts/config 工具批量启用/禁用配置,避免手动操作:

    # 禁用IPv6(=n)
    scripts/config --disable CONFIG_IPV6  
    # 启用USB支持(=y)
    scripts/config --enable CONFIG_USB  
    # 将WiFi驱动设为模块(=m)
    scripts/config --module CONFIG_WLAN  
    

    适合需要批量调整的场景(如禁用所有调试选项)。

  4. 对比配置差异
    diff 比较不同配置文件,快速定位修改点:

    diff .config .config.old > config_diff.txt  
    

    常用于复用历史配置或排查因配置导致的问题。

二、依赖处理:避免“牵一发而动全身”

内核配置项存在复杂依赖关系(如启用 A 必须启用 B),处理不当可能导致关键功能被误删或编译失败。

  1. make oldconfig 处理依赖变更
    当基于旧版本配置修改或手动编辑 .config 后,运行:

    make oldconfig  
    

    工具会自动检测依赖变化,提示用户确认新增或冲突的选项(按 Enter 接受默认值,适合快速处理)。

  2. 识别“隐性依赖”
    部分配置项的依赖不明显(如文件系统依赖 VFS 层),可通过以下方式确认:

    • menuconfig 中选中选项后按 ? 键,查看帮助信息中的“Depends on”;
    • 查看内核源码 Kconfig 文件(如 fs/Kconfig 包含文件系统依赖)。
      例如:CONFIG_EXT4_FS 依赖 CONFIG_BLOCK(块设备支持),禁用 CONFIG_BLOCK 会导致 ext4 无法启用。
  3. “最小依赖”原则
    启用功能时只勾选直接依赖,不勾选“可选依赖”。例如:启用 CONFIG_TCP 时,仅需确保 CONFIG_INET(IPv4)启用,无需勾选 CONFIG_TCP_MD5SIG(TCP 加密,非必需)。

三、模块化与内置:平衡体积与灵活性

功能的编译方式(内置 =y/模块 =m/禁用 =n)直接影响内核体积和灵活性,需按场景选择。

  1. 启动必需功能→内置
    设备启动阶段依赖的功能(如 CPU 驱动、根文件系统驱动、主板总线)必须编译为内置(=y),否则会因无法加载模块而启动失败。例如:

    • 根文件系统为 ext4:CONFIG_EXT4_FS=y
    • 板载网卡为启动时联网必需:CONFIG_NET_VENDOR_INTEL=y 且具体驱动 =y
  2. 非必需功能→模块或禁用

    • 偶尔使用的功能(如 USB 外接设备驱动)编译为模块(=m),需要时手动加载(insmod),不占用内核镜像体积;
    • 完全无用的功能直接禁用(=n),如物联网设备禁用 CONFIG_PRINTER(打印支持)。
  3. 资源受限设备→全内置
    对于内存极小(如 <64MB)的设备,建议禁用模块支持(CONFIG_MODULES=n),所有功能编译为内置:

    • 避免模块加载器(modprobe)占用内存;
    • 减少文件系统中模块文件的存储开销。

四、极致裁剪:移除“隐形冗余”

除了明显的功能,内核中还有许多默认启用但非必需的冗余项,需针对性清理。

  1. 禁用调试与诊断功能
    调试功能会显著增加内核体积并降低性能,生产环境可全部禁用:

    CONFIG_DEBUG_KERNEL=n          # 关闭内核调试框架
    CONFIG_DEBUG_INFO=n           # 不生成调试信息(减少几十MB)
    CONFIG_PRINTK=n               # 禁用内核日志(仅极端场景,如无控制台设备)
    CONFIG_AUDIT=n                # 禁用进程审计(嵌入式无需)
    
  2. 简化进程与内存管理

    • 单核心设备:禁用 SMP(对称多处理)支持(CONFIG_SMP=n),移除多核心调度冗余;
    • 小内存设备(<128MB):禁用虚拟内存(CONFIG_MMU=n,需内核支持无 MMU 模式)、swap 交换(CONFIG_SWAP=n);
    • 非实时设备:简化调度器(仅保留 CFS,禁用 CONFIG_PREEMPT 实时抢占)。
  3. 裁剪文件系统与网络

    • 无本地存储的设备(如传感器):禁用所有文件系统(CONFIG_FILE_SYSTEMS=n);
    • 仅需基础联网:保留 CONFIG_INET(IPv4)和 CONFIG_TCP/CONFIG_UDP,禁用 CONFIG_IPV6CONFIG_BT(蓝牙)、CONFIG_WIFI 等;
    • 专用网络设备:移除不支持的协议(如 CONFIG_NET_IPIP 隧道、CONFIG_IPVLAN 等)。
  4. 移除架构无关代码
    明确目标架构后,禁用其他架构支持:

    • ARM 设备:CONFIG_X86=nCONFIG_RISCV=n
    • x86 设备:CONFIG_ARM=nCONFIG_MIPS=n
      可在 menuconfigArchitecture 菜单中批量处理。

五、验证与调试:确保裁剪后系统可用

裁剪后需通过严格验证,避免因缺失功能导致系统异常。

  1. 启动日志分析
    启动后查看 dmesg 日志,重点关注:

    • 错误信息(如 driver not found 表示缺失驱动);
    • 警告信息(如 module not loaded 表示依赖模块未启用)。
      例如:若网卡未识别,日志中会出现 eth0: no such device,需重新启用对应网卡驱动。
  2. 功能测试清单
    按设备核心功能制定测试清单,例如:

    • 路由器:测试有线/无线联网、NAT 转发、DHCP 分配;
    • 传感器:测试数据采集、无线传输、低功耗休眠。
  3. 体积与性能评估

    • 体积:查看编译后的内核镜像(arch/<架构>/boot/bzImage)大小;
    • 启动时间:用 systemd-analyze 或自定义脚本统计从内核加载到应用启动的耗时;
    • 内存占用:用 freetop 查看 idle 状态下的内存使用。

六、配置复用与版本管理

裁剪后的配置需妥善保存,方便后续迭代或移植到同类设备。

  1. 生成精简配置文件
    make savedefconfig 生成去除冗余注释的精简配置(defconfig):

    make savedefconfig  
    cp defconfig arch/<架构>/configs/my_custom_defconfig  # 保存到架构目录
    

    下次编译可直接使用:make my_custom_defconfig

  2. 用配置片段(config fragments)管理差异
    对于同类设备的细微差异(如不同传感器型号),可将公共配置作为基础,差异部分用片段文件管理:

    # 基础配置
    make base_defconfig  
    # 叠加传感器A的配置片段
    scripts/kconfig/merge_config.sh .config sensor_a.fragment  
    

    片段文件(如 sensor_a.fragment)内容为:CONFIG_SENSOR_A=y

七、避坑指南

  1. 勿碰核心功能:进程调度(CONFIG_SCHED)、内存管理(CONFIG_MMUCONFIG_NO_MMU)、中断处理(CONFIG_GENERIC_IRQ)等核心功能不可禁用,否则内核无法运行。
  2. 硬件文档优先:裁剪驱动前务必查阅硬件手册,确认芯片型号(如网卡型号为“RTL8168”,则需保留对应驱动)。
  3. 渐进式裁剪:先基于默认配置禁用明显无用项,测试通过后再逐步细化,避免一次性大幅修改导致问题定位困难。

通过以上技巧,可在保证功能的前提下,将内核体积缩减50%-90%(视场景而定),同时提升启动速度和运行效率。核心原则是:“明确需求→精准配置→反复验证”,结合具体硬件和场景灵活调整。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐