MISC 设备动态次设备号分析

转自:http://blog.csdn.net/yongan1006/article/details/6778285

 

今天看驱动源码时,发现一个MISC_DYNAMIC_MINOR宏,于是分析了一下内核源码。先粘出源码。在misc_register函数中,有如下语句:

   

    if (misc->minor == MISC_DYNAMIC_MINOR) {
              int i = DYNAMIC_MINORS;
              while (--i >= 0)
                     if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
                            break;
              if (i<0) {
                     mutex_unlock(&misc_mtx);
                     return -EBUSY;
              }
              misc->minor = i;
       }
 
       if (misc->minor < DYNAMIC_MINORS)
              misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
       dev = MKDEV(MISC_MAJOR, misc->minor);

宏定义MISC_DYNAMIC_MINOR=255DYNAMIC_MINORS=64

misc_minors定义static unsigned char misc_minors[DYNAMIC_MINORS / 8];是一个char型的数组。代码的关键是看懂(misc_minors[i>>3] & (1 << (i&7))) == 0。为了方便分析,本人写了一个分析ii&7的值的程序

#include
void main()
{
       int i=64;
       int j;
       int l;
       while(--i>=0)
       {
              j=i>>3;
              l=1<<(i&7);
              cout<<"j's valule is: "<<j<<endl;
              cout<<"l's valule is: "<<l<<endl;
              cout<<"i's valule is: "<<i<<endl;
       }
}

运行结果:

……

……


       基于以上运行结果我们可以看出:

j的值是从7递减到0j每减一个值,l的值循环一次出现1286432168421

i的值则是从63一直减到0

所以我们可以得出以下几个结论

1.       misc_minors[i>>3]这个char型数组有8个成员,每个成员是一个8位的数(因为j是从7减到0)

2.       (1 << (i&7))),当i减小1时,(1 << (i&7)))就向右移1位。即出现1286432168421的情况

3.       misc_minors数组成员与i值有对应关系,即misc_minors[7]对应63,62,61……56

misc_minors[6]对应55,54,……48。以些类推。因为misc_minors的成员是8位的数,每一个成员对应8minors,所以很容易这样联想:misc_minors成员的每一位标记一个次设备号(有没有使用过)。

4.       (misc_minors[i>>3] & (1 << (i&7))) == 0意思就是将misc_minors数组中8个成员的每个成员的每一位遍历一遍,看是否为0

 

看懂了(misc_minors[i>>3] & (1 << (i&7))) == 0的意思后往下看,如果条件成立,就—i,如果是就将i赋给minor。这就说明,此前的联想是正确的。位是0就代表没有使用过这个次设备号,位1是代表使用过这个次设备号。所以在下面的代码中还可以看到,如果得到了一个次设备号后,就要马上将代表这个次设备号的位标记为1。但是使用MISC_DYNAMIC_MINOR这个宏有一个限制:你的次设备号不会超过63

分析完毕。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 中的 misc 是一种杂项设备类型,它可以用来创建一些没有特定驱动程序的设备文件,例如 /dev/null 和 /dev/random。 要创建一个 misc 设备,可以使用 misc_register() 函数,该函数需要一个 miscdevice 结构体作为参数,其中包含设备的名称、设备等信息。然后,可以使用 misc_deregister() 函数来注销设备。 下面是一个简单的示例程序,用于创建一个名为 mymiscmisc 设备: ```c #include <linux/module.h> #include <linux/miscdevice.h> static int mymisc_open(struct inode *inode, struct file *file) { printk(KERN_INFO "mymisc: device opened\n"); return 0; } static int mymisc_release(struct inode *inode, struct file *file) { printk(KERN_INFO "mymisc: device closed\n"); return 0; } static const struct file_operations mymisc_fops = { .owner = THIS_MODULE, .open = mymisc_open, .release = mymisc_release, }; static struct miscdevice mymisc_device = { .minor = MISC_DYNAMIC_MINOR, .name = "mymisc", .fops = &mymisc_fops, }; static int __init mymisc_init(void) { int ret; ret = misc_register(&mymisc_device); if (ret) { printk(KERN_ERR "mymisc: unable to register device\n"); return ret; } printk(KERN_INFO "mymisc: device registered\n"); return 0; } static void __exit mymisc_exit(void) { misc_deregister(&mymisc_device); printk(KERN_INFO "mymisc: device unregistered\n"); } module_init(mymisc_init); module_exit(mymisc_exit); MODULE_LICENSE("GPL"); ``` 编译并安装模块后,可以使用以下命令来查看设备文件: ``` $ ls -l /dev/mymisc crw------- 1 root root 10, 58 May 22 15:08 /dev/mymisc ``` 可以使用 cat 命令来测试设备: ``` $ cat /dev/mymisc mymisc: device opened mymisc: device closed ``` 这里的输出是由 mymisc_open() 和 mymisc_release() 函数生成的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值