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 注册块设备驱动。

具体代码:

  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. #include <asm/system.h>
  18. #include <asm/uaccess.h>
  19. #include <asm/dma.h>
  20. static struct gendisk *ramblock_disk;
  21. static request_queue_t *ramblock_queue;
  22. static int major;
  23. static DEFINE_SPINLOCK(ramblock_lock);
  24. static struct block_device_operations ramblock_fops = {
  25. .owner  = THIS_MODULE,
  26. };
  27. #define RAMBLOCK_SIZE (1024*1024)
  28. static void do_ramblock_request(request_queue_t * q)
  29. {
  30. static int cnt = 0;
  31. printk("do_ramblock_request %d\n", ++cnt);
  32. }
  33. static int ramblock_init(void)
  34. {
  35. /* 1. 分配一个gendisk结构体 */
  36. ramblock_disk = alloc_disk(16); /* 次设备号个数: 分区个数+1 */
  37. /* 2. 设置 */
  38. /* 2.1 分配/设置队列: 提供读写能力 */
  39. ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);
  40. ramblock_disk->queue = ramblock_queue;
  41. /* 2.2 设置其他属性: 比如容量 */
  42. major = register_blkdev(0, "ramblock");  /* cat /proc/devices */
  43. ramblock_disk->major       = major;
  44. ramblock_disk->first_minor = 0;
  45. sprintf(ramblock_disk->disk_name, "ramblock");
  46. ramblock_disk->fops        = &ramblock_fops;
  47. set_capacity(ramblock_disk, RAMBLOCK_SIZE / 512);
  48. /* 3. 注册 */
  49. add_disk(ramblock_disk);
  50. return 0;
  51. }
  52. static void ramblock_exit(void)
  53. {
  54. unregister_blkdev(major, "ramblock");
  55. del_gendisk(ramblock_disk);
  56. put_disk(ramblock_disk);
  57. blk_cleanup_queue(ramblock_queue);
  58. }
  59. module_init(ramblock_init);
  60. module_exit(ramblock_exit);
  61. MODULE_LICENSE("GPL");

linux 块设备-整理(一)的更多相关文章

  1. linux块设备驱动之实例

    1.注册:向内核注册个块设备驱动,其实就是用主设备号告诉内核这个代表块设备驱动 sbull_major  =  register_blkdev(sbull_major, "sbull&quo ...

  2. Linux块设备驱动详解

    <机械硬盘> a:磁盘结构 -----传统的机械硬盘一般为3.5英寸硬盘,并由多个圆形蝶片组成,每个蝶片拥有独立的机械臂和磁头,每个堞片的圆形平面被划分了不同的同心圆,每一个同心圆称为一个 ...

  3. (linux)块设备驱动程序

      1.4.1  Linux块设备驱动程序原理(1) 顾名思义,块设备驱动程序就是支持以块的方式进行读写的设备.块设备和字符设备最大的区别在于读写数据的基本单元不同.块设备读写数据的基本单元为块,例如 ...

  4. linux块设备模型架构框架

    Linux块设备的原理远比字符设备要复杂得多,尽管在linux这一块的方法论有很多相似之处,但考虑到它是用中块结构,它常常要搭配内存页管理,页缓冲块缓冲来改善硬盘访问的速度,按照块硬件最大的性能要求进 ...

  5. IO调度 | Linux块设备中的IO路径及调度策略

    当文件系统通过submit_bio提交IO之后,请求就进入了通用块层.通用块层会对IO进行一些预处理的动作,其目的是为了保证请求能够更加合理的发送到底层的磁盘设备,尽量保证性能最佳.这里面比较重要的就 ...

  6. 简单linux块设备驱动程序

    本文代码参考<LINUX设备驱动程序>第十六章 块设备驱动程序 本文中的“块设备”是一段大小为PAGE_SIZE的内存空间(两个扇区,每个扇区512字节) 功能:向块设备中输入内容,从块设 ...

  7. Linux 块设备驱动 (二)

    linux下Ramdisk驱动 1 什么是Ramdisk Ramdisk是一种模拟磁盘,其数据实际上是存储在RAM中,它使用一部分内存空间来模拟出一个磁盘设备,并以块设备的方式来组织和访问这片内存.对 ...

  8. Linux 块设备驱动 (一)

    1.块设备的I/O操作特点 字符设备与块设备的区别: 块设备只能以块为单位接受输入和返回输出,而字符设备则以字符为单位. 块设备对于I/O请求有对应的缓冲区,因此它们可以选择以什么顺序进行响应,字符设 ...

  9. Linux块设备驱动(一) _驱动模型

    块设备是Linux三大设备之一,其驱动模型主要针对磁盘,Flash等存储类设备,本文以3.14为蓝本,探讨内核中的块设备驱动模型 框架 下图是Linux中的块设备模型示意图,应用层程序有两种方式访问一 ...

随机推荐

  1. centos7 安装kafka Manager

    1.安装sbt编译环境 curl https://bintray.com/sbt/rpm/rpm |tee /etc/yum.repos.d/bintray-sbt-rpm.repo yum inst ...

  2. Spring的AOP细节理解

    什么是AOP?AOP:是面向切面编程,是对面向对象编程(oop)的一种补充,为什么需要AOP?例如在我们做一个计算器,要求我们每次运行对应的功能(也就是进行运算时)都要输出日志,以便于知道程序是怎么运 ...

  3. mysql IPv4 IPv6

    w如何通过一个mysql方法,而不是借助脚本判断?INET6_ATON(expr) https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-func ...

  4. 01. Java序列化与反序列化简介

    Java对象的序列化与反序列化 ; 给大家讲解一下什么是序列化 & 反序列化  当两个进程进行远程通讯的时候,彼此相互可以发送各种类型的数据,如文本,图片,语音和视频等无论是任何类型,最终都会 ...

  5. 火狐不支持backgroundPosition的js插件

    用js backgroundPositionX,backgroundPositionY设置在firefox下无法识别,用backgroundPosition同样在火狐无法识别.要识别只能用js插件来实 ...

  6. centos7虚拟机克隆

    第一步:克隆 打开VMware,确认已经完成安装配置的centos7虚拟机在关闭状态. 右键点击虚拟机,选择“管理”-“克隆” 原始虚拟机名称为“master”,IP地址为“192.168.80.10 ...

  7. leetcode 去除单链表倒数第k个节点

    Given a linked list, remove the n-th node from the end of list and return its head. Example: Given l ...

  8. 发现一个小技巧:火狐浏览器对phpmyadmin支持更友好

    这段时间ytkah正在迁移服务器(A→B),为了方便起见,直接用phpmyadmin导入数据库.一般我们是用navicat来操作数据库的,但是服务器A设置了权限,无法用navicat连接,只好在浏览器 ...

  9. 单例Singleton模式的两种实现方法

    在设计模式中,有一种叫Singleton模式的,用它可以实现一次只运行一个实例.就是说在程序运行期间,某个类只能有一个实例在运行.这种模式用途比较广泛,会经常用到,下面是Singleton模式的两种实 ...

  10. TQ2440系统介绍入门 、linux系统目录结构

    TQ2440开发板系统安装步骤: 1.先用JTAG线安装BIOS到开发板.下载BIOS,NOR/NAND开关选在NOR位置. 2.linux安装步骤: (1).格式化分区 (2).安装BIOS---& ...