课程导学与环境准备
说实话,每次带新人入门内核驱动,我都要先问一句:你为什么要学字符设备驱动?
很多人觉得驱动开发高深莫测,其实不然。字符设备驱动,说白了就是内核里最简单的一类驱动。它就像你写的第一行"Hello World"——虽然简单,但五脏俱全。
我个人习惯把字符设备驱动比作内核与用户空间之间的一个管道。应用程序通过这个管道,跟硬件设备打交道。你想想看,键盘、鼠标、串口,这些不都是字符设备吗?
什么是字符设备驱动?
先给个准确定义:字符设备驱动,是指以字节流方式访问设备的驱动程序。数据按顺序读写,没有缓冲区,没有随机访问。
举个例子。你在终端敲键盘,每个按键就是一个字符。驱动收到这个字符,直接传给应用程序。就这么简单。
我在项目中遇到过不少新手,上来就想写块设备驱动。结果被复杂的缓存机制搞得晕头转向。我建议:从字符设备开始,稳扎稳打。
核心特征:
- 数据以字节流方式传输
- 顺序访问,不支持随机定位
- 没有内核缓存层(对比块设备)
- 通过设备文件(/dev/xxx)与用户交互
课程目标与学习路径
这门课的目标很明确:让你亲手写出一个能跑起来的字符设备驱动。不是纸上谈兵,是真正在QEMU虚拟机上加载、测试、验证。
我设计的路径是这样的:
- 环境搭建——先把锅碗瓢盆准备好
- 内核编译——理解内核构建流程
- 驱动框架——掌握file_operations结构体
- 设备号管理——学会申请和释放设备号
- 实现读写——让驱动真正干活
- 测试验证——用应用程序测试驱动
嗯,这里要注意:不要跳步。我见过太多人急着写代码,结果环境没配好,编译都过不了,白白浪费时间。
开发环境搭建
工欲善其事,必先利其器。我们的开发环境是:Ubuntu + QEMU + Busybox。
为什么选这套组合?
- Ubuntu:开发主机,编译内核和驱动
- QEMU:模拟ARM开发板,运行内核
- Busybox:制作根文件系统,提供shell环境
我曾经在真实开发板上调试驱动,每次烧写都要几分钟。后来改用QEMU,编译完直接启动,效率提升了好几倍。所以这次课程,我们全程用QEMU。
安装依赖包
sudo apt-get update
sudo apt-get install build-essential git vim
sudo apt-get install qemu-system-arm
sudo apt-get install gcc-arm-linux-gnueabihf
sudo apt-get install libncurses5-dev bison flex
sudo apt-get install libssl-dev bc
这些包缺一不可。我踩过坑:忘了装libssl-dev,编译内核到一半报错,折腾了半天才发现。
下载内核源码
我们使用Linux 5.10 LTS版本,稳定且文档齐全。
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.210.tar.xz
tar -xf linux-5.10.210.tar.xz
cd linux-5.10.210
配置并编译内核
针对ARM架构,我们使用vexpress开发板配置。
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make vexpress_defconfig
make -j4
编译时间取决于你的机器。我建议第一次编译时,泡杯咖啡,耐心等待。
小技巧:如果编译过程中断,下次执行 make 会从断点继续,不用重新开始。
制作根文件系统
用Busybox制作一个最小根文件系统。
wget https://busybox.net/downloads/busybox-1.36.0.tar.bz2
tar -xf busybox-1.36.0.tar.bz2
cd busybox-1.36.0
make defconfig
make menuconfig # 确保选中 "Build static binary (no shared libs)"
make -j4
make install
安装完成后,在 _install 目录下生成根文件系统。我们需要手动创建一些目录:
cd _install
mkdir -p proc sys dev etc/init.d
touch etc/init.d/rcS
chmod +x etc/init.d/rcS
在 rcS 文件中写入:
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mdev -s
启动QEMU验证
一切就绪后,用以下命令启动:
qemu-system-arm -M vexpress-a9 \
-kernel linux-5.10.210/arch/arm/boot/zImage \
-dtb linux-5.10.210/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
-append "console=ttyAMA0 root=/dev/mmcblk0" \
-sd rootfs.ext3 \
-nographic
如果看到内核启动日志,最后出现 # 提示符,恭喜你,环境搭建成功!
常见问题:
- QEMU启动后黑屏:检查
-nographic参数是否添加 - 内核崩溃:确认dtb文件路径是否正确
- 根文件系统挂载失败:检查rootfs.ext3格式是否正确
知识体系总览
为了让你对整个课程有个全局认识,我画了一张图:
这张图把整个课程串起来了。你跟着这个路径走,每一步都有明确的目标。不会迷路。
避坑指南
最后,分享几个我当年踩过的坑:
- 交叉编译工具链版本不匹配:我曾经用gcc-9编译内核,结果QEMU启动就崩溃。后来换成gcc-7,一切正常。建议使用Ubuntu官方源提供的工具链。
- 根文件系统权限问题:Busybox编译时一定要选静态链接,否则动态库找不到,启动就报错。
- QEMU参数顺序:
-kernel、-dtb、-append的顺序不能乱,否则内核无法正确解析参数。
我的建议:第一次搭建环境时,每一步都做记录。出了问题,回头查记录,比重新搜索快得多。
好了,环境准备就绪。接下来,我们就要真正动手写驱动了。记住:驱动开发不是魔法,是工程。每一步都有章可循。
公众号:蓝海资料掘金营,微信deep3321