Linux 块设备驱动

news2024/9/27 12:10:11

1.块设备是针对存储设备的,比如 SD 卡、 EMMC、 NAND Flash、 Nor Flash、 SPI Flash、机械硬盘、固态硬盘等。因此块设备驱动其实就是这些存储设备驱动,块设备驱动相比字符设备驱动的主要区别如下:
①、块设备只能以块为单位进行读写访问,块是 linux 虚拟文件系统(VFS)基本的数据传输单位。字符设备是以字节为单位进行数据传输的,不需要缓冲。
②、块设备在结构上是可以进行随机访问的,对于这些设备的读写都是按块进行的,块设备使用缓冲区来暂时存放数据,等到条件成熟以后在一次性将缓冲区中的数据写入块设备中。
这么做的目的为了提高块设备寿命,大家如果仔细观察的话就会发现有些硬盘或者 NAND Flash就会标明擦除次数(flash 的特性,写之前要先擦除),比如擦除 100000 次等。因此,为了提高块设备寿命而引入了缓冲区,数据先写入到缓冲区中(所以linux中对存储设备操作完,需要使用sync同步,才能写入将数据写入到存储设备,不然可能数据还在缓存区中),等满足一定条件后再一次性写入到真正的物理存储设备中,这样就减少了对块设备的擦除次数,提高了块设备寿命。

2.字符设备是顺序的数据流设备,字符设备是按照字节进行读写访问的。字符设备不需要缓冲区,对于字符设备的访问都是实时的,而且也不需要按照固定的块大小进行访问。

3.块设备结构的不同其 I/O 算法也会不同,比如对于 EMMC、 SD 卡、 NAND Flash 这类没有任何机械设备的存储设备就可以任意读写任何的扇区(块设备物理存储单元)。但是对于机械硬盘这样带有磁头的设备,读取不同的盘面或者磁道里面的数据,磁头都需要进行移动,因此对于机械硬盘而言,将那些杂乱的访问按照一定的顺序进行排列可以有效提高磁盘性能, linux 里面针对不同的存储设备实现了不同的 I/O 调度算法。

4.linux驱动程序中字符设备和块设备的三点区别
​1)字符设备只能以字节为最小单位访问,而块设备以块为单位访问,例如512字节,1024字节等
2)块设备可以随机访问,但是字符设备不可以
3)字符和块没有访问量大小的限制,块也可以以字节为单位来访问

5.驱动

5.1驱动入口函数

static int __init ramdisk_init(void)
{

    int ret = 0;
    /* 1、先申请内存 */
    ramdisk.ramdiskbuf = kzalloc(RAMDISK_SIZE, GFP_KERNEL);

    /* 2、注册块设备 */
    ramdisk.major = register_blkdev(0, RAMDISK_NAME); 

    /* 3、申请gendisk */
    ramdisk.gendisk = alloc_disk(RAMDISK_MINOR);
	   
    /* 4、初始化自旋锁 */
    spin_lock_init(&ramdisk.lock);

    /* 5、申请并初始化请求队列 */
    ramdisk.queue = blk_init_queue(ramdisk_request_fn, &ramdisk.lock);

    /* 6、初始化 gendisk */
    ramdisk.gendisk->major = ramdisk.major;      /* 主设备号 */
    ramdisk.gendisk->first_minor = 0;            /* 起始次设备号 */
    ramdisk.gendisk->fops = &ramdisk_fops;       /* 操作函数 */
    ramdisk.gendisk->private_data = &ramdisk;    /* 私有数据 */
    ramdisk.gendisk->queue = ramdisk.queue;      /* 请求队列 */
    sprintf(ramdisk.gendisk->disk_name, RAMDISK_NAME); /* 名字(拷贝名字) */
	
    set_capacity(ramdisk.gendisk, RAMDISK_SIZE/512);   /* 设置gendisk容量,单位扇区 */
	
    add_disk(ramdisk.gendisk); /* 向内核添加一个磁盘设备 */

    return 0;

blk_queue_fail:
    put_disk(ramdisk.gendisk); 
gendisk_alloc_fail:
    unregister_blkdev(ramdisk.major, RAMDISK_NAME);
ramdisk_register_blkdev_fail:
    kfree(ramdisk.ramdiskbuf);  /* 释放内存 */
ramalloc_fail:
    return ret;
}

5.2定义设备结构体

/* ramdisk设备结构体 */
struct ramdisk_dev{
    int major;                    /* 主设备号 */
    unsigned char *ramdiskbuf;    /* 模拟磁盘的空间 */
    struct gendisk *gendisk;      /* 描述一个磁盘设备 */
    struct request_queue *queue;  /* 请求队列 */
    spinlock_t lock;              /* 自旋锁 */
};

5.3块设备请求处理函数

/* 请求函数 */
static void ramdisk_request_fn(struct request_queue *q)
{
    int err = 0;
    struct request *req;

	req = blk_fetch_request(q);  /* 有电梯调度算法, */
	while (req) {
    
        /* 具体的数据读写操作 */
        ramdisk_transfer(req);

	    /* 判断是否为最后一个请求,如果不是的话就获取下一个请求循环处理完请求队列中的所有请求。*/
        if (!__blk_end_request_cur(req, err))
			req = blk_fetch_request(q);
    }
}

5.4具体的块数据读写操作

static void ramdisk_transfer(struct request *req)
{
    /* 数据传输三要素:源,目的(地),长度。*/

    unsigned long start = blk_rq_pos(req) << 9;  
    unsigned long len  = blk_rq_cur_bytes(req); 


    void *buffer = bio_data(req->bio);  

    if (rq_data_dir(req) == READ)       /* 读操作(读数据 ) */ 
		memcpy(buffer, ramdisk.ramdiskbuf + start, len);    
	else                                /* 写操作(写数据) */
		memcpy(ramdisk.ramdiskbuf + start, buffer, len);      
}

5.5块设备操作集

/* 块设备操作集 */
static const struct block_device_operations ramdisk_fops =
{
	.owner		= THIS_MODULE,
	.open		= ramdisk_open,    
	.release	= ramdisk_release,
    .getgeo     = ramdisk_getgeo,  /* 获取磁盘信息,包括磁头、柱面和扇区等信息。 */
};

6.驱动测试

6.1查看磁盘设备:fdisk -l

 

6.2格式化/dev/ramdisk

格式化完成以后就可以挂载/dev/ramdisk 来访问了,挂载点可以自定义,这里就将其挂
载到/tmp

6.3 挂载设备:mount /dev/ramdisk /tmp/disk_test/

6.4卸载设备:umount /dev/ramdisk

 

6.5卸载设备后,重新挂载设备,查看存储设备中的内容是否还存在。

 

7.根目录下文件简单介绍:

7.1、/bin目录:binary(二进制的):许多指令对应的可执行程序文件目录。

7.2、/sbin目录:super binary超级的二进制许多指令对应可执行程序文件目录,该目录文件对应指令都是root用户可以执行的指令普通用户不能使用该目录里的命令:普通用户 用$开发、root用户 用#开头。

7.3、/usr目录:unix system resource,Unix系统资源文件目录,该目录类似于Windows系统的C:/Program files目录,该目录经常用于安装各种软件,软件安装完毕会形成对应的指令,该指令对应的可执行程序文件就存放在以下目录。/usr/bin许多指令对应的可执行程序文件目录/usr/sbin root用户执行的指令对应的可执行程序文件目录。

7.4、/dev目录:device系统硬件设备目录,Linux系统所有的硬件都通过文件表示,比如:/dev/cdrom是光驱/dev/sda 是第一块scsi硬盘。

7.5、/home目录:存放所有用户文件的根目录,是用户主目录的基点,比如用户user的主目录就是/home/user,可以用~user表示。

7.6、/proc目录:内存映射目录,该目录可以查看系统的相关信息。

7.7、/var目录:用于存放运行时需要改变数据的文件,也是某些大文件的溢出区,比如说各种服务的日志文件等。

7.8、/boot目录:系统启动核心目录,用于储存系统启动文件。

7.9、/etc目录:存放系统管理和配置文件,比如:/ect/passwd 用于存储用户信息的文件、/etc/group 用于存储组别信息的文件。

7.10、/lib目录:存放跟文件系统中的程序运行所需要的共享库及内核模块。共享库又叫作动态链接共享库,作用类似Windows里的.dll文件,存放了根文件系统程序运行所需的共享文件。

7.11、/mnt目录:系统管理员安装临时文件系统的安装点,系统提供这个目录是让用户临时挂载其他的文件系统。

7.12、/tmp目录:用于存放各种临时文件,是公用的临时文件存储点。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/139955.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【阶段二】Python数据分析Pandas工具使用07篇:探索性数据分析:数据的描述:数据的集中趋势

本篇的思维导图: 探索性数据分析:数据的描述 数据的描述是为了让数据使用者或开发者更加了解数据,进而做到“心中有数”,其描述过程侧重于统计运算和统计绘图。通过统计运算可以得到具体的数据特征,如反映集中趋势中的均值水平、中位数、分位数和众数等;反映分散趋势的方…

Unity脚本 --- VS调试工具

一般游戏逻辑调试的时候用的都是VS调试工具来进行调试 1.在Unity脚本中启动调试后并不会立刻开始调试&#xff0c;还需要我们在Unity中点击play&#xff08;游戏运行&#xff09;后调试才会开始进行 2.在调试的时候点击f11可以逐语句调试&#xff0c;同时当我们在调试的时候想…

螺旋桨k线的意义?

相信大家即使没坐过直升机&#xff0c;也很看见过螺旋桨吧&#xff1f;它的动能巨大&#xff0c;刮起的旋风能支撑起一架飞机的升降。但大家是否知道&#xff0c;在K线技术分析中&#xff0c;也有一种特殊的形态叫“螺旋桨”呢&#xff1f; 三、螺旋桨K线的形态概念 如下图&am…

2023-1-4目前市面上存在的树莓派rp2040控制器

目前市面上存在的树莓派rp2040控制器 1、树莓派pico原装 2、微雪rp2040 3、Ultimate pico rp2040兼容树莓派pico RaspberryPi Pico是一款低成本&#xff0c;高性能的微控制器开发板&#xff0c;具有灵活数字接口。硬件上&#xff0c;采用Raspberry Pi官方自主研发的RP2040微控…

高精度PWM脉宽调制信号转模拟信号隔离变送器0-5V/0-10V/1-5V,0-10mA/0-20mA/4-20mA

主要特性:>>精度等级&#xff1a;0.1级。产品出厂前已检验校正&#xff0c;用户可以直接使用>>辅助电源&#xff1a;8-32V 宽范围供电>>PWM脉宽调制信号输入: 1Hz~10KHz>>输出标准信号&#xff1a;0-5V/0-10V/1-5V,0-10mA/0-20mA/4-20mA等&#xff0c;…

国家法定节假日安排,节假日查询API接口有哪些?

节假日&#xff0c;对于我们每个人来说都息息相关。特别是国家法定节假日的安排&#xff0c;大家都希望清楚知道并合理安排好。因为&#xff0c;节假日是国务院统一安排的&#xff0c;我们就为此编写了这样一个节假日查询API接口&#xff0c;供大家方便查询。 节假日API接口正广…

佳能6D误格式化覆盖后的恢复方法

佳能6D算是佳能众多摄像机中的明星机型&#xff0c;销量很大。同样遇到的问题也很多&#xff0c;今天要说的案例就是佳能6D格式化覆盖后的恢复案例&#xff0c;比较特殊的是其结构部分全部覆盖了&#xff0c;下面我们来看看这个案例。故障存储:64G sd卡&#xff0c;采用exFAT文…

软件项目如何进行任务分配,减少冲突?

1、任务分配并非平均分配 项目经理往往有个认知误区&#xff0c;认为把工作任务详细分解&#xff0c;平均分配给每个人&#xff0c;不偏不倚&#xff0c;公平公正就没有问题。但在实际开发过程中&#xff0c;这样很容易出问题&#xff0c;尤其是到项目后期&#xff0c;掉链子的…

Python中的时间序列数据操作总结

时间序列数据是一种在一段时间内收集的数据类型&#xff0c;它通常用于金融、经济学和气象学等领域&#xff0c;经常通过分析来了解随着时间的推移的趋势和模式 Pandas是Python中一个强大且流行的数据操作库&#xff0c;特别适合处理时间序列数据。它提供了一系列工具和函数可以…

意想不到的前端三个小妙招

大厂面试题分享 面试题库前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库整理下本人在工作中撸代码遇到的一些刚看时一脸懵逼&#xff0c;实则很简单就能解决的小妙招&#xff0c;希望对大家有所帮助哟~伪元素动态改变…

「诗人艺术家ll著名诗人」胭脂茉莉十四行诗10首

【诗人艺术家ll著名诗人】胭脂茉莉十四行10首胭脂茉莉诗人简介&#xff1a;胭脂茉莉&#xff0c;女&#xff0c;江苏人&#xff0c;年少习诗&#xff0c;作家、诗人。评论及随笔见诸媒体及报刊&#xff0c;诗歌被选编入海内外多种选本及刊物&#xff0c;其主要代表作有现代禅诗…

vue3-init

Vue3快速上手 1.Vue3简介 2020年9月18日&#xff0c;Vue.js发布3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;海贼王&#xff09;耗时2年多、2600次提交、30个RFC、600次PR、99位贡献者github上的tags地址&#xff1a;https://github.com/vuejs/vue-next/release…

maven中的scope

provided: 编译运行时期&#xff0c;目标容器已经提供&#xff0c;打jar包时候不带optional&#xff0c;依赖传递test: 举例子junit&#xff0c;为什么Test在src的java蓝包的测试类的方法上面不能用&#xff1f;src的java绿包里的测试类的方法上可以用。 依赖传递&#xff1a;间…

【数据篇】32 # 如何选择合适的方法对数据进行可视化处理?

说明 【跟月影学可视化】学习笔记。 从原始数据中过滤出有用的信息 下面通过航拍公园人群分布例子&#xff0c;按照某些属性对数据进行过滤&#xff0c;再将符合条件的结果展现出来。 数据来源&#xff1a;https://github.com/akira-cn/graphics/blob/master/data/park-peo…

Java on Azure Tooling 2022年12月更新|Azure SDK 参考书代码样例支持及用户体验提升

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎回到12月的 Java on Azure Tooling 的更新。首先&#xff0c;提前祝大家新年快乐。在这次更新中&#xff0c;我们将介绍 Azure SDK 参考书的…

Linux系统之部署MxsDoc个人文件管理系统

Linux系统之部署MxsDoc个人文件管理系统一、MxsDoc介绍1.MxsDoc简介2.MxsDoc功能3.MxsDoc应用场景二、检查本地系统环境1.检查系统版本2.检查系统内核三、下载MxsDoc软件包1.创建软件目录2.下载MxsDoc软件3.查看下载软件四、部署MxsDoc1.解压MxsDoc软件包2.一键部署MxsDoc五、登…

【Linux逻辑卷管理】之pvcreate、pvdisplay和pvremove

文章目录一、逻辑卷管理(LVM)概念1. LVM 定义2. 物理卷(PV)3. 卷组(VG)4. 逻辑卷(LV)二、创建逻辑卷1. pvcreate命令将分区标记为物理卷&#xff0c;创建物理卷2. vgcreate命令将一个或多个物理卷结合为一个卷组&#xff0c;创建卷组3. lvcreate命令根据卷组中的可用物理区块,创…

【线上故障记录】MySQLTransactionRollbackException: Lock wait timeout exceeded

数据同学反馈凌晨1-2点会出现连接系统MySQL数据库等待锁超时 com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction InnoDB事务等待一个行级锁的时间最长时间默认值是50秒&#xff08;单位是秒&#x…

尚硅谷_ShardingSphere5

ShardingSphere5第01章 高性能架构模式1、读写分离架构2、数据库分片架构2.1、垂直分片2.2、水平分片3、读写分离和数据分片架构4、实现方式4.1、程序代码封装4.2、中间件封装4.3、常用解决方案第02章 ShardingSphere1、简介2、ShardingSphere-JDBC3、ShardingSphere-Proxy第03…

tcping实用小工具

Tcping----实用小工具tcping命令详解 一、tcping介绍 tcping&#xff1a;tcping命令基于tcp协议监控&#xff0c;可以从较低级别的协议获得简单的&#xff0c;可能不可靠的数据报服务。 原则上&#xff0c;TCP应该能够在从容硬线连接到分组交换或电路交换网络的各种通信系统之…