第1章:Linux内核源码结构

大家好,欢迎来到《嵌入式Linux驱动开发入门宝典》的第一章。今天咱们聊聊Linux内核源码的结构。说实话,我刚接触内核那会儿,面对几万个文件,心里也是发怵的。但别担心,摸清门道之后,你会发现内核的架构其实非常清晰。

1.1 获取内核源码

要学驱动开发,第一步当然是拿到内核源码。我个人习惯从 kernel.org 下载官方版本。为什么?因为干净、可靠。你想想看,如果从第三方网站下载,万一被人动了手脚,那调试起来可就麻烦了。

下载命令很简单:

wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.tar.xz
tar -xf linux-6.1.tar.xz
cd linux-6.1

嗯,这里要注意:版本号的选择。我建议初学者选长期支持版(LTS),比如6.1或5.15。我在项目中遇到过,用太新的内核,某些驱动还没跟上,反而给自己挖坑。

小提示: 如果你用的是嵌入式开发板,厂商通常会提供修改过的内核源码。这时候别急着用主线内核,先拿厂商的版本跑起来再说。

1.2 内核目录结构分析

解压完内核,咱们来看看它的目录结构。说白了,内核的顶层目录就像一个大公司的部门划分,各司其职。

目录 作用
arch/ 架构相关代码,比如arm、x86、riscv
drivers/ 设备驱动,这是咱们最常打交道的目录
fs/ 文件系统实现,ext4、vfat都在这里
include/ 头文件,内核API的声明
kernel/ 核心子系统,调度、进程管理
mm/ 内存管理
net/ 网络协议栈
scripts/ 编译和配置脚本

我记得第一次看drivers目录时,差点被吓到——里面有好几百个子目录!但别慌,咱们做嵌入式驱动,重点关注这几个:

  • drivers/i2c/:I2C总线驱动
  • drivers/spi/:SPI总线驱动
  • drivers/gpio/:GPIO驱动
  • drivers/misc/:杂项设备,放一些不好归类的驱动
核心观点: 内核源码虽然庞大,但80%的驱动开发工作只集中在drivers/目录下的几个子目录里。别被吓到,咱们一步步来。

1.3 Kconfig与Makefile基础

好,现在咱们聊聊Kconfig和Makefile。这两个文件是内核的"骨架"和"血脉"。Kconfig负责配置选项,Makefile负责编译规则。

先看一个简单的Kconfig例子:

config MY_DRIVER
    tristate "My Custom Driver"
    depends on I2C
    help
      This is a custom driver for my embedded device.
      Say Y here to enable it.

这里tristate表示三种状态:Y(编译进内核)、M(编译成模块)、N(不编译)。我在项目中遇到过,新手经常搞混Y和M的区别。简单说:如果你的驱动是系统启动必须的,选Y;如果是可插拔的设备,选M。

再看对应的Makefile:

obj-$(CONFIG_MY_DRIVER) += my_driver.o

这行代码的意思是:如果CONFIG_MY_DRIVER被配置为Y或M,就编译my_driver.c。嗯,就这么简单。

避坑指南: 我曾经因为Makefile里少写了一个.o后缀,结果编译出来的模块死活加载不上。检查了整整两个小时才发现问题。所以,写Makefile时一定要仔细核对文件名。

1.4 内核配置与编译

配置内核,说白了就是告诉内核:你要支持哪些功能,不要哪些功能。常用的配置命令有:

  • make menuconfig:基于ncurses的图形界面,我最常用
  • make defconfig:使用默认配置
  • make oldconfig:基于现有配置更新

我个人习惯用menuconfig,因为它直观。你想想看,在终端里上下翻找选项,比直接改文本文件舒服多了。

配置完成后,编译命令也很直接:

make -j4
make modules
make modules_install

-j4表示用4个线程并行编译,能快不少。不过要注意,如果你的电脑内存不大,别把数字设太大,否则容易卡死。

小技巧: 编译内核时,建议先执行 make mrproper 清理一下旧的编译产物。我曾经因为没清理,导致新配置没生效,白白浪费了半天时间。

最后,编译好的内核镜像通常在 arch/arm/boot/arch/x86/boot/ 目录下,叫zImage或bzImage。模块则安装在 /lib/modules/ 目录下。

好了,第一章的内容就到这里。下一章咱们会深入讲解字符设备驱动的编写,到时候见!


公众号:蓝海资料掘金营,微信deep3321