4. 内核配置与编译基础:Kconfig与Makefile结构、defconfig使用、menuconfig配置、内核编译流程

在全志T113平台上进行外设驱动移植,内核的配置与编译是贯穿始终的基础技能。不同内核版本(如Linux 4.9、5.4、5.10、6.1等)在Kconfig语法、Makefile组织以及编译流程上虽有共性,但也存在细微差异。本章将系统梳理这些核心概念,帮助你在面对不同内核版本时,能够快速定位配置选项、理解编译依赖,并高效完成内核镜像的构建。

4.1 Kconfig 内核配置系统

Kconfig是Linux内核的配置系统,它定义了所有可配置的选项及其依赖关系。每个内核版本都包含一个庞大的Kconfig树,驱动开发者通过修改或新增Kconfig条目,使自己的外设驱动能够被用户选择。

4.1.1 Kconfig 语法核心

一个典型的Kconfig条目包含类型、提示、依赖和选择逻辑。以下是在全志T113上常见的驱动配置示例:

config SUNXI_GPIO
    tristate "Allwinner Sunxi GPIO support"
    depends on ARCH_SUNXI
    default y
    help
      Say Y here to support GPIO on Allwinner Sunxi SoCs.
      This driver is required for GPIO control on T113.
关键字 含义 常见取值
tristate 三态选项(编译进内核/编译为模块/不编译) tristate, bool, int, string
depends on 依赖条件,条件不满足时选项不可见 ARCH_SUNXI, OF, GPIO
select 反向选择,选中当前项时自动选中另一项 select GPIOLIB
default 默认值 y, n, m
help 帮助文本,在menuconfig中显示 描述驱动功能
版本差异提示: 在Linux 5.4及以上版本中,Kconfig引入了imply关键字,它比select更温和,允许被依赖项仍可被用户手动关闭。全志T113在移植较新内核时,建议优先使用imply代替部分select,以减少配置冲突。

4.1.2 Kconfig 层级结构

内核源码树中的Kconfig文件按目录层级组织,顶层Kconfig通过source语句包含子目录的Kconfig。全志T113的驱动通常位于drivers/下的子目录中。

Kconfig 层级结构(全志T113视角) 顶层 Kconfig arch/arm/Kconfig arch/arm/mach-sunxi/Kconfig drivers/gpio/Kconfig drivers/pinctrl/Kconfig drivers/mmc/host/Kconfig source "drivers/gpio/Kconfig" 每个子目录通过 source 语句被父级包含

4.2 Makefile 驱动编译框架

内核的Makefile系统负责将Kconfig中配置的选项编译成目标文件。驱动开发者需要理解obj-$(CONFIG_*)机制,才能正确地将自己的驱动加入编译。

4.2.1 驱动Makefile基本模式

在驱动目录(如drivers/gpio/)下的Makefile中,通常采用以下模式:

# 单文件驱动
obj-$(CONFIG_GPIO_SUNXI) += gpio-sunxi.o

# 多文件驱动
obj-$(CONFIG_SUNXI_PINCTRL) += sunxi-pinctrl.o
sunxi-pinctrl-objs := pinctrl-sunxi.o pinctrl-sunxi-t113.o
Makefile 变量 含义 示例
obj-y 无条件编译进内核 obj-y += core.o
obj-m 编译为可加载模块 obj-m += mydrv.o
obj-$(CONFIG_XXX) 根据配置决定编译方式 obj-$(CONFIG_SUNXI_GPIO) += gpio-sunxi.o
xxx-objs 多文件驱动时指定目标文件列表 sunxi-pinctrl-objs := a.o b.o
ccflags-y 附加编译标志 ccflags-y += -DDEBUG
版本迁移注意: 在Linux 4.19之前,部分全志平台驱动使用obj-$(CONFIG_ARCH_SUNXI)作为条件。从5.4开始,推荐使用更细粒度的CONFIG_SUNXI_XXX。移植驱动时,务必检查目标内核的Makefile风格,避免条件变量不匹配导致驱动未被编译。

4.3 defconfig 默认配置文件

defconfig是芯片厂商或开发板厂商提供的默认内核配置,它包含了使能特定SoC和板级外设所需的最小配置集。全志T113的defconfig文件位于内核源码的arch/arm/configs/或arch/arm64/configs/目录下。

4.3.1 全志T113常见defconfig

配置文件名称 适用场景 内核版本示例
sunxi_defconfig 全志通用32位平台 Linux 4.9 / 5.4
t113_defconfig T113专用配置(部分厂商提供) Linux 5.10 / 6.1
sunxi_arm64_defconfig 全志64位平台(T113使用) Linux 5.10+

4.3.2 defconfig 使用流程

  1. 加载默认配置: make ARCH=arm sunxi_defconfig
  2. 基于默认配置调整: make ARCH=arm menuconfig
  3. 保存新配置: make ARCH=arm savedefconfig(生成精简版defconfig)
  4. 备份配置: 将生成的defconfig文件复制到arch/arm/configs/my_t113_defconfig
最佳实践: 在全志T113驱动移植中,建议始终从官方提供的defconfig开始,然后通过menuconfig增量添加所需驱动配置。不要手动编辑.config文件,以免引入依赖不一致问题。

4.4 menuconfig 图形化配置

menuconfig是基于ncurses的终端图形化配置工具,是内核配置最常用的交互方式。它直观地展示了Kconfig定义的选项树,并自动处理依赖关系。

4.4.1 menuconfig 操作指南

按键 功能
↑ ↓ 上下移动光标
Enter 进入子菜单 / 确认选择
Space 切换选项状态(Y / N / M)
/ 搜索配置项(支持通配符)
Z 显示所有选项(包括被依赖隐藏的)
? 查看选项的帮助信息

4.4.2 在全志T113上快速定位驱动

在menuconfig界面中,按/键进入搜索模式,输入驱动名称或关键词即可快速定位。例如搜索SUNXI_GPIO:

Symbol: SUNXI_GPIO [=y]
Type  : tristate
Defined at drivers/gpio/Kconfig:123
  Prompt: Allwinner Sunxi GPIO support
  Depends on: ARCH_SUNXI [=y] && GPIOLIB [=y]
  Location:
    -> Device Drivers
      -> GPIO Support (GPIOLIB [=y])
        -> Memory mapped GPIO drivers
menuconfig 配置流程(全志T113驱动使能) 加载 defconfig make menuconfig 搜索驱动 (/) 使能驱动 (Y/M) 保存退出 关键检查点 • 依赖项是否已选 • 是否与现有驱动冲突 • 选择 Y 还是 M • 检查 help 中的说明

4.5 内核编译完整流程

从源码到可启动的内核镜像,全志T113的编译流程遵循标准Linux内核构建步骤,但需注意架构和工具链的指定。

4.5.1 编译步骤详解

# 1. 设置环境变量(交叉编译工具链)
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-

# 2. 清理旧配置和编译产物
make distclean

# 3. 加载默认配置
make sunxi_defconfig

# 4. 自定义配置(可选)
make menuconfig

# 5. 编译内核镜像和设备树
make -j$(nproc) zImage dtbs

# 6. 编译内核模块(如果有)
make -j$(nproc) modules

# 7. 安装模块到目标根文件系统
make INSTALL_MOD_PATH=/path/to/rootfs modules_install

4.5.2 编译产物说明

产物文件 路径 说明
zImage arch/arm/boot/zImage 压缩后的内核镜像,T113常用格式
*.dtb arch/arm/boot/dts/ 编译后的设备树二进制文件
vmlinux 源码根目录 未压缩的ELF格式内核,用于调试
System.map 源码根目录 内核符号表,用于地址解析
.config 源码根目录 当前使用的内核配置

4.5.3 编译流程可视化

全志T113内核编译完整流程 内核源码 + Kconfig 配置阶段 (menuconfig) 生成 .config 编译阶段 (make) zImage (内核镜像) *.dtb (设备树) .ko (内核模块) 部署到启动分区 / 根文件系统 T113 启动要求:zImage + sunxi-t113.dtb + 根文件系统 模块 .ko 需放入根文件系统的 /lib/modules/ 目录

4.6 不同内核版本的配置差异

在全志T113驱动移植过程中,不同内核版本在配置和编译方面存在以下关键差异:

对比项 Linux 4.9 Linux 5.10 Linux 6.1
设备树目录 arch/arm/boot/dts/ arch/arm/boot/dts/ arch/arm/boot/dts/allwinner/
Kconfig依赖检查 较宽松 引入imply关键字 更严格的depends on检查
编译输出 默认zImage 支持Image.gz(ARM64) 默认Image(ARM64)
模块签名 可选 默认关闭 部分架构默认开启
GCC版本要求 GCC 5.x+ GCC 7.x+ GCC 10.x+
关键提醒: 当从Linux 4.9向5.10或6.1迁移全志T113驱动时,设备树文件的路径变化是常见陷阱。务必检查arch/arm/boot/dts/下是否包含sunxi-t113.dtsi,以及Makefile中是否注册了对应的.dtb目标。

4.7 本章小结