Chinaunix首页 | 论坛 | 博客
  • 博客访问: 116163
  • 博文数量: 50
  • 博客积分: 2495
  • 博客等级: 大尉
  • 技术积分: 535
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-04 11:44
文章分类
文章存档

2011年(20)

2010年(30)

我的朋友

分类: LINUX

2010-09-30 15:06:29

scull pipe device driver note
Learner: 山涛
Date: 2007-7-4
设备类型:
字符设备
 
SCULLSimple Character Utility for Loading Localities
SCULL驱动模块操作PC上的一块内存,它是一个char设备。
 

SCULL的内存使用

SCULL以一片系统内存作为一个字符设备,对其进行操作。SCULL的内存使用是很有趣的。

代表SCULL设备的数据结构是scull_devscull_dev通过一个链表来管理内存,链表的具体结构为scull_qset,每个scull_qset指向一块内存区域:这块内存区域被分成1000份,每份4000个字节。所以,每份称为quantum,份数成为quantum set,其实份数就是指针了。 SCULL设备的规划如下图:

这个内存使用模型是以scull_qset结构为单位的,当你向SCULL中写入一个byte的数据时,SCULL需要分配给你一个scull_qet结构,这至少需要1000个指针(占用4000字节或8000字节,这取决于平台是32位还是64位)和一个quantum4000字节)。所以写一个字节对于这样一个内存使用模型的开销是很大的。SCULL内存使用模型并没有限制最大使用内存的数目,你可以用完你的机器上所有的实际内存。SCULL只限制了一个scull_qset可以容纳4000x1000大小的内存。

驱动介绍:
scullpipe0 to scullpipe3
Four FIFO (first-in-first-out) devices, which act like pipes. One process reads what another process writes. If multiple processes read the same device, they contend for data. The internals of scullpipe will show how blocking and nonblocking read and write can be implemented without having to resort to interrupts. Although real drivers synchronize with their devices using hardware interrupts, the topic of blocking and nonblocking operations is an important one and is separate from interrupt handling.
 
设备模型:
 
scull pipe设备是针对一片内存实现了一个circular buffer(循环缓冲)。write指针比read大1时,缓冲区满,read和write相等时缓冲区为空,如上图。
代表scull pipe设备的数据结构是:
struct scull_pipe {
        wait_queue_head_t inq, outq;       /* read and write queues */
        char *buffer, *end;                /* begin of buf, end of buf */
        int buffersize;                    /* used in pointer arithmetic */
        char *rp, *wp;                     /* where to read, where to write */
        int nreaders, nwriters;            /* number of openings for r/w */
        struct fasync_struct *async_queue; /* asynchronous readers */
        struct semaphore sem;              /* mutual exclusion semaphore */
        struct cdev cdev;                  /* Char device structure */
};
 
驱动框架:
①模块初始:scull_p_init
②模块注销:scull_p_cleanup
③字符设备相关方法的实现:scull_p_read, scull_p_write, scull_p_ioctl, scull_p_open, scull_p_release, scull_p_fasync
 
(1)    scull_p_init
1)      使用register_chrdev_region()注册scull pipe设备为字符设备;
Name
register_chrdev_region — register a range of device numbers
Synopsis
int register_chrdev_region (
dev_t  
from,
 
unsigned  
count,
 
const char *  
name);
Arguments
from
the first in the desired range of device numbers; must include the major number.
count
the number of consecutive device numbers required
name
the name of the device or driver.
Description
Return value is zero on success, a negative error code on failure.
2)      使用kmalloc()分配scull pipe设备的数据结构;
3)      初始化scull pipe设备的数据结构中的相关的域:
a. 初始化inq域(调用init_waitqueue_head());
b. 初始化outq域(调用init_waitqueue_head());
c. 初始化sem域;
d. scull pipe设备在内核里建立char_dev结构;
 
(2)    scull_p_cleanup()
1)      调用cdev_del()从内核删除scull pipe设备相应的cdev数据结构;
2)      释放代表scull pipe设备的数据结构所占的内存;
3)      调用unregister_chrdev_region()函数释放分配的一系列设备号。
 
(3)    scull_p_ope
阅读(1035) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~