android4.0 input子系统分析(kernel部分)

一、前言   前面我们分析了android的input子系统的android部分的代码,下面我们继续来分析kernel部分的,对于这个系统kernel部分和标准linux差别不大,   google在原linux基础上增加了一些代码以使其更适合手持设备,比如支持多点触控设备,支持android特有的4个按键等等。我们会一步一步的分析   内核代码,来分析出input系统的工作原理。
摘要由CSDN通过智能技术生成
一、前言
   前面我们分析了android的input子系统的android部分的代码,下面我们继续来分析kernel部分的,对于这个系统kernel部分和标准linux差别不大,
   google在原linux基础上增加了一些代码以使其更适合手持设备,比如支持多点触控设备,支持android特有的4个按键等等。我们会一步一步的分析
   内核代码,来分析出input系统的工作原理。
二、input设备类的注册
    在input系统android部分我们知道了,在android层的eventhub中,建立了一个epoll,来监控/dev/input目录下有效的input设备所有事件,如果有
    事件输入的话就会读出当前事件,然后交给android上层处理。所使用的方法也是 open(),read(),close()的标准方法。因此我们要分析这个input
    系统的话,要从/dev/input下的设备文件分的实现析其,他的实现代码在android\kernel\drivers\input\input.c文件中,input也是内核的一个模块
    我们从模块的初始化看起subsys_initcall(input_init);

    static int __init input_init(void)
    {
        int err;
    
        err = class_register(&input_class);    //注册input设备类--------
        if (err) {                                                  |
            pr_err("unable to register input_dev class\n");         |
            return err;                                             |    
        }                                                           V
        /****************************************************************
        struct class input_class = {
            .name        = "input",
            .devnode    = input_devnode,
        };
        ********************************************************************/
        err = input_proc_init();    //建立input类proc文件系统   见下面
        if (err)
            goto fail1;
    
        err = register_chrdev(INPUT_MAJOR, "input", &input_fops);//注册字符设备驱动,此中包含了设备的具体操作函数 见下面
        if (err) {
            pr_err("unable to register char major %d", INPUT_MAJOR);
            goto fail2;
        }
    
        return 0;
    
     fail2:    input_proc_exit();
     fail1:    class_unregister(&input_class);
        return err;
    }

1.proc文件系统建立

   我们首先对proc文件系统做一个介绍:/proc 文件系统是一个特殊的软件创建的文件系统, 内核用来输出消息到外界./proc 下的每个
   文件都绑到一个内核函数上, 当文件被读的时候即时产生文件内容. 我们已经见到一些这样的文件起作用; 例如, /proc/modules, 常
   常返回当前已加载的模块列表./proc 在 Linux 系统中非常多地应用. 很多现代 Linux 发布中的工具, 例如ps, top, 以及 uptime, 
   从 /proc 中获取它们的信息. 一些设备驱动也通过/proc 输出信息, 你的也可以这样做. /proc 文件系统是动态的, 因此你的模块
   可以在任何时候添加或去除条目.-------Linux 设备驱动 第三版
   input_proc_init()代码在android\kernel\drivers\input\input.c中

  
    static int __init input_proc_init(void)
    {
        struct proc_dir_entry *entry;
    
        proc_bus_input_dir = proc_mkdir("bus/input", NULL);//为input类创建/proc/bus/input目录
        if (!proc_bus_input_dir)        |
            return -ENOMEM;             V
    /*********************************************************************************
    proc_mkdir()函数定义在android\kernel_imx\fs\proc\generic.c中,这个函数调用
    调用proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
    这个函数定义也在这个文件中
    struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode,
    struct proc_dir_entry *parent)
       {
           struct proc_dir_entry *ent;
       
           ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
           if (ent) {
               if (proc_register(parent, ent) < 0) {
                   kfree(ent);
                   ent = NULL;
               }
           }
           return ent;
       }
    函数调用__proc_create()定义在本文件中
        
    static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
                          const char *name,
                          mode_t mode,
                          nlink_t nlink)
    {
        ..................
        if (xlate_proc_name(name, parent, &fn) != 0)//将name整理成/proc/name
            goto out;
    ...................
        //分配内存
        ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
        if (!ent) goto out;
        //初始化这个这个proc子系统
        memset(ent, 0, sizeof(struct proc_dir_entry));
        memcpy(((char *) ent) + sizeof(struct proc_dir_entry), fn, len + 1);
        ent->name = ((char *) ent) + sizeof(*ent);
        ent->namelen = len;
        ent->mode = mode;
        ent->nlink = nlink;
        atomic_set(&ent->count, 1);
        ent->pde_users = 0;
        spin_lock_init(&ent->pde_unload_lock);
        ent->pde_unload_completion = NULL;
        INIT_LIST_HEAD(&ent->pde_openers);//得到队列回首地址
     out:
        return ent;
    }
    到了这里我们就创建好了这个proc文件系统的子目录,下面继续创建设备文件
    **************************************************************************************/
        entry = proc_create("devices", 0, proc_bus_input_dir,   //创建devices这个设备文件
                    &input_devices_fileops);
        if (!entry)
            goto fail1;
    
        entry = proc_create("handlers", 0, proc_bus_input_dir,//创建handlers这个设备文件
                    &input_handlers_fileops);
        if (!entry)
            goto fail2;
    
        return 0;
    
     fail2:    remove_proc_entry("devices", proc_bus_input_dir);
     fail1: remove_proc_entry("bus/input", NULL);
        return -ENOMEM;
    }
    
    这里创建了两个proc文件

a)  我们先看entry = proc_create("devices", 0, proc_bus_input_dir
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值