open系统调用在内核中的流程分析

转自:

http://blog.sina.com.cn/s/blog_523491650100cdd7.html

open系统调用在内核中的流程分析
 
 
真是蛮复杂的,我分三步走,力求讲得比较清楚。
以字符设备为例,相对于块设备要简单些。
基于2.6.26的内核

Understand the Linux Kernel 3rd里面其实都讲到了,所以想再深入的话,可以去参考那本书。


一)驱动注册open函数都干了些什么?

register_chrdev -> cdev_add ->  kobj_map

file: fs/char_dev.c
int register_chrdev(unsigned int major, const char *name,
                   const struct file_operations *fops)
{
       struct char_device_struct *cd;
       struct cdev *cdev;
       char *s;
       int err = -ENOMEM;

       cd = __register_chrdev_region(major, 0, 256, name);
       if (IS_ERR(cd))
               return PTR_ERR(cd);

       cdev = cdev_alloc();
       if (!cdev)
               goto out2;

       cdev->owner = fops->owner;
       cdev->ops =fops;      // 注意,在后面的 chrdev_open会从cdev再得到 fops

...
}

file: fs/char_dev.c
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
       p->dev = dev;
       p->count = count;
       return kobj_map(cdev_map, dev, count, NULL, exact_match,exact_lock, p);
}

file: fs/char_dev.c
static struct kobject *exact_match(dev_t dev, int *part, void*data)
{
       struct cdev *p = data;
       return &p->kobj;
}

file: drivers/base/map.c
int kobj_map(struct kobj_map *domain, dev_t dev, unsigned longrange,
            struct module *module, kobj_probe_t *probe,
            int (*lock)(dev_t, void *), void *data)
{
       unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1;
       unsigned index = MAJOR(dev);
       unsigned i;
       struct probe *p;

       if (n > 255)
               n = 255;

       p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL);

   

你可能感兴趣的:(kernel,kernel)