zoukankan      html  css  js  c++  java
  • linux 输入子系统(4)---- input子系统的初始化

    Input子系统的初始化函数为input_init(),如下:

    static int __init input_init(void)
    {
        int err;
    
        input_init_abs_bypass();
    
        err = class_register(&input_class);
        if (err) {
            printk(KERN_ERR "input: unable to register input_dev class
    ");
            return err;
        }
    
        err = input_proc_init();
        if (err)
            goto fail1;
    
        err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
        if (err) {
            printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
            goto fail2;
        }
    
        return 0;
    
     fail2:    input_proc_exit();
     fail1:    class_unregister(&input_class);
        return err;
    }

     在这个初始化函数里,先注册了一个名为”input”的类.所有input device都属于这个类.在sysfs中表现就是.所有input device所代表的目录都位于/dev/class/input下面.

    然后调用input_proc_init()在/proc下面建立相关的交互文件.

    再后调用register_chrdev()注册了主设备号为INPUT_MAJOR(13).次设备号为0~255的字符设备.它的操作指针为input_fops.
    在这里,我们看到.所有主设备号13的字符设备的操作最终都会转入到input_fops中./dev/input/event0~/dev/input/event4的主设备号为13.操作也不例外的落在了input_fops中.
     
    Input_fops定义如下:
    static const struct file_operations input_fops = {
        .owner = THIS_MODULE,
        .open = input_open_file,
    };

     打开文件所对应的操作函数为input_open_file.代码如下示:

    static int input_open_file(struct inode *inode, struct file *file)
    {
        struct input_handler *handler;
        const struct file_operations *old_fops, *new_fops = NULL;
        int err;
    
        err = mutex_lock_interruptible(&input_mutex);
        if (err)
            return err;
    
        /* No load-on-demand here? */
        handler = input_table[iminor(inode) >> 5];
        if (handler)
            new_fops = fops_get(handler->fops);
    
        mutex_unlock(&input_mutex);
    
        /*
         * That's _really_ odd. Usually NULL ->open means "nothing special",
         * not "no device". Oh, well...
         */
        if (!new_fops || !new_fops->open) {
            fops_put(new_fops);
            err = -ENODEV;
            goto out;
        }
    
        old_fops = file->f_op;
        file->f_op = new_fops;
    
        err = new_fops->open(inode, file);
        if (err) {
            fops_put(file->f_op);
            file->f_op = fops_get(old_fops);
        }
        fops_put(old_fops);
    out:
        return err;
    }

     iminor(inode)为打开文件所对应的次设备号.input_table是一个struct  input_handler全局数组.在这里.它先设备结点的次设备号右移5位做为索引值到input_table中取对应项.从这里我们也可以看到.一 个handle代表1<<5个设备节点(因为在input_table中取值是以次备号右移5位为索引的.即低5位相同的次备号对应的是同一 个索引).在这里,终于看到了input_talbe大显身手的地方了.input_talbe[ ]中取值和input_talbe[  ]的赋值,这两个过程是相对应的.

     在input_table中找到对应的handler之后,就会检验这个handle是否存,是否带有fops文件操作集.如果没有.则返回一个设备不存在的错误.
    然后将handler中的fops替换掉当前的fops.如果新的fops中有open()函数,则调用它.
  • 相关阅读:
    PHP AES256加密算法
    PHP字符串比较
    linux常用命令
    播放音乐方法(兼容IE FF Chrome Opera Safari)
    JS小游戏象棋暗棋
    Sublime Text 2 介紹
    php生成QRcode
    几种极其隐蔽的XSS注入的防护
    JS判断碰撞方法
    php 发送带附件邮件
  • 原文地址:https://www.cnblogs.com/hello2mhb/p/3366751.html
Copyright © 2011-2022 走看看