--- title: Linux内核裁剪与编译 tags: [Linux内核, 内核编译, Makefile, 内核移植, 设备树, ARM] created: 2026-09-17 updated: 2026-09-17 pdf_ref: - "40_第三十五章 Linux内核顶层Makefile详解.pdf" - "42_第三十七章 Linux内核移植.pdf" --- # Linux内核裁剪与编译 > **关联知识**: [[06-系统移植与启动/01-U-Boot命令与使用]] | [[06-系统移植与启动/02-U-Boot启动流程]] | [[06-系统移植与启动/04-根文件系统构建]] 编译 Linux 内核和编译 U-Boot 的流程高度相似:先 `make xxx_defconfig` 选定默认配置,再 `make` 生成镜像。区别在于 Linux 内核多出一套 Kconfig 配置系统、一个庞大的 `drivers/` 驱动目录和独立编译的设备树(DTS/DTB)。本章以 NXP `linux-imx-4.1.15` 源码和正点原子 I.MX6U-ALPHA(EMMC 版)为主线,串起内核概述、配置、裁剪、顶层 Makefile、编译、设备树六个环节。 --- ## 一、Linux内核概述 ### 1.1 内核版本选择 内核源码由 Linux 基金会管理与发布,官网 。开发中并不追求最新版,而是**跟随半导体厂商的 BSP 版本**: | 来源 | 版本 / 文件 | 说明 | | ------------ | -------------------------------------------- | --------------------------------------------------------------------------- | | NXP 官方原版 | `linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2` | NXP 移植到 i.MX 系列后的 BSP,解压出目录`linux-imx-rel_imx_4.1.15_2.1.0_ga` | | 移植用目录 | `linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek` | 用`mv`重命名,避免与 NXP 官方目录混淆(书中做法) | 为什么用 **4.1.15**:NXP 对 i.MX6ULL 的 BSP 长期维护在这个版本,外设驱动、设备树最完整;4.x 与 5.x 在核心机制上没有本质区别,5.x 更多是新增平台和外设。中途换版本意味着设备树、驱动全部重调,得不偿失。 ### 1.2 内核源码目录结构 ```mermaid mindmap root((Linux内核源码)) arch/ 体系结构与设备树 drivers/ 设备驱动 fs/ 文件系统 kernel/ 核心调度 mm/ 内存管理 net/ 网络协议栈 include/ 头文件 init/ 内核初始化 scripts/ 构建脚本 Makefile Kconfig 顶层构建 ``` ```text linux-imx-4.1.15/ +-- arch/ # 架构相关,arch/arm 下有 boot、configs、mach-xxx +-- block/ # 块设备管理 +-- crypto/ # 加密算法(crc、md5、hash) +-- Documentation/ # 官方文档,查模块/驱动架构的第一去处 +-- drivers/ # 驱动(i2c、gpio、net、mmc…),学习重点 +-- firmware/ # 固件 +-- fs/ # 文件系统(ext4、f2fs、nfs、yaffs2) +-- include/ # 头文件 +-- init/ # 内核启动初始化代码 +-- ipc/ # 进程间通信 +-- kernel/ # 内核核心代码 +-- lib/ # 公共库函数 +-- mm/ # 内存管理 +-- net/ # 网络协议栈 +-- samples/ # 示例代码 +-- scripts/ # 编译脚本(kconfig、Makefile.build、link-vmlinux.sh) +-- security/ # 安全模块 +-- sound/ # 音频子系统 +-- tools/ # 编译工具 +-- usr/ # initramfs 相关 +-- virt/ # 虚拟化(KVM) +-- .config # 最终配置(编译生成) +-- Kbuild # 部分 Makefile 会读取 +-- Kconfig # menuconfig 图形界面的配置源 +-- Makefile # 顶层 Makefile +-- System.map # 符号表(编译生成) +-- vmlinux # 未压缩 ELF(编译生成) ``` 重点关注的子目录: | 目录 | 作用 | 关键点 | | ------------------------ | ---------------- | ------------------------------------------- | | `arch/arm/configs/` | 各平台默认配置 | `imx_v7_defconfig`、`imx_v7_mfg_defconfig` | | `arch/arm/boot/` | 编译产物 | `Image`、`zImage` | | `arch/arm/boot/dts/` | 设备树源码与产物 | `imx6ull-alientek-emmc.dts/.dtb` | | `arch/arm/mach-xxx/` | 平台初始化 | `mach-imx` 为 i.MX 系列 | | `drivers/` | 驱动源码 | 按类型分类,如 `drivers/net`、`drivers/mmc` | | `scripts/kconfig/` | 配置工具 | `conf` 负责生成 `.config` | | `scripts/Makefile.build` | 子目录构建入口 | 每个目录的 `built-in.o` 由它生成 | ### 1.3 内核配置系统 | 文件 | 角色 | 是否该改 | | ------------------------------ | ------------------------------------------------ | --------------------------- | | `Kconfig` | 配置菜单的“源”,描述每个配置项的名称、类型、依赖 | 加新驱动时才改 | | `.config` | 最终生效的配置,`make` 编译时读取 | 机器生成,不手改 | | `xxx_defconfig` | 精简版默认配置,存于 `arch/arm/configs/` | 手改或 `savedefconfig` 导出 | | `include/generated/autoconf.h` | 由 `.config` 自动生成,供 C 代码 `#ifdef` 使用 | 自动生成 | 三者的转换关系: ```text Kconfig(菜单定义) + xxx_defconfig(默认值) | make menuconfig / make xxx_defconfig v .config(最终配置) | 自动生成 v include/generated/autoconf.h(C 代码可见的宏) ``` ### 1.4 内核构建系统(Kbuild) Kbuild 是 Linux 内核的构建框架,不是单个文件,而是一套约定: - 顶层 `Makefile` 负责版本号、交叉编译变量、目标分发(`all`、`zImage`、`dtbs`、`modules`)。 - `scripts/Kbuild.include` 提供 `build`、`if_changed`、`echo-cmd` 等通用函数。 - `scripts/Makefile.build` 是每个子目录的真正执行者,读取子目录的 `Makefile`(或 `Kbuild`)。 - 子目录用 `obj-y`(编译进内核)、`obj-m`(编译成模块)声明源文件。 ```makefile # drivers/net/phy/Makefile 片段:按配置决定是否编译 obj-$(CONFIG_SMSC_PHY) += smsc.o ``` 当 `.config` 里 `CONFIG_SMSC_PHY=y` 时,`smsc.c` 被编译进内核;`=m` 时编译为模块 `smsc.ko`。 --- ## 二、内核配置方法 ### 2.1 make menuconfig 交互式配置 ```bash # 在源码根目录执行,菜单界面基于 ncurses make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig ``` 界面结构:顶部为标题,中间为可折叠菜单树,底部为操作提示。配置项前的符号含义: | 符号 | 含义 | | --------- | -------------------------- | | `[ ]` | 布尔项,未选 | | `[ * ]` | 布尔项,选中(编进内核) | | `< >` | 三态项,未选 | | `< * >` | 三态项,`=y`(编进内核) | | `< M >` | 三态项,`=m`(编译成模块) | | `(value)` | 数值 / 字符串项 | | `-*-` | 被其他项强制选中,不可改 | ### 2.2 导航技巧 | 按键 | 作用 | | --------------- | -------------------------------------------------------------- | | `↑` / `↓` | 上下移动 | | `←` / `→` | 切换底部按钮(`