写一个块设备驱动

转载 2012年03月30日 15:17:04

第 8章

+---------------------------------------------------+
|                 写一个块设备驱动                   |
+---------------------------------------------------+
| 作者:赵磊                                         |
| email: zhaoleidd@hotmail.com                      |
+---------------------------------------------------+
| 文章版权归原作者所有。                             |
| 大家可以自由转载这篇文章,但原版权信息必须保留。   |
| 如需用于商业用途,请务必与原作者联系,若因未取得   |
| 授权而收起的版权争议,由侵权者自行负责。           |
+---------------------------------------------------+

本章的目的是让读者继续休息,因此决定仍然搞一些简单的东西

比如:给我们的驱动程序模块加上模块参数,这样在加载模块时,可以通过参数设定块设备的大小

给我们模块加参数的工作不难,这牵涉到 1个宏:
module_param_named(name, value, type, perm)
        name是参数的名称
        value是参数在模块中对应的变量
        type是参数的类型
        perm是参数的权限

如,在模块中添加

int disk_size = 1024;
module_param_named(size, disk_size, int, S_IRUGO);
可以给模块加上名称为 "size"的参数,如果在加载模块是使用 insmod thismodule size=1                    ,那么
在模块代码中 disk_size的值就是 1
相反,如果加载模块时没有指定参数,那么模块代码中disk_size的值仍是默认的 1024
S_IRUGO指定了这个参数的值在模块加载以后可以被所有人通过/sys/module/
[module_name]/parameters/看到,但无法修改

----------------------- Page 61-----------------------

好了,有关 module_param_named就介绍到这里,细节可以 google或者看
linux/include/linux/moduleparam.h

然后我们就要给这个模块加个参数,用来在加载时指定块设备的大小

参数的名字都已经想好了,就叫size吧,类型嘛,32位无符号整数最大能设定到 4G ,而我们的野心看

起来可能更大一些,

为了让这个模块支持 4G以上的虚拟磁盘(当然是内存足够的情况下) ,我们打算使用 64位无符号整型
这样能够设定的最大值为 16777216T ,应该够了吧

然后我们试图找出module_param_named的参数中与 unsigned long long对应的 type来
结果是:google了,没找到;看 linux/include/linux/moduleparam.h了,还是没找到
结论是:目前的 linux(2.6.28)还不支持 unsigned long long类型的模块参数

更新一些的内核中会不会有是将来的事,尽快搞定这一章的功能却是现在面临的问题

然后我们就开始找解决方案:

1 :给内核打个补丁,看样子不错,但至少今天之类完成不了我们的程序了
   并且这样一来,我们的程序只能在今后的内核中运行,而失去对旧版 linux的兼容性
2 :指定设置磁盘大小的单位为 M。这样可设置的最大的数字就成了 4G*1M ,也就是4096T
   这个主意看似不错。而且看样子1 年内机器的内存应该到不了这个容量
3 :用字符串来指定大小
   这倒是可以解决所有问题,并且我们可以支持 16M、1G之类的设定,让我们的程序看起来比较花哨

   缺点应该是我们需要在程序中自己去解析传入的字符串了,幸运的是,实际的解析代码比想象的容易

一些

因此,我们采用第 3个方案,向模块中添加一个名称为 size、类型为字符串的参数,并且支持解析以
K,M,G,T为单位的设定

第 1步:

  向程序中添加以下参数申明

  static char *simp_blkdev_param_size = "16M";
  module_param_named(size, simp_blkdev_param_size, charp, S_IRUGO);
  char *simp_blkdev_param_size用于存储设定的磁盘大小,我们把磁盘大小的默认值指定为 16M

  目前我们不允许用户在模块加载后改变磁盘大小,将来嘛,有可能增加这一功能,看起来很眩

第 2步:

  原来的程序使用

  #define SIMP_BLKDEV_BYTES      (16*1024*1024)

  定义磁盘大小,而现在我们不需要这一行了

  同时,我们需要一个unsigned long long变量来存储用户设定的磁盘大小,因此我们增加这个变量:

  static unsigned long long simp_blkdev_bytes;
  然后把程序中所有使用 SIMP_BLKDEV_BYTES的位置换成使用 simp_blkdev_bytes变量
第 3步:

----------------------- Page 62-----------------------

  在模块加载时对模块参数进行解析,设置simp_blkdev_bytes变量的值

  我们增加一个函数进行解析工作:

int getparam(void)
{
        char unit;
        char tailc;

        if (sscanf(simp_blkdev_param_size, "%llu%c%c", &simp_blkdev_bytes,
                &unit, &tailc) != 2) {
                return -EINVAL;
        }

        if (!simp_blkdev_bytes)
                return -EINVAL;

        switch (unit) {
        case 'g':
        case 'G':
                simp_blkdev_bytes <<= 30;
                break;
        case 'm':
        case 'M':
                simp_blkdev_bytes <<= 20;
                break;
        case 'k':
        case 'K':
                simp_blkdev_bytes <<= 10;
                break;
        case 'b':
        case 'B':
                break;
        default:
                return -EINVAL;
        }

        /* make simp_blkdev_bytes fits sector's size */
        simp_blkdev_bytes = (simp_blkdev_bytes + (1<<9) - 1) & ~((1ULL<<9) - 1);

        return 0;
}
然后在 simp_blkdev_init()中调用这个函数:
ret = getparam();

----------------------- Page 63-----------------------

if (IS_ERR_VALUE(ret))
        goto err_getparam;
当然,err_getparam的位置读者应该能猜出来了

这样一来,工作大概就完成了,让我们看看结果:

使用默认值:

# insmod simp_blkdev.ko
# fdisk /dev/simp_blkdev
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF 
disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.

Warning: invalid flag 0x         of partition table 4 will be corrected by w(rite)

Command (m for help): p

Disk /dev/simp_blkdev: 16 MB, 16777216 bytes
1 heads, 32 sectors/track, 1024 cylinders
Units = cylinders of 32 * 512 = 16384 bytes

           Device Boot      Start         End      Blocks   Id  System

Command (m for help): q

#
设定成 20M :
# rmmod simp_blkdev
# insmod simp_blkdev.ko size=20M
# fdisk /dev/simp_blkdev
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF 
disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.

The number of cylinders for this disk is set to 1280.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
    (e.g., DOS FDISK, OS/2 FDISK)

----------------------- Page 64-----------------------

Warning: invalid flag 0x       of partition table 4 will be corrected by w(rite)

Command (m for help): p

Disk /dev/simp_blkdev: 20 MB, 20971520 bytes
1 heads, 32 sectors/track, 1280 cylinders
Units = cylinders of 32 * 512 = 16384 bytes

           Device Boot      Start         End      Blocks   Id  System

Command (m for help): q

#
变态一下,还是设定成 20M ,但用k作单位:
# rmmod simp_blkdev
# insmod simp_blkdev.ko size=20480k
# fdisk /dev/simp_blkdev
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF 
disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.

The number of cylinders for this disk is set to 1280.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
    (e.g., DOS FDISK, OS/2 FDISK)
Warning: invalid flag 0x       of partition table 4 will be corrected by w(rite)

Command (m for help): p

Disk /dev/simp_blkdev: 20 MB, 20971520 bytes
1 heads, 32 sectors/track, 1280 cylinders
Units = cylinders of 32 * 512 = 16384 bytes

           Device Boot      Start         End      Blocks   Id  System

Command (m for help): q

#

----------------------- Page 65-----------------------

看样子结果不错

这一章中基本上没有提到什么比较晦涩的知识,而且看样子通过这一章的学习,大家也应该休息好了

如果读者现在感觉到精神百倍,那么这一章的目的应该就达到了

<未完,待续>


写一个块设备驱动程序

----------------------- Page 1----------------------- 第 1章 +----------------------------------...
  • leopard21
  • leopard21
  • 2014年03月01日 00:16
  • 1120

块设备驱动架构分析

1. 块设备概念:块设备是指只能以块为单位进行访问的设备,块的大小一般是512个字节的整数倍。常见的块设备包括硬件,SD卡,光盘等。 2. 块设备驱动的系统架构 2.1 系统架构---VFS VFS是...
  • coding__madman
  • coding__madman
  • 2016年06月06日 22:34
  • 3679

通过内存模拟硬盘实现一个简单的块设备驱动

本文的主要工作是通过硬盘来模拟内存,按照块设备驱动编程的框架实现一个简单的块设备驱动程序。 一、前期的准备工作 1、基本开发环境 Linux内核版本:Linux-3.4.10 开发板 ...
  • TECH_PRO
  • TECH_PRO
  • 2017年05月22日 12:54
  • 652

Linux块设备驱动总结

《Linux设备驱动程序》第十六章 块设备驱动程序读书笔记 简介 一个块设备驱动程序主要通过传输固定大小的随机数据来访问设备 Linux内核视块设备为与字符设备相异的基本设备类型 Linu...
  • bcbobo21cn
  • bcbobo21cn
  • 2016年03月26日 08:36
  • 1389

写一个块设备驱动

----------------------- Page 1----------------------- 第 1章 +----------------------------------...
  • u011305802
  • u011305802
  • 2013年07月04日 18:16
  • 1241

块设备和字符设备驱动比较

块设备和字符设备驱动比较 Linux中I/O设备分为两类:块设备和字符设备。两种设备本身没有严格限制,但是,基于不同的功能进行了分类。 (1) 字符设备:提供连续的数据流,应用程序可以顺序读取,通...
  • u013177084
  • u013177084
  • 2014年09月12日 22:16
  • 818

linux块设备驱动之实例

前两篇blog已经基本熟悉了块设备的相关结构,这里来总结下ldd3中提到的一些块设备驱动例题; 注册: sbull_major = register_blkdev(sbull_ma...
  • YuZhiHui_No1
  • YuZhiHui_No1
  • 2015年07月13日 00:39
  • 1905

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

http://www.cnblogs.com/xiaojiang1025/p/6500557.html 块设备是Linux三大设备之一,其驱动模型主要针对磁盘,Flash等存储类...
  • zdy0_2004
  • zdy0_2004
  • 2017年03月21日 21:10
  • 655

《Linux设备驱动程序》——块设备驱动程序

块设备驱动程序
  • Explorer_day
  • Explorer_day
  • 2014年12月05日 11:29
  • 1304

块设备驱动程序之一

一、块设备概述 linux支持的两种重要的设备类型分别是字符设备和块设备,块设备可以随机地以固定大小的块传送数据。与字符设备相比,块设备有以下几个特殊之处: 块设备可以从数据的任何位置进行访问块数据...
  • goodluckwhh
  • goodluckwhh
  • 2014年02月10日 23:41
  • 4181
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:写一个块设备驱动
举报原因:
原因补充:

(最多只允许输入30个字)