分类: LINUX
2005-09-09 11:09:20
一 。注册模块
1。注册 register_blkdev(major,name,struct block_device_operation *p);
2.初始化队列:
多队列 blk_init_queue(request_queue_t *,request_fn);
blk_dev[major]=sbull_find_queue;
无队列 blk_queue_make_request(BLK_DEFAULT_QUEUE(major),sbull_make_request);
单队列 blk_init_queue(BLK_DEFAULT_QUEUE(major),sbull_request);
3.注册分区设备 register_disk(NULL,MKDEV(major,i),1,&sbull_bdops,sbull_size<<1);
二 。结构
struct block_device_operation sbull_bdops={
open:
sbull_open,
release:
sbull_release,
ioctl:
sbull_ioctl,
check_media_change: sbull_check_change,
revalidate:
sbull_revalidate,
};
在linux/blk.h
(MAJOR_NR,CURRENT等macro变量);linux/blkdev.h(blk_dev[MAX],blk_size,
blksize_size,request_queue_t等结构申明);在drivers/block/ll_rw_blk.c(包含
blk_init_queue等函数的实现);
三 请求处理函数
sbull_request(request_queue_t *p);
四 支持常用的对快设备操作的命令
fdisk mount mkfs
例如 mount 的过程 1。open设备;2。调用request处理方法,传输数据块。
五 可分区设备
1。在driver/block/genhd.c中的struct gendisk
*gendisk_head 为static 所以虽然在linux/genhd.h中申明为extern struct gendisk
*gendisk_head ;但在我们的程序中还是出现unresolved symbol ,所以在我们的程序中还得申明一下struct
gendisk *gendisk_head 。
2。申明一个struct gendisk spull_gendisk 并初始化各成员。
3。在revalidate函数中重新调用register_disk(struct gendisk
*gd,int driver,unsigned minors,struct block_device_operation *ops,long
size)注册分区。
4。模块注册过程和sbull一样。
5. 中断处理过程,在请求处理函数中启动定时器,然后在定时器函数中end_request(1);
普通的请求处理函数是在本函数中直接调用end_request(1)的。
如果驱动程序是中断驱动的,request
函数应该提交一次数据传输并立即返回,而无需调用 end_request。但是,在没有调用
end_request(或其组成部分)之前,不会认为请求已经 完成。因此,在设备告诉驱动程序已完成数据传输时,顶半或底半中断处理程序需要调用
end_request。