Chinaunix首页 | 论坛 | 博客
  • 博客访问: 222243
  • 博文数量: 86
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 256
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-12 15:39
文章分类

全部博文(86)

文章存档

2016年(20)

2015年(65)

2014年(1)

我的朋友

分类: LINUX

2015-07-30 15:52:32

看完了block子系统的初始化之后,我曾一度迷茫过,也曾辗转反侧,,我完全不知道下一步该怎么走,几经思索,思索着我和中国的未来,徘徊过后,彷徨过后,终于决定,scsi disk驱动同步进行往下走,因为scsi disk那边会调用许多block层这边提供的函数,于是我们就在这边来看看这些函数究竟是干什么的.

第一个函数当然就是register_blkdev().

     55 int register_blkdev(unsigned int major, const char *name)

     56 {

     57         struct blk_major_name **n, *p;

     58         int index, ret = 0;

     59

     60         mutex_lock(&block_subsys_lock);

     61

     62         /* temporary */

     63         if (major == 0) {

     64                 for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) {

     65                         if (major_names[index] == NULL)

     66                                 break;

     67                 }

     68

     69                 if (index == 0) {

     70                         printk("register_blkdev: failed to get major for %s/n",

     71                                name);

     72                         ret = -EBUSY;

     73                         goto out;

     74                 }

     75                 major = index;

     76                 ret = major;

     77         }

     78

     79         p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL);

     80         if (p == NULL) {

     81                 ret = -ENOMEM;

     82                 goto out;

     83         }

     84

     85         p->major = major;

     86         strlcpy(p->name, name, sizeof(p->name));

     87         p->next = NULL;

     88         index = major_to_index(major);

     89

     90         for (n = &major_names[index]; *n; n = &(*n)->next) {

     91                 if ((*n)->major == major)

     92                         break;

     93         }

     94         if (!*n)

     95                 *n = p;

     96         else

     97                 ret = -EBUSY;

     98

     99         if (ret < 0) {

    100                 printk("register_blkdev: cannot get major %d for %s/n",

    101                        major, name);

    102                 kfree(p);

    103         }

    104 out:

    105         mutex_unlock(&block_subsys_lock);

    106         return ret;

    107 }

sd那边调用这个函数来看,咱们是指定了主设备号了的.换言之,这里的major是非零值,struct blk_major_name的定义也在block/genhd.c:

     27 static struct blk_major_name {

     28         struct blk_major_name *next;

     29         int major;

     30         char name[16];

     31 } *major_names[BLKDEV_MAJOR_HASH_SIZE];

注意这里顺便定义了一个数组major_names,咱们这里也用到了.

这其中BLKDEV_MAJOR_HASH_SIZE定义于include/linux/fs.h:

   1575 #define BLKDEV_MAJOR_HASH_SIZE  255

即数组major_names[]255个元素,换言之,咱们定义了255个指针.

88行这个内联函数同样来自block/genhd.c:

     33 /* index in the above - for now: assume no multimajor ranges */

     34 static inline int major_to_index(int major)

     35 {

     36         return major % BLKDEV_MAJOR_HASH_SIZE;

     37 }

比如咱们传递的major8,那么major_to_index就是8.

不难理解,register_blkdev()这个函数做的事情就是,为这255个指针找到归属.即先在79行调用kmalloc申请一个struct blk_major_name结构体并且让p指向它,接下来为p赋值,n将指向major_names[index],比如index就是8,那么n就指向major_names[8],一开始它肯定为空,所以直接执行94行并进而95,于是就把赋好值的p的那个结构体赋给了major_names[8],因此,major_names[8]就既有major也有name,name就是”sd”.

那么此时此刻的效果是什么?告诉你,不是在/dev/目录下面有sda,sdb之类的文件,而是通过/proc/devices能够看到这个块设备驱动注册了.

localhost:/usr/src/linux-2.6.22.1 # cat /proc/devices

Character devices:

  1 mem

  2 pty

  3 ttyp

  4 /dev/vc/0

  4 tty

  4 ttyS

  5 /dev/tty

  5 /dev/console

  5 /dev/ptmx

  7 vcs

 10 misc

 13 input

 21 sg

 29 fb

128 ptm

136 pts

162 raw

180 usb

189 usb_device

254 megaraid_sas_ioctl

 

Block devices:

  1 ramdisk

  3 ide0

  7 loop

  8 sd

  9 md

 65 sd

 66 sd

 67 sd

 68 sd

 69 sd

 70 sd

 71 sd

128 sd

129 sd

130 sd

131 sd

132 sd

133 sd

134 sd

135 sd

253 device-mapper

254 mdp

 


阅读(1539) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~