Linux驱动开发1.基础创建
Linux驱动开发(1.基础创建)
序言:从高层逻辑到底层硬件的回归
在当今的软件开发中,我们习惯于用高级语言构建抽象层——通过框架、库和云服务快速实现功能。这种“软逻辑”的便利性让开发效率倍增,却也逐渐模糊了我们对计算机本质的认知:一切代码终将落地为硬件行为 。 Bjarne Stroustrup(C++之父)曾言:“The Web is a flea on the tail of the dog called IT.”(万维网不过是信息技术狗尾巴上的一只跳蚤)。这句话深刻揭示了技术表象与底层根基的关系。 回想DOS时代,从盘符加载到命令执行,每一步都直击硬件本质;而如今的一键开机背后,是无数硬件信号、固件协议和驱动程序的精密协作。理解底层,不是为了复古,而是为了在高层抽象失效时,仍能掌控全局 。
设备驱动程序——连接软硬件的桥梁
1.1 什么是设备驱动?
设备驱动是操作系统的“硬件翻译官”,它完成两件事:
- 机制(Mechanism) :将硬件操作(如寄存器读写、中断处理)封装为统一接口。
- 策略(Policy) :由上层决定如何使用这些接口(如权限管理、数据调度)。 示例 :
- 键盘驱动(机制)提供按键扫描码,窗口管理器(策略)决定如何响应快捷键(如Ctrl+C)。
- GPU驱动(机制)实现图形渲染,桌面环境(策略)管理窗口布局。
1.2 为什么需要学习驱动开发?
- 突破技术黑箱 :理解从代码到硬件的完整链路(如
printf
如何点亮屏幕像素)。 - 解决实际问题 :定制硬件支持(如为嵌入式设备编写专用驱动)。
- 职业竞争力 :内核开发、IoT、自动驾驶等领域对底层能力要求极高。
1.3 设备驱动的分类
类型 | 特点 | 典型设备 | 用户接口示例 |
---|---|---|---|
字符设备 | 按字节流访问,支持read() /write() | 键盘、串口 | /dev/ttyS0 |
块设备 | 按数据块访问,用于存储设备 | 硬盘、SSD | /dev/sda |
网络接口 | 处理数据包,无文件节点 | 网卡、虚拟隧道 | eth0 、wlan0 |
1.4 从零编写一个驱动模块
代码示例:最简单的内核模块 #include #include // 模块加载时执行 static int __init my_driver_init(void) { printk(KERN_INFO “Driver loaded: Hello, Kernel!\n”); // 内核日志输出 return 0; } // 模块卸载时执行 static void __exit my_driver_exit(void) { printk(KERN_INFO “Driver unloaded: Goodbye, Kernel!\n”); } // 注册模块入口/出口 module_init(my_driver_init); module_exit(my_driver_exit); // 模块元信息 MODULE_LICENSE(“GPL”); // 开源协议 MODULE_AUTHOR(“Your Name”); // 作者 MODULE_DESCRIPTION(“A Minimal Driver”); // 描述 操作步骤 :
- 使用vim创建一个my_driver.c文件
- 编写
Makefile
: obj-m += my_driver.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean - 编译并加载模块: make # 编译 sudo insmod my_driver.ko # 加载模块 dmesg | tail -n 2 # 查看内核日志输出 sudo rmmod my_driver # 卸载模块 当加载模块后通过dmesg可以看见我们驱动运行时打印的信息 。 现在自己也在学习Linux驱动开发中也欢迎各位同学和大佬跟我交流~