最近,终于有时间开始学习写Linux的驱动了。
我的第一个驱动程序,其实基本上都是抄的,只是结合自己的理解把它们都拼起来。
参考资料:《Linux设备驱动程序(第三版)》(Linux Device Driver, LDD)
首先,对于Linux的设备,在系统中,它的表示也是一个文件,只不过比较特殊而已,如下图:
而驱动,就是对这样的特殊文件的功能进行定义,就像普通文件的open、close等等,那当用户对设备进行open、close的时候应该怎么处理?这就是内核的作用了。
对于一个驱动程序,在系统中就是一个模块,所以要让模块能进入到系统中工作,就要在安装模块的时候做点事情。
1、申请这个驱动对应的设备号
2、注册设备
对于字符设备,就是告诉系统,要添加编号为某某的设备,这里有一个重要的结构体就是cdev了。
有安装就有卸载。
所以最后第一部分程序是这样的:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef __MODULE__
#define __MODULE__
#endif
#include "scull_driver.h" //local define
int scull_major = SCULL_MAJOR;
int scull_minor = SCULL_MINOR;
int scull_nr_devs = SCULL_NR_DEVS;
int scull_quantum = SCULL_QUANTUM;
int scull_qset = SCULL_QSET;
module_param(scull_major, int, S_IRUGO); /*模块参数,可以在安装模块时指定*/
module_param(scull_minor, int, S_IRUGO);
module_param(scull_nr_devs, int, S_IRUGO);
module_param(scull_quantum, int, S_IRUGO);
module_param(scull_qset, int, S_IRUGO);
pSCULL_DEV pdev = NULL;
static int scull_trim ( pSCULL_DEV pdev )
{
pSCULL_QSET next;
pSCULL_QSET dptr;
int qset = pdev->qset;
int i;
for ( dptr = pdev->data; dptr; dptr = next )
{
if ( dptr->data )
{
for ( i = 0; i < qset; i++ )
kfree ( dptr->data[i] );
kfree ( dptr->data );
dptr->data = NULL;
}
next = dptr->next;
kfree ( dptr );
}
pdev->size = 0;
pdev->quantum = scull_quantum;
pdev->qset = scull_qset;
pdev->data = NULL;
return 0;
}
static void cleanup_scull ( void )
{
int i;
dev_t devno = MKDEV ( scull_major, scull_minor );
if ( pdev )
{