分享

教你写第一个Linux设备驱动程序

 copy_left 2020-04-11

首先说明:写这个第一个Linux设备驱动程序的目的是熟悉Linux驱动的框架以及编程流程,所以是通过打印的信息来观察程序运行的情况,并不是真正的实现了某一个具体设备的驱动,可以类比于C语言编程中的“Hello World”。

Linux下的设备驱动架构如下图所示:

教你写第一个Linux设备驱动程序

在本篇文章中以first_device_driver为例进行介绍

一般来说,写出完整的设备驱动程序需要如下几个步骤:

  1. 写出first_drv_open、first_drv_write、first_drv_read和first_drv_ioctl等函数;
  2. 定义file_operations结构体并填充其成员函数first_drv_open、first_drv_write、first_drv_read和first_drv_ioctl等;
  3. 模块加载函数,通过register_chrdev将字符设备注册到内核中;
  4. 写驱动的入口函数;
  5. 写驱动的出口函数;
  6. 通过module_init()来修饰驱动入口函数;
  7. 通过module_exit()来修饰驱动出口函数;
  8. 声明模块许可证;

下面进行详细讲解

步骤一:在新创建的.c文件中编写如图例中的代码

教你写第一个Linux设备驱动程序

教你写第一个Linux设备驱动程序

步骤二:编写Makefile脚本

教你写第一个Linux设备驱动程序

值得提出的一点是,编写Makefile是Linux驱动工程师必备的基础,但是要明白我们并不需要完全的掌握Makefile的语法及编程,我们只需要能模仿着其他工程的Makefile文件写出我们自己想要的Makefile文件即可。

步骤三:在对应目录中执行make命令,生成.ko模块文件

这一步骤较为简单,只是在相应目录输入make命令即可。

步骤四:通过U盘或者nfs网络文件系统将该.ko文件加载到内核中

我们在加载驱动模块之前可以先通过命令:cat /proc/devices来查看字符主设备号是否已经被占用。proc文件系统是Linux在运行时存在于内存中的文件系统,它记录着系统运行的实时信息,当关闭系统时,proc文件系统也随之释放。

然后可通过命令:insmod first_drv.ko将模块挂载到内核, 通过命令:cat /proc/devices可以观察first_drv设备是否已经挂载成功;另外也可以通过modprobe来加载驱动模块,这两者的区别在于modprobe可以解决加载模块时的依赖关系,它是通过/lib/modules/#uname -r/modules.dep(.bb)文件来查找依赖关系的,而insmod不能解决模块间的依赖问题。

步骤五:创建dev/first_driver设备节点

通过命令:mknod /dev/first_driver 100 0 来创建设备节点。

步骤六:编写应用程序进行测试

测试的应用程序如下:

教你写第一个Linux设备驱动程序

在这里我们可以发现测试程序里的open()函数实际就是调用了驱动中的first_drv_open()函数,而write()函数实际调用了驱动中的first_drv_write()函数。本质上是这样的一个执行过程:用户空间的open()函数->文件系统的sys_open()函数->驱动的first_drv_open()函数。

另外很重要的一点,上文中图例中的程序是需要手动创建设备节点,从而提供给用户程序访问的,如此一来当驱动模块较多的时候就很麻烦,所以Linux也提供自动创建设备节点的接口,建议使用自动创建设备节点的机制。如下是自动创建设备节点的方法:

1、首先创建一个class设备类,然后在class类下,创建一个class_device,即在类下面创建类的设备;

2、在驱动入口函数中添加步骤:firstdrv_class= class_create(THIS_MODULE,'first_drv');irstdrv_class_devs=class_device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,'first_drv');

3、在驱动出口函数中添加:class_device_unregister(firstdrv_class_devs);class_destroy(firstdrv_class);

这个自动创建设备节点的功能是基于Linux支持的热拔插功能,Linux内核中每当设备出现变动时,都会处理对应的信息,使用户程序对/dev目录下的设备进行操作。

最后,此驱动程序运行的实际效果就是打印信息,这个Linux设备驱动例程可以类比于C语言中的“Hello World”例程,希望可以帮助大家初步认识Linux的设备驱动程序。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多