理解scull设备

    技术2025-11-01  19

    scull设备是一个操作内存的字符设备,不是真正的设备,只是向内核注册为字符设备,并使用内存来存取数据。当用户向其中写数据时,它就申请空闲内存来存放用户数据;当用户读取其数据时,便按顺序读取数据。接下来两个结构贯穿整个驱动,理解它是很必要的。struct scull_qset {void **data;struct scull_qset *next; };struct scull_dev {struct scull_qset *data; int quantum;  int qset;  unsigned long size;  unsigned int access_key; struct semaphore sem;  struct cdev cdev;};当申请内存空间时,不大可能一次完全申请需要的空间,只有需要(用户写)的时候才去申请内存,这就存在零散的内存区域,也需要管理这些零散的区域。故此,出现了上述的结构来来维护之!struct scull_qset 量子集结构所谓量子就是每次申请分配内存的最小单位,量子集就是这些最小单位的集合。(作者这么设计的,不是内核的概念)void **data 这是个二重指针,表明它指向的单元存放的是一个指针,这个指针指向的地址才存放着真正的数据(量子)。struct scull_qset *next 指向下一个量子集。这个量子集是多大呢,通过这两个成员无法判断这个集合究竟多大。这是scull_dev来维护的。struct scull_dev scull设备结构,维护该设备的所有数据struct scull_qset *data,它指向第一个量子集。quantum 量子大小。所有量子大小相同,只需这里维护。如果说每个量子集中量子大小不一致,那就需要把这个成员下移到量子集管理结构中。qset 量子集大小,表明量子集中量子个数。同上面的理由一样,scull设备被设计为它的所有量子集大小一致。size 设备中保存的数据量。access_key  /* used by sculluid and scullpriv */ 未见使用sem 互斥量,互斥量经常使用于存在可能同时访问共享资源的情况下。cdev 注册字符设备就要靠它了。把它集成在cull_dev是相当有用的。看cull_open函数(用户open时)中,dev = container_of(inode->i_cdev, struct scull_dev, cdev); 这样可方便地从cdev得到cull_dev,有时也把它设置为全局变量,但是这并不够灵活。在后面的驱动程序会体会到这种做法的好处。

    最新回复(0)