- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
实验七(补充):写一个块设备驱动
试验七(补充):写一个块设备驱动
static int __init simp_blkdev_init(void)
{
return 0;
}
static void __exit simp_blkdev_exit(void)
{
}
module_init(simp_blkdev_init);
module_exit(simp_blkdev_exit);
为了建立一个可用的块设备,我们需要做1件事情:用add_disk()向系统中添加这个块设备。
添加一个全局的结构体指针:
static struct gendisk *simp_blkdev_disk;
然后申明模块的入口和出口:
module_init(simp_blkdev_init);
module_exit(simp_blkdev_exit);
然后在入口处添加这个设备、出口处释放这个设备:
static int __init simp_blkdev_init(void)
{
add_disk(simp_blkdev_disk);
return 0;
}
static void __exit simp_blkdev_exit(void)
{
del_gendisk(simp_blkdev_disk);
}
当然,在添加设备之前我们需要申请这个设备的资源,这用到了alloc_disk(),因此模块入口函数simp_blkdev_init()应该是:
static int __init simp_blkdev_init()
{
simp_blkdev_disk = alloc_disk(1);
if (!simp_blkdev_disk)
{
ret = -ENOMEM;
goto err_alloc_disk;
}
add_disk(simp_blkdev_disk);
return 0;
err_alloc_disk:
return ret;
}
还有别忘了在卸载模块的代码中也加一个行清理函数:
put_disk(simp_blkdev_disk);
还有就是,设备有关的属性是要设置的,因此在alloc_disk()和add_disk()之间我们需要:
strcpy(simp_blkdev_disk-disk_name, SIMP_BLKDEV_DISKNAME);
simp_blkdev_disk-major = (?1);
simp_blkdev_disk-first_minor = 0;
simp_blkdev_disk-fops = (?2);
simp_blkdev_disk-queue = (?3);
set_capacity(simp_blkdev_disk, (?4);
SIMP_BLKDEV_DISKNAME是这个块设备的名称,把它定义成宏了:
#define SIMP_BLKDEV_DISKNAME simp_blkdev
这里又引出了4个问号。
第1个问号:每个设备需要对应的主、从驱动号。使用命令cat /proc/devices查看没有占用设备号。然后在?1的位置填上150。
第2个问号:
gendisk结构需要设置fops指针,虽然我们用不到,但该设还是要设的。好吧,就设个空得给它,在全局部分添加:
struct block_device_operations simp_blkdev_fops =
{
.owner = THIS_MODULE,
};
然后把?2的位置填上simp_blkdev_fops。
第3个问号:首先介绍请求队列的概念。对大多数块设备来说,系统会把对块设备的访问需求用bio和bio_vec表示,然后提交给通用块层。
通用块层为了减少块设备在寻道时损失的时间,使用I/O调度器对这些访问需求进行排序,以尽可能提高块设备效率。
关于I/O调度器在本章中不打算进行深入的讲解,但我们必须知道的是:
1:I/O调度器把排序后的访问需求通过request_queue结构传递给块设备驱动程序处理。
2:我们的驱动程序需要设置一个request_queue结构。申请request_queue结构的函数是blk_init_queue(),而调用blk_init_queue()时需要传入一个函数的地址,这个函数担负着处理对块设备数据的请求。
因此我们需要做的就是:
1:实现一个static void simp_blkdev_do_request(struct request_queue *q)函数。
2:加入一个全局变量,指向块设备需要的请求队列:
static struct request_queue *simp_blkdev_queue;
3:在加载模块时用simp_blkdev_do_req
文档评论(0)