zoukankan      html  css  js  c++  java
  • 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 ", ++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");  
  • 相关阅读:
    android 启动报错
    android 百度地图
    android LayoutInflater使用
    spring mvc No mapping found for HTTP request with URI [/web/test.do] in DispatcherServlet with name 'spring'
    sql mysql和sqlserver存在就更新,不存在就插入的写法(转)
    jsp include
    json 解析
    css
    Scrapy组件之item
    Scrapy库安装和项目创建
  • 原文地址:https://www.cnblogs.com/Ph-one/p/8497171.html
Copyright © 2011-2022 走看看