读书笔记(2)

来源:互联网 发布:php oa办公系统源代码 编辑:程序博客网 时间:2024/05/17 23:14

6. 字符设备驱动:

  cdev结构体——P119

  MKDEV(int major, int minor) 通过这个宏可以将主设备号和次设备号生成dev_t

      一些用来操作cdev结构体的函数:

      cdev_init(),它用来初始化cdev的成员,并且建立cdev和file_operations之间的连接, void cdev_init(struct cdev *cdev, struct file_operations *fops)

      cdev_alloc()函数用于动态申请一个cdev内存,TA的实现中用到了kzalloc函数

     cdev_add()和cdev_del()函数分别向系统添加和删除一个cdev,完成字符设备的注册和注销,他们通常在模块的加载和卸载中  

  分配和释放设备号

      register_chrdev_region(dev_t from, unsigned count, const char * name)

      alloc_chrdev_region(dev_t *dev,unsigned baseminor, unsigned count, const char  * name)

      unregister_chrdev_region(dev_t from, unsigned count)

      由于内核空间和用户空间的内存不能直接互访,要借助于copy_from_user()完成用户空间到内核空间的拷贝,copy_from_user完成内核空间到用户空间的拷贝,如果要复制的仅仅是简单的类型的话,比如char,int,可以简单的put_user和get_user,如get_user(val,(int *)arg) arg为用户空间的地址,put_user(val,(int *) arg)内核到用户,arg是用户空间的地址。具体copy的用法在P127有,实例化了内核空间指针,用户空间什么的。

      在驱动中用到比如globalmem_setup_cdev(),它用于完成cdev的初始化和添加,具体函数在——P126

 file_operations中的seek()函数,用于文件的定位的,返回定位后的地址。

ioctl()函数是一个很好的操作方法,它可以做出了读写之外其他的事情,通常ioctl命令有着建议的组成格式——P129,像_IO(),_IOC()等也就是一种命名方式,它们仅仅是对ioctl控制命令中的设备类型,序列号,方向,数据尺寸进行给值移位。

在文件操作中,一个潜规则是:将文件的私有数据private_data指向自建的设备结构体,然后file_operations通过这个private_data来访问设备结构体。不过若仅仅是一个设备在用的话,还不如直接用该设备结构体的指针,没必要引出private_data的概念,但是如果如果涉及到两个以上的设备的时候,private_data的优势就会显示出来了。

其中和container_of()配合使用。如dev=container_of(inode->i_cdev, struct globalmem_dev, cdev); flip->private_data=dev;

 container_of - cast a member of a structure out to the containing structure

 @ptr:        the pointer to the member

 @type:       the type of the container struct this is embedded in

 @member:     the name of the member within the struct

#define container_of(ptr,type, member) ({  const typeof( ((type *)0)->member ) *__mptr = (ptr);   (type *)( (char *)__mptr - offsetof(type,member) );}) //据我对这句话的理解,它是通过计算type和member之间的地址差值,来算出所要求的结构体的地址位置。

如果启用了sysfs文件系统,将会防线多了一个/sys/module/globalmem目录,其中refcnt记录引用次数,sections下记录BSS,数据段和代码段等地址。

总结:

字符设备的驱动程序中,完成的主要工作就是初始化,添加,删除cdev结构体,申请和释放设备号,以及填充file_operations结构体的操作函数,实现file_operations结构体的read(),write()。ioctl()等函数是驱动设计的主要工作。

原创粉丝点击