字符设备驱动一 - wawzzll - 博客园Linux 字符设备驱动开发基础(六)—— VFS 虚拟文件系统解析_知秋一叶-CSDN博客_vfs 文件系统字符设备驱动一 - wawzzll - 博客园
大神都讲得很清楚,俺根据自己的记忆写写加深印象
linux1.6下的字符设备驱动编写方式比较旧,基本已经不被推荐使用。但是比新的驱动方式简单,容易被理解,新的字符设备编写方式也是继承旧的方式。可能有助于加深理解。
字符设备:只能一个字节一个字节的读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序进行。字符设备是面向流的设备,常见的字符设备如鼠标、键盘、串口、控制台、LED等。
应用层不能直接访问内核层也不会理会低层硬件如何,只管调用open()、read()、write()等函数实现自己的需求。
open()、read()、write()等函数在VFS都有对应的sysopen()、sysread()、syswrite()等函数对应,如当应用层调用open()函数时,通过VFS的sysopen()就会去进入内核层里调用相关驱动的open()函数,从而打开驱动,其他的read()、write()函数也类似的方式,在open()打开了驱动函数后操作驱动函数,从而驱动硬件。
字符设备框架内有一个file_operation结构体,该结构体提供用于实现驱动的 _open, _read, _write 等函数的函数指针,VFS可以调用。定义需要的file_operation结构体并填充好即可对硬件的操作。
如何确定某个file_operation结构体就是要找的那个?通过主设备号。使用register_chrdev()把file_operation结构体时,会把给它分配的主设备号注册进内核,而且是一个字符设备驱动类型。上层通过字符设备类型和主设备号找到这个结构体。
如何让内核使用register_chrdev()函数注册,通过module_init()函数,这是一个修饰的宏,是该驱动的入口,需要把初始化函数填进去。
有入口自然要有出口module_exit(),在该宏填充的函数内把注册声明的一切东西都要去掉
还要加上协议MODULE_LICENSE("GPL");
第一步:构造file_operation结构体,并填充里面的open()等函数指针
第二步:在初始化函数中使用register_chrdev()函数把结构体注册进内核
第三步:使用module_init(); 作为入口
第四步:出口的宏
第五步:退出函数要对所有资源释放
其他:
1.内核空间不能直接使用物理地址,需要把物理地址映射到内核,ioremap()函数
2.用户空间的值不能直接与内核空间互通,可以使用copy_from_user()以及copy_to_user()
3.MKDEV()函数
4.自动创建设备节点
xx_class=class_create(THIS_MODULE, "xxdev")这个函数会自动的在(/sys/class)目录下创建一个(xxdev)类,名字不重要。
led_chrdev_class_dev=class_device_create(xx_class, NULL, MKDEV(major, 0), NULL, "xyz")这个函数会自动的在(/sys/class/ledchrdev)目录下创建一个(xyz)设备,并且该文件夹下有一个(dev)文件保存有该设备的主设备号和次设备号 ,名字不重要。