ARM的嵌入式Linux移植体验之设备驱动
_blkdev(unsigned int major, const char *name, struct block_device_operations *bdops); 但是,register_chrdev使用一个向 file_operations 结构的指针,而register_blkdev 则使用 block_device_operations 结构的指针,其中定义的open、release 和 ioctl 方法和字符设备的对应方法相同,但未定义 read 或者 write 操作。这是因为,所有涉及到块设备的 I/O 通常由系统进行缓冲处理。 块驱动程序最终必须提供完成实际块 I/O 操作的机制,在 Linux 当中,用于这些 I/O 操作的方法称为"request(请求)"。在块设备的注册过程中,需要初始化request队列,这一动作通过blk_init_queue来完成,blk_init_queue函数建立队列,并将该驱动程序的 request 函数关联到队列。在模块的清除阶段,应调用 blk_cleanup_queue 函数。 本例中相关的代码为: BLK_INIT_QUEUE(BLK_DEFAULT_QUEUE(MAJOR_NR), mtdblock_request, mtdblock_lock); 每个设备有一个默认使用的请求队列,必要时,可使用 BLK_DEFAULT_QUEUE(major) 宏得到该默认队列。这个宏在 blk_dev_struct 结构形成的全局数组(该数组名为 blk_dev)中搜索得到对应的默认队列。blk_dev 数组由内核维护,并可通过主设备号索引。blk_dev_struct 接口定义如下: struct blk_dev_struct { request_queue 成员包含了初始化之后的 I/O 请求队列,data 成员可由驱动程序使用,以便保存一些私有数据。 request_queue定义为: struct request_queue /* request_fn_proc * request_fn; /* /* /* /* /* 下图表征了blk_dev、blk_dev_struct和request_queue的关系: 下图则表征了块设备的注册和释放过程: 5.小结 本章讲述了Linux设备驱动程序的入口函数及驱动程序中的内存申请、中断等,并分别以实例讲述了字符设备及块设备的驱动开发方法。
int unregister_blkdev(unsigned int major, const char *name);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
/*
* queue_proc has to be atomic
*/
request_queue_t request_queue;
queue_proc *queue;
void *data;
};
{
/*
* the queue request freelist, one for reads and one for writes
*/
struct request_list rq[2];
* Together with queue_head for cacheline sharing
*/
struct list_head queue_head;
elevator_t elevator;
merge_request_fn * back_merge_fn;
merge_request_fn * front_merge_fn;
merge_requests_fn * merge_requests_fn;
make_request_fn * make_request_fn;
plug_device_fn * plug_device_fn;
/*
* The queue owner gets to use this for whatever they like.
* ll_rw_blk doesn't touch it.
*/
void * queuedata;
* This is used to remove the plug when tq_disk runs.
*/
struct tq_struct plug_tq;
* Boolean that indicates whether this queue is plugged or not.
*/
char plugged;
* Boolean that indicates whether current_request is active or
* not.
*/
char head_active;
* Is meant to protect the queue in the future instead of
* io_request_lock
*/
spinlock_t queue_lock;
* Tasks wait here for free request
*/
wait_queue_head_t wait_for_request;
};
- Linux嵌入式系统开发平台选型探讨(11-09)
- 基于ARM体系的嵌入式系统BSP的程序设计方案(04-11)
- 在Ubuntu上建立Arm Linux 开发环境(04-23)
- 达芬奇数字媒体片上系统的架构和Linux启动过程(06-02)
- SQLite嵌入式数据库系统的研究与实现(02-20)
- 革新2410D开发板试用手记(04-21)
