Linux设备驱动都是以内核模块的形式出现的,但模块不一定是驱动。驱动可以编译进内核,在配置内核时,如果把某个配置项设为m,那么它将会随着内核编译时被编译成一个模块,但是这样向内核添加驱动程序会使得内核变得很大,而且在增加、修改、删除驱动程序时需要再一次编译内核,这样做极为麻烦。所以一般的驱动程序都是采用模块化装载,在需要使用时候通过insmod装载进内核,不需要使用时用rmmod卸载驱动模块。

    内核模块的主要相关命令:

  1. lsmod:查看当前内核装载有哪些模块

  2. insmod:加载模块

  3. rmmod:卸载模块

  4. modinfo:查看模块信息

    驱动是内核的一部分,写驱动程序时要遵循一定的内核开发规则,一般写一个驱动程序由一下几步骤:

  1. 查看原理图,了解设备的操作方法

  2. 在内核中查找相似的开发程序,仿造其格式和用法,实在没有就要从头开始

  3. 实现驱动程序的初始化

  4. 实现应用程序接口的对应操作函数

  5. 编译加载程序

  6. 测试

    驱动程序编写的基本框架都是差不多的,都是为系统调用实现想对应的函数,并在函数中实现相对应的功能,以一个简单的led驱动为例,根据字符设备中核心的数据结构file_operations结构(在内核中搜索),这个结构体中的成员函数是字符设备驱动程序设计的主要内容,这些函数实际在应用程序Linux中使用open()、read()、write...等系统调用时最终被调用。Linux设备驱动基本框架(字符设备)_第1张图片

根据这个结构体以及实际应用程序的需求在驱动程序中实现相对应的函数

Linux设备驱动基本框架(字符设备)_第2张图片

以上是一个基本的驱动框架,首先在使用insmod mydev.ko挂载驱动程序时,执行:module_init->my_init完成初始化工作,在卸载时rmmod mydev.ko->module_exit->my_exit完成清理工作(关闭设备等等)。驱动程序装载成功后,应用程序对对应的设备文件使用open、read等系统调用时就会调用到驱动程序的my_open、my_read,一一对应。最后MODULE_LICENSE("GPL");是声明本程的许可证声明,防止内核污染。