zoukankan      html  css  js  c++  java
  • linux3.4.2内核之块设备驱动

    1. 基本概念:

    扇区(Sectors):任何块设备硬件对数据处理的基本单位。通常,1个扇区的大小为512byte。(对设备而言)

    块  (Blocks):由Linux制定对内核或文件系统等数据处理的基本单位。通常,1个块由1个或多个扇区组成。(对Linux操作系统而言)

    段(Segments):由若干个相邻的块组成。是Linux内存管理机制中一个内存页或者内存页的一部分。

    2. 块设备结构体:

    1 static const struct block_device_operations blk_ops = {
    2     .owner =   THIS_MODULE,
    3     .open =    blk_open,
    4     .release = blk_release,
    5 };

    3. 创建块设备:

    3.1静态创建(主设备号自己定义)

    register_blkdev(MAJOR,"z-block");

    3.2 动态创建(内核自动分配主设备号)

    major = register_blkdev(0,"z-block");

    4. 分配一个gendisk结构体,用来描述磁盘信息

    blkdisk = alloc_disk(3);//磁盘分区数,次设备个数 = 分区数 + 1

    5. 创建队列

            内核驱动访问块设备,进行输入输出操作,都需要发送请求。但有些磁盘请求速度缓慢,影响了读写速度,所以引入了队列。采用电梯算法,先将请求放入队列,优化后执行,提高了块设备的访问速度。

    blk_queue = blk_init_queue(do_request, &blk_spin);

    其中第一个参数是队列的处理函数,第二个参数是队列访问权限的自旋锁。定义如下

    static DEFINE_SPINLOCK(blk_spin); 

    6. 将队列告诉gendisk结构体

    blkdisk->queue = blk_queue;

    7. 确定主、次设备号及操作函数

     blkdisk->first_minor = 0;
     blkdisk->major = major;
     sprintf(blkdisk->disk_name, "zblock");
     blkdisk->fops = &blk_ops;

    注意这里不加sprintf这句话,最后insmod会出错。具体原因我也还不知道。

    8. 定义配磁盘容量(大小)

    set_capacity(blkdisk, SIZE);//设置扇区数

    9. 分配一块空间,作为源/目的

    block_buf = kzalloc(BUFFERSIZE, GFP_KERNEL);  //分配一块空间,作为源/目的

    10. 向内核注册gendisk结构体

    add_disk(blkdisk);

    11. 请求队列处理函数

    11.1 while循环使用elv_next_request()获取申请队列中每个未处理的申请,这是Linux2.6.22.6里的函数,对于linux3.4.2内核,应该使用blk_fetch_request函数;

    11.2 使用rq_data_dir()来获取每个申请的读写命令标志,为 0(READ)表示读, 为1(WRITE)表示写;

    11.3 使用memcp()来读或者写扇区(缓存);

    11.4 linux2.6使用end_request()来结束获取的每个申请,linux3.4.2使用函数__blk_end_request_cur;

    12. 磁盘格式化

    /mnt # mkdosfs /dev/zblock

    13. 挂载磁盘

    /mnt # mount /dev/zblock tmp/

    在tmp/目录下写数据,实际上写到了块设备/dev/zblock里面。cat /dev/zblock > /tmp/zblock.bin就可以将/dev/zblock里的数据传到/tmp/zblock.bin。

    完整程序见https://www.cnblogs.com/zhu-g5may/p/9314403.html

  • 相关阅读:
    基于正方系统的抢课软件教程系列一模拟登录1
    基于正方系统的抢课软件教程系列二正则表达式使用
    基于正方系统的抢课软件教程系列一模拟登录3之验证码识别
    eCos中断模型
    eCos下针对MIPS指令集的backtrace
    开源许可证GPL
    获取ListView中的ImageButton
    Rancher v2.4.8 容器管理平台集群搭建(基于k8s)
    Linux awk 替换文本字符串内容
    go: go.mod file not found in current directory or any parent directory; see 'go help mod 解决
  • 原文地址:https://www.cnblogs.com/zhu-g5may/p/9314362.html
Copyright © 2011-2022 走看看