Scull字符设备驱动模块的内存使用分析

先看一下每个scull_dev的数据结构的定义:

struct scull_qset {
 void **data;
 struct scull_qset *next;
};

struct scull_dev {
 struct scull_qset *data;                       /* Pointer to first quantum set */
 int quantum;                                          /* the current quantum size */
 int qset;                                                   /* the current array size */
 unsigned long size;                              /* amount of data stored here */
 unsigned int access_key;                   /* used by sculluid and scullpriv */
 struct semaphore sem;                       /* mutual exclusion semaphore     */
 struct cdev cdev;                                    /* Char device structure  */
};

每个scull设备都有一个数据指针,每个指针都指向下一个scull_qset数据结构。每个内存区成为一个量子quantum,这个指针数组即它的长度成为量子集qset,这个两个值可以在scull.h定义初始值,也可以通过ioctl函数自定义其大小,在此例子的源码中每个scull_qset的data里定义了1000个指针(qset)的数组,每个指针都指向一个4000字节的区域(quantum)。

这个内存使用图在《linux驱动程序》上作了说明,可以比较一下第三版和第二版对这个图解释的区别,以下我的应用的程序都是针对第三版发布的源代码。

我们要对这个内存作读取访问,首先传到内核空间的是一个loff_t *offp指针,表示用户对这个文件的读或写操作的位置。首先可以通过这个offp可以获取一个信息,这个loff_t *offp指针指在哪个struct scull_qset上,看源码,在ssize_t scull_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos):

..........................................

/* find listitem, qset index, and offset in the quantum */
 item = (long)*f_pos / itemsize;
 rest = (long)*f_pos % itemsize;
 s_pos = rest / quantum; q_pos = rest % quantum;

 /* follow the list up to the right position (defined elsewhere) */
 dptr = scull_follow(dev, item);

通过scull_follow()函数定位offp指针所在的scull_qset,而在读取数据的时候是针对某一块内存quantum来读取;

item = (long)*f_pos / itemsize:数据在链表的哪个scull_qset里面?

rest = (long)*f_pos % itemsize:在这个scull_qset里面数据偏移量为多少?

s_pos = rest / quantum:在这个scull_qset里面的哪一个quantum?

q_pos = rest % quantum:在这个quantum里面偏移量多少?

指针loff_t *f_pos成功定位!

if (copy_to_user(buf, dptr->data[s_pos] + q_pos, count)),内核数据到用户空间的拷贝,成功之后更新偏移指针:*f_pos += count。

下篇文章就介绍对scull源码的简单移植,并提供所有源码 ,赫赫,今天先到这里,休息休息......

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值