1 基本要求及如何学习
1.1 基本技能与背景知识要求
- C 语言基础:Linux 内核大部分由 C 语言编写,C 语言是驱动开发的必备知识。
- 硬件背景:需能看懂硬件原理图,理解驱动开发涉及的硬件相关内容。
- 动手实践能力:需具备实操、调试的动手能力。
- 单片机基础(非必须):有单片机开发经验会更有助于学习驱动开发。
- 抗压与毅力:需有不怕困难、迎难而上的学习勇气。
- 总结复盘能力:要善于记录、总结学习过程中的问题与经验。
1.2 学习准备:开发板选择要点
- 优先选择源码开源的开发板,便于学习和修改代码。
- 优先选择硬件开源的开发板,方便对照原理图理解硬件与驱动的关系。
- 选择配套学习资料丰富的开发板,降低入门难度。
- 优先选择有技术支持 / 社区活跃的开发板,遇到问题更容易找到解决方案。
- 选择能长期适配学习需求的开发板,避免频繁更换,节省成本。
1.3 核心学习方法
- 按教程顺序循序渐进学习,不要跳学,打好基础再深入。
- 熟练掌握开发基础技能:环境搭建、Shell 命令使用、NFS/SSH 工具使用、开发板的编译与烧写流程。
- 初学者推荐直接使用现成搭建好的开发环境,降低入门门槛。
- 培养独立分析、解决问题的能力,主动排查调试驱动开发中的问题。
RK3568 / ULL
2 什么是Linux驱动
驱动的核心作用是让硬件动起来,它是底层硬件和上层软件之间的桥梁,直接与硬件打交道。
在**无操作系统(裸机)**的场景中,驱动开发直接通过操作寄存器控制硬件,比如单片机控制 LED 灯的程序,无需额外的系统框架。
在Linux 系统中,驱动开发需要遵循系统提供的驱动框架,为应用程序提供统一的调用接口,整体架构为「应用→操作系统→驱动→硬件」。
Linux 系统将驱动分为三类:
- 字符设备:需按串行顺序访问的设备,如鼠标
- 块设备:支持任意顺序访问的存储设备,如硬盘
- 网络设备:面向数据包收发的设备,如网卡
3 初步认识Linux源码
可以在 Linux 官网(https://www.kernel.org/) 下载最新的 Linux 内核源码。
嵌入式开发所使用的源码不是直接在官网下载,而是需要根据芯片硬件适配之后的源码。
Linux 内核源码采用树状多级目录结构,其顶层目录包含多个核心子目录,关键目录及说明如下:

- arch:存放不同 CPU 架构的相关代码(如 arm、x86、MIPS 等)
- block:存放块设备(如硬盘、SD 卡)相关代码
- crypto:存放加密算法相关代码
- Documentation:存放官方内核文档
- drivers:存放 Linux 支持的各类硬件设备驱动源码
- firmware:存放固件文件
- fs:存放文件系统相关代码(如 fat、ext2、ext3 等)
- include:存放公共头文件
- init:存放内核启动初始化代码
- ipc:存放进程间通信相关代码
- kernel:存放内核核心代码
- lib:存放通用库函数
- mm:存放内存管理相关代码(memory management)
- net:存放网络协议栈相关代码(如 TCP/IP)
- scripts:存放编译构建所需的脚本文件
- security:存放安全相关代码
- sound:存放音频相关代码
- tools:存放内核相关工具
- usr:存放与内核启动相关的代码
- virt:存放内核虚拟机相关代码
4 编写第一个驱动Helloworld
一个最简单的 Linux 驱动模块,由以下必须项 和可选项组成:
✅ 必须包含的部分
-
头文件需包含内核相关头文件,核心为:
#include <linux/module.h>:模块加载、卸载相关定义#include <linux/init.h>:模块初始化 / 退出相关定义
-
驱动加载函数 模块被内核加载时自动执行,通常用
__init宏标记。 -
驱动卸载函数 模块被内核卸载时自动执行,通常用
__exit宏标记。 -
许可证声明 需声明驱动遵循的协议,常见为
MODULE_LICENSE("GPL v2"),否则内核加载时会提示警告,甚至影响部分功能使用。
⚙️ 可选部分
- 模块参数模块加载时可传递给内核模块的参数值,用于动态配置驱动行为。
- 作者和版本信息可声明驱动的作者、版本号等信息,方便维护与溯源。
💡 补充说明:这类 "最简驱动" 通常是一个内核模块,它不直接操作硬件,仅完成加载 / 卸载的基本流程,是学习 Linux 驱动开发的入门基础结构。