当前位置: 首页 > news >正文

linux 块设备-整理(一)

1. 基本概念:

 linux设备驱动开发详解(宋宝华):

字符设备与块设备 I/O 操作的不同如下。
(1)块设备只能以块为单位接受输入和返回输出,而字符设备则以字节为单位。

大多数设备是字符设备,因为它们不需要缓冲而且不以固定块大小进行操作。
(2)块设备对于 I/O 请求有对应的缓冲区,因此它们可以选择以什么顺序进行响应,字符设备无须缓冲且被直接读写 。

对于存储设备而言调整读写的顺序作用巨大,因为在读写连续的扇区比分离的扇区更快。
(3)字符设备只能被顺序读写,而块设备可以随机访问。

虽然块设备可随机访问,但是对于磁盘这类机械设备而言,顺 序地组织块设备的访问可以提高性能。

对于块设备而言,最重要的,就是处理请求,对请求的排队和整合由 I/O 调度算法解决,

因此,块设备驱动的核心就是请求处理函数或“制造请求”函数。

块设备中最小的可寻址单元是扇区,扇区大小一般是 2 的整数倍,最常见的大小是 512 字节。

扇区的大小是设备的 物理属性,扇区是所有块设备的基本单元,块设备无法对比它还小的单元进行寻址和操作,

不过许多块设备能够一次 就传输多个扇区。虽然大多数块设备的扇区大小都是 512 字节,

不过其他大小的扇区也很常见,比如,很多 CD-RO M 盘的扇区都是 2KB。

不管物理设备的真实扇区大小是多少,内核与块设备驱动交互的扇区都以 512 字节为单位

 在块设备驱动的模块加载函数中通常需要完成如下工作。
1 分配、初始化请求队列,绑定请求队列和请求函数。
2 分配、初始化 gendisk,给 gendisk 的 major、fops、queue 等成员赋值,最后添加 gendisk。
3 注册块设备驱动。 

具体代码:

 

[cpp]  view plain  copy
 
  1. #include <linux/module.h>  
  2. #include <linux/errno.h>  
  3. #include <linux/interrupt.h>  
  4. #include <linux/mm.h>  
  5. #include <linux/fs.h>  
  6. #include <linux/kernel.h>  
  7. #include <linux/timer.h>  
  8. #include <linux/genhd.h>  
  9. #include <linux/hdreg.h>  
  10. #include <linux/ioport.h>  
  11. #include <linux/init.h>  
  12. #include <linux/wait.h>  
  13. #include <linux/blkdev.h>  
  14. #include <linux/blkpg.h>  
  15. #include <linux/delay.h>  
  16. #include <linux/io.h>  
  17.   
  18. #include <asm/system.h>  
  19. #include <asm/uaccess.h>  
  20. #include <asm/dma.h>  
  21.   
  22. static struct gendisk *ramblock_disk;  
  23. static request_queue_t *ramblock_queue;  
  24.   
  25. static int major;  
  26.   
  27. static DEFINE_SPINLOCK(ramblock_lock);  
  28.   
  29. static struct block_device_operations ramblock_fops = {  
  30.     .owner  = THIS_MODULE,  
  31. };  
  32.   
  33. #define RAMBLOCK_SIZE (1024*1024)  
  34.   
  35. static void do_ramblock_request(request_queue_t * q)  
  36. {  
  37.     static int cnt = 0;  
  38.     printk("do_ramblock_request %d\n", ++cnt);  
  39. }  
  40.   
  41. static int ramblock_init(void)  
  42. {  
  43.     /* 1. 分配一个gendisk结构体 */  
  44.     ramblock_disk = alloc_disk(16); /* 次设备号个数: 分区个数+1 */  
  45.   
  46.     /* 2. 设置 */  
  47.     /* 2.1 分配/设置队列: 提供读写能力 */  
  48.     ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);  
  49.     ramblock_disk->queue = ramblock_queue;  
  50.       
  51.     /* 2.2 设置其他属性: 比如容量 */  
  52.     major = register_blkdev(0, "ramblock");  /* cat /proc/devices */      
  53.     ramblock_disk->major       = major;  
  54.     ramblock_disk->first_minor = 0;  
  55.     sprintf(ramblock_disk->disk_name, "ramblock");  
  56.     ramblock_disk->fops        = &ramblock_fops;  
  57.     set_capacity(ramblock_disk, RAMBLOCK_SIZE / 512);  
  58.   
  59.     /* 3. 注册 */  
  60.     add_disk(ramblock_disk);  
  61.   
  62.     return 0;  
  63. }  
  64.   
  65. static void ramblock_exit(void)  
  66. {  
  67.     unregister_blkdev(major, "ramblock");  
  68.     del_gendisk(ramblock_disk);  
  69.     put_disk(ramblock_disk);  
  70.     blk_cleanup_queue(ramblock_queue);  
  71. }  
  72.   
  73. module_init(ramblock_init);  
  74. module_exit(ramblock_exit);  
  75.   
  76. MODULE_LICENSE("GPL");  

 

转载于:https://www.cnblogs.com/Ph-one/p/8497171.html

相关文章:

  • 22.Linux-块设备驱动之框架详细分析(详解)
  • linux input输入子系统分析《四》:input子系统整体流程全面分析
  • 形参传递关键点
  • Calling Convention的总结
  • unsigned short A = 10; printf(~A = %u\n, ~A); char c=128; printf(c=%d\n,c); 输出多少?
  • linux中断的下半部机制
  • linux下.so、.ko、.a的区别
  • platform_device和platform_driver的注册过程,及probe函数何时调用的分析 ⭐⭐⭐
  • Linux文件系统学习(一)之相关概念⭐⭐⭐
  • 系统调用彻底理解
  • Linux内存管理的基本框架⭐⭐
  • c语言数据类型字节长度
  • 仔细讨论 C/C++ 字节对齐问题⭐⭐
  • 字节序:大端法和小端法⭐
  • 强制类型转换⭐
  • 分享的文章《人生如棋》
  • Apache Pulsar 2.1 重磅发布
  • canvas 高仿 Apple Watch 表盘
  • laravel5.5 视图共享数据
  • Linux下的乱码问题
  • miaov-React 最佳入门
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • Python利用正则抓取网页内容保存到本地
  • Rancher-k8s加速安装文档
  • spring + angular 实现导出excel
  • Vue官网教程学习过程中值得记录的一些事情
  • 当SetTimeout遇到了字符串
  • 深入 Nginx 之配置篇
  • 网页视频流m3u8/ts视频下载
  • 走向全栈之MongoDB的使用
  • 关于Android全面屏虚拟导航栏的适配总结
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • (2)STL算法之元素计数
  • (3)llvm ir转换过程
  • (C++20) consteval立即函数
  • (Matlab)使用竞争神经网络实现数据聚类
  • (初研) Sentence-embedding fine-tune notebook
  • (多级缓存)缓存同步
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (四)鸿鹄云架构一服务注册中心
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (一)认识微服务
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • ./configure、make、make install 命令
  • .bashrc在哪里,alias妙用
  • .describe() python_Python-Win32com-Excel
  • .NET gRPC 和RESTful简单对比
  • .NET 使用 XPath 来读写 XML 文件
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .NET中统一的存储过程调用方法(收藏)
  • .sys文件乱码_python vscode输出乱码
  • /var/lib/dpkg/lock 锁定问题