加入收藏 | 设为首页 | 会员中心 | 我要投稿 佛山站长网 (https://www.0757zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

浅谈Linux 中字符设备的注册 - Linux系统

发布时间:2013-12-08 11:23:56 所属栏目:Linux 来源:站长网
导读:Linux中字符设备的注册过程是比较简单的。我们通常可以调用misc_register()函数来注册一个字符设备。Misc设备是一种字符设备,通过该设备可以将fops请求转发给
Linux中字符设备的注册过程是比较简单的。我们通常可以调用misc_register()函数来注册一个字符设备。Misc设备是一种字符设备,通过该设备可以将fops请求转发给注册的misc设备,从而实现字符设备的功能。用户调用该接口注册Misc字符设备时,可以动态分配设备Minor号,当获取Minor号之后调用class_simple_device_add()或者device_create()函数完成字符设备的创建。Misc字符设备注册函数如下所示:

int misc_register(struct miscdevice * misc)  
{  
    struct miscdevice *c;  
    dev_t dev;  
    int err = 0;  
     
    INIT_LIST_HEAD(&misc->list);  
     
    mutex_lock(&misc_mtx);      //获取misc设备信号量  
    list_for_each_entry(c, &misc_list, list) {  //检查设备是否已经存在  
        if (c->minor == misc->minor) {  
            mutex_unlock(&misc_mtx);  
            return -EBUSY;          //如果设备存在,直接返回  
        }  
    }  
     
    if (misc->minor == MISC_DYNAMIC_MINOR) {    //动态分配分配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->this_device = device_create(misc_class, misc->parent, dev,  
                      "%s", misc->name);        //创建字符设备(Misc设备)  
    if (IS_ERR(misc->this_device)) {  
        err = PTR_ERR(misc->this_device);  
        goto out;  
    }  
     
    /*  
     * Add it to the front, so that later devices can "override"  
     * earlier defaults  
     */
    list_add(&misc->list, &misc_list);  //将设备保存至misc设备链中,设备访问时需要操作该链表  
 out:  
    mutex_unlock(&misc_mtx);  
    return err;  
}

需要注意的是2.6.12内核中创建系统设备时需要调用simple_device的接口class_simple_device_add()。在2.6.23中需要调用device_create()函数完成设备注册。在3.2内核中,simple_device的接口已经不存在了,所以必须调用device_create函数,另外,3.2内核不支持具有相同minor号的字符设备,在2.6.x内核中是支持的。

系统是如何完成fops函数调用的呢?回答这个问题需要分析Misc设备打开过程。在打开Misc设备驱动的时候,Misc设备驱动会根据访问设备的Minor号重定向fops函数集,该程序说明如下:

static int misc_open(struct inode * inode, struct file * file)  
{  
    int minor = iminor(inode);  
    struct miscdevice *c;  
    int err = -ENODEV;  
    const struct file_operations *old_fops, *new_fops = NULL;  
     
    mutex_lock(&misc_mtx);  
     
    list_for_each_entry(c, &misc_list, list) {  //通过minor号来匹配对应的fops函数集  
        if (c->minor == minor) {  
            new_fops = fops_get(c->fops);  
            break;  
        }  
    }  
     
    if (!new_fops) {  
        mutex_unlock(&misc_mtx);  
        request_module("char-major-%d-%d", MISC_MAJOR, minor);  
        mutex_lock(&misc_mtx);  
     
        list_for_each_entry(c, &misc_list, list) {  
            if (c->minor == minor) {  
                new_fops = fops_get(c->fops);  
                break;  
            }  
        }  
        if (!new_fops)  
            goto fail;  
    }  
     
    err = 0;  
    old_fops = file->f_op;  
    file->f_op = new_fops;  //重定向fops函数  
    if (file->f_op->open) {     //打开设备  
        err=file->f_op->open(inode,file);  
        if (err) {  
            fops_put(file->f_op);  
            file->f_op = fops_get(old_fops);  
        }  
    }  
    fops_put(old_fops);  
fail:  
    mutex_unlock(&misc_mtx);  
    return err;  
}

(编辑:佛山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读