第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/:杂项设备,放一些不好归类的驱动
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。嗯,就这么简单。
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