首页 > 其他分享 >块设备驱动实现--模拟一个块设备

块设备驱动实现--模拟一个块设备

时间:2024-07-13 17:31:32浏览次数:20  
标签:-- queue init mq blk disk my 模拟 设备

1、前言

        存储层在收到I/O请求后进行数据处理,再给上层应答,本文实现一个实际的块设备驱动。使用Linux5.4为基础,进行框架搭建和功能实现。

2、ko模块与编译

        首先定义一个init和exit函数,去注册自己的驱动函数模块。

#include <linux/module.h>
#include <linux/init.h>

static int __init init_myblk(void)
{
    int ret;
 
    printk("start lsmod my blk_dev");
 
    my_disk_queue = blk_mq_init_sq_queue( &tag_set, &my_blk_mq_ops, 16, BLK_MQ_F_SHOULD_MERGE);
    if (!my_disk_queue) {
        ret = -ENOMEM;
        goto err_init_queue;
    }
 
    my_disk = alloc_disk(1);
    if (!my_disk) {
        ret = -ENOMEM;
        goto err_alloc_disk;
    }
 
    strcpy(my_disk->disk_name, MY_BLKDEV_DISKNAME);//设备名称
 
    my_disk->major = MY_BLKDEV_DEVICEMAJOR;//块设备的主设备号
    my_disk->first_minor = 0;
 
    my_disk->fops = &myblk_fops;//操作结构体
 
    my_disk->queue = my_disk_queue;//块设备驱动的请求队列
 
    set_capacity(my_disk, MY_BLKDEV_BYTES>>9);
 
 
    add_disk(my_disk);
 
    return 0;
err_init_queue:
    printk("init blk_queue error");
    return ret;
 
err_alloc_disk:
    printk("alloc blk error");
    return ret;
}

module_init(init_myblk);
module_exit(exit_myblk);
MODULE_LICENSE("GPL");

这里还要在要Makefile里记得拉上自己的文件路径,在.config中加上编译的宏,并且写一个kconfig去配置这个宏。

其中,my_disk_queue = blk_mq_init_sq_queue(&tag_set, &my_blk_mq_ops, 16, BLK_MQ_F_SHOULD_MERGE);    在5.4中块设备全面改成了blk_mq(多任务队列),所以相关的API都是和blk_mq有关系的,这个地方卡了好久好久,最终还是从z2ram.c中了解到的,后边io处理的队列也是参考z2ram.c来写的。

所以接下来就是这个my_blk_queue_rq()的内容:

static const struct blk_mq_ops my_blk_mq_ops = {
    .queue_rq   = my_blk_queue_rq,
};
 
static blk_status_t my_blk_queue_rq(struct blk_mq_hw_ctx *hctx,
                            const struct blk_mq_queue_data *bd)
{
    struct request *req = bd->rq;
    unsigned long start = blk_rq_pos(req) << 9;
    unsigned long len  = blk_rq_cur_bytes(req);
    void *buffer;
 
    blk_mq_start_request(req);
 
    if (start + len > MY_BLKDEV_BYTES) {
        printk(KERN_ERR MY_BLKDEV_DISKNAME
            ": bad request: block=%llu, count=%u\n",
            (unsigned long long)blk_rq_pos(req),
            blk_rq_cur_sectors(req));
            blk_mq_end_request(req, BLK_STS_OK);
    }
 
    spin_lock_irq(&myblk_lock);
 
    buffer = bio_data(req->bio);
 
    if (rq_data_dir(req) == READ)
        memcpy(buffer,
            my_blkdev_data + start,
            blk_rq_cur_sectors(req) << 9);
    else if(rq_data_dir(req) == WRITE)
        memcpy(buffer,
            my_blkdev_data + start,
            blk_rq_cur_sectors(req) << 9);
 
    spin_unlock_irq(&myblk_lock);
    blk_mq_end_request(req, BLK_STS_OK);
    return BLK_STS_OK;
}

        实际上就是memcpy相关的字符串到块设备的存储空间内。然后各种编译。且要把blk_mq_init_sq_queue加入白名单(while list)。

3、编译与使用

        在Android开发环境中,选择bootimage编译,修改Makefile和Kconfig后,会自动加载该模块。 使用lsmod可以发现这时候还没被使用,首先进行文件系统挂载:

ir:/ # mkfs.ext4 dev/block/my_blkdev                                                                                                                                                                       
mke2fs 1.45.4 (23-Sep-2019)
Creating filesystem with 16384 1k blocks and 4096 inodes
Filesystem UUID: 200b5fcd-e9ea-4634-9c98-94a8bc58d1f2
Superblock backups stored on blocks:
    8193
 
Allocating group tables: done                           
Writing inode tables: done                           
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
 
ir:/ # mount dev/block/my_blkdev mnt/tmp1/                                                                                                                                                               
mount: 'dev/block/my_blkdev'->'mnt/tmp1/': I/O error

        但是,这里有个问题,将ko整机刷入后,会面临io调度导致的挂载失败问题, 需要进行修改。

参考:[原创] 写一个块设备驱动 - 内核源码-Chinaunix

标签:--,queue,init,mq,blk,disk,my,模拟,设备
From: https://blog.csdn.net/qq_38473009/article/details/140402875

相关文章

  • AI 作词新境界,引领音乐创作新潮流
    在当今音乐创作的领域中,AI技术的融入正开创着令人瞩目的新境界,引领着音乐潮流的走向。“妙笔生词智能写歌词软件(53650899)”便是这一创新浪潮中的杰出代表。它以先进的AI算法和强大的语言处理能力,为音乐创作者们提供了前所未有的作词体验。 妙笔生词智能写歌词软件不再局限......
  • 前端HTML+CSS实现3D炫酷相册(附源码)
    前言    利用基础的html和css实现3D相册(可自我添加照片)    本人初衷是为了验证所学的知识,顺便想逗女朋友开心......
  • 第二周
    本周主要学习了java面向对象的封装,继承和多态。封装:关键词和C嘎嘎一样,private,protected,public等来实现封装。publicclassPerson{privateStringname;privateintage;publicStringgetName(){returnname;}publicvoidsetName(StringnewName){name=......
  • 使用python绘制3D柱状图+完整代码展示
    一、首先进行代码效果图的展示        这是一个简单的3D模型图的展示,我们可以从官网上看到有类似的模型代码,但是大部分都没有加上全局系统配置,整体效果很单一,看不出来有什么特色,我们可以通过了解我们的python绘图工具pyecharts库。二、了解代码这个就是我们的全局......
  • pysnooper
    [root@ansibledts]#pip3installpysnoop-ihttps://mirrors.aliyun.com/pypi/simpleWARNING:Runningpipinstallwithrootprivilegesisgenerallynotagoodidea.Try`pip3install--user`instead.CollectingpysnoopCouldnotfindaversionthatsatisfies......
  • Mysql数据库之约束条件
    一、主键约束主键约束(PRIMARYKEYconstraint)用于唯一标识数据库表中的每条记录。语法:createtable 表名(   列名1数据类型primary key,   列名2数据类型,   ...);在主键的后面添加:auto_increment,可以让主键自增。设置auto_increment之后,可以......
  • G. Ultra-Meow
    原题链接题解遍历所有的子集肯定不行,所以我么考虑某些数作为\(mex\)的值时的贡献,也就是求\(i\)作为\(mex\)的值时,有多少子集的\(mex\)是\(i\)实施对于\(i\leqn\),假设子集选了\(k_1\)个小于\(i\)的数,\(k_2\)个大于\(i\)的数,则有\(1+(i-1)-k_1=k_1+k_2\)......
  • Html5前端基本知识整理与回顾上篇
    今天我们结合之前上传的知识资源来回顾学习的Html5前端知识,与大家共勉,一起学习。目录介绍了解注释标签结构排版标签标题标签​编辑段落标签​编辑换⾏标签​编辑⽔平分割线⽂本格式化标签媒体标签绝对路径相对路径音频标签格式​编辑注意点视频标签格......
  • 解锁创意:人工智能打造专属你的动人歌词
    在音乐的广袤天地里,歌词是那璀璨繁星,点亮了旋律的灵魂。然而,寻找那恰到好处、能深深触动人心的歌词,常常是创作者们面临的挑战。如今,人工智能的崛起为我们带来了全新的可能,让专属动人歌词的诞生变得不再遥不可及。“妙笔生词智能写歌词软件(53650899)”便是这场音乐革命中的璀璨明星......
  • python数据可视化(5)——绘制饼图
    课程学习来源:b站up:【蚂蚁学python】【课程链接:【【数据可视化】Python数据图表可视化入门到实战】】【课程资料链接:【链接】】Python绘制饼图分析北京天气饼图,是一个划分为几个扇形的圆形统计图表,能够直接以图形的方式直接显示各个组成部分所占比例目的:查看2019年北京......