注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小白的博客

嵌入式爱好者

 
 
 

日志

 
 

内存模拟磁盘之函数分析  

2012-09-22 14:57:47|  分类: 韦东山视频第二轮 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
为了加深对这个程序的理解,我们简单对内核分析一下上一节里面遇到的一些函数

1、register_blkdev(unsigned int major, const char *name)

register_blkdev(unsigned int major, const char *name)
      for (index = ARRAY_SIZE(major_names)-1; index > 0; index--)//遍历找到一个没有用的主设备号,主设备是0---255
              if (major_names[index] == NULL)
                     major = index;
      index = major_to_index(major);                           //可见index为0
              return major % CHRDEV_MAJOR_HASH_SIZE;
                      #define CHRDEV_MAJOR_HASH_SIZE 255
      for (n = &major_names[index]; *n; n = &(*n)->next)
              if ((*n)->major == major)//遍历major_names,找到相同名字的或者遍历完没找到都会退出循环
                     break;
      if (!*n)
            *n = p;  //如果是没找到退出的,就会将p加入链表,p里面是本块设备的名字和主设备号信息
      else 
             ret = -EBUSY; //如果是因为找到同名的而退出的,就会出错返回

由此我们可以看出:register_blkdev这个函数只是去分配一个没有用的主设备号,以及防止块设备名字相同,其他什么都没有做!

2、request_queue *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)
request_queue *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)
          blk_init_queue_node(rfn, lock, -1);
                //分配一个请求队列节点
                uninit_q= kmem_cache_alloc_node(blk_requestq_cachep,gfp_mask | __GFP_ZERO, node_id);
                q = blk_init_allocated_queue(uninit_q, rfn, lock);
                         q->request_fn = rfn;        //我们分析过,读写磁盘的时候会调用请求队列里面的request_fn,这个函数由我们自己实现
                         q->queue_lock = lock;   //还需要自旋锁
                         blk_queue_make_request(q, blk_queue_bio);//这里定义默认的构造请求的函数

我们看到这个函数主要是做了三件事情:一是定义了构造请求的函数,而是构造了队列处理函数,三是自旋锁!

3、inline void set_capacity(struct gendisk *disk, sector_t size)
inline void set_capacity(struct gendisk *disk, sector_t size)
      disk->part0.nr_sects = size; 
这个函数的功能就是设置磁盘的容量,表示磁盘有几个扇区!

4、add_disk(struct gendisk *disk)
add_disk(struct gendisk *disk)
      disk->major = MAJOR(devt);
      disk->first_minor = MINOR(devt);
      blk_register_region(disk_devt(disk), disk->minors, NULL,exact_match, exact_lock, disk);
      register_disk(disk);
             dev_set_name(ddev, disk->disk_name);
             device_add(ddev)
                   //在/sys/block目录下生成了ramblolk目录
                   kobject_add(&dev->kobj, dev->kobj.parent, NULL);
             //建立反连接,连接到/sys/block/ramblolk/device
             ysfs_create_link(block_depr, &ddev->kobj,kobject_name(&ddev->kobj));
             if (!get_capacity(disk)) 
             goto exit;
      blk_register_queue(disk);
            elv_register_queue(q);//以电梯调度算法注册请求队列

从这个函数分析里面我们大体可以看出为什么要在init函数里面为磁盘进行那些设置,那些设置都是不可少的!
  评论这张
 
阅读(989)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017