1、驱动分类:
字符设备驱动:硬件读写以字节为单位;串口、
块设备驱动:以块为单位;硬盘(一个扇区512bit)
网络设备驱动:内核协议栈内存;网卡驱动、can驱动等;
2、动态加载M和静态加载Y(编译选项):
区别:
1)编译选项不同:Y为内核,M为驱动;
2)存在位置不同:Y在内核镜像(uImage)里,M在文件系统上;
3)加载时机不同:静态加载随内核启动而启动,动态加载待文件系统启动完成后手动用命令启动;
系统启动顺序:uboot ——> 内核 ——> 文件系统
动态加载的优势:
1)系统支持热插拔,则需先实现动态加载;
2)驱动调试时,只编译驱动,手动命令测试;
3)驱动的启动位于用户图形界面启动之后,用户会感觉系统启动速度加快。
一、概念和结构体:
设备号 + 设备信息描述 + 设备行为描述(callback函数) + 相关函数注册
二、源码分析:
1、驱动加载函数:module_init();
devNum —— 设备号,reg_major——主设备号,reg_minor——次设备号;
MKDEV —— 将ma向左偏移20再 或 mi,即根据主次设备号生成一个唯一的“标识符”
MAJOR(dev) —— 设备号右偏移20位,得到主设备号;
MINOR(dev) —— 得到次设备号;
在内核中定义,在驱动中使用
printk 打印结果,有打印级别限制,
register_chrdev_region() —— 注册设备号
kzalloc / kmalloc —— 申请的内核空间的内容全部清零
gDev —— 申请字符设备的信息结构体
gFile —— 申请字符设备的行为结构体
GFP_KERNEL —— 在内核中申请内存并使用
给open、read、write三个值赋等式右边的值
清零、初始化链表、赋值(建立设备信息和设备行为之间的联系)
把字符设备注册到内核当中。
三、驱动测试以及makefile:
1、驱动测试:
dmesg —— 打印出来charDrvInit()中printk函数的信息。
测试程序:
编译测试程序并执行,返回打开失败;
使用mknod手动创建文件,其中c代表字符设备文件(b为块设备),主设备号232,次设备号0
2、makefile文件:
判断变量是否定义:
若未定义:
PWD — 赋值文件原目录,KDIR — 内核源码目录,all — 编译、change(-C)到内核源码目录去编译M指定的驱动文件;
若定义:obj-m 将.o文件编译成驱动文件;最后在编译成.ko文件。