输入子系统(一)字符设备驱动框架分析

很多分析输入子系统的文章已经讲得很清楚了,这里主要是记录自己的学习过程。参考的几篇文章:

输入子系统学习笔记之按键实例编程

输入子系统学习笔记之源码分析1_框架性分析

输入子系统学习笔记之源码分析2_数据结构分析

输入子系统学习笔记之源码分析3_流程分析

输入子系统也是字符设备驱动,也遵循字符设备驱动的流程:

a. 分配主设备号

b. 构建file_operations结构体中的open,write,read...等函数

c. 调用register_chrdev()函数注册字符设备

d. 调用class_register()注册类

e. 调用device_create()创建设备,linux会在sysfs目录下自动创建字符设备。

以上的步骤同样适用于分析输入子系统,只不过上面的各个步骤可能分散在不同的文件与函数中完成。

1. input.c中的函数input_init()完成上述a,b,c,d四步。

 1 /*
 2 *b. 构建file_operations结构体,只实现了open函数
 3 */
 4 static const struct file_operations input_fops = {
 5     .owner = THIS_MODULE,
 6     .open = input_open_file,
 7     .llseek = noop_llseek,
 8 };
 9 
10 static int __init input_init(void)
11 {
12     int err;
13 
14     err = class_register(&input_class);/*d. 调用class_register()注册类*/
15     if (err) {
16         pr_err("unable to register input_dev class
");
17         return err;
18     }
19 
20     err = input_proc_init();
21     if (err)
22         goto fail1;
23     /*
24     *a. 分配主设备号INPUT_MAJOR=13
25     *c. 调用register_chrdev()函数注册字符设备
26     */
27     err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
28     if (err) {
29         pr_err("unable to register char major %d", INPUT_MAJOR);
30         goto fail2;
31     }
32 
33     return 0;
34 
35  fail2:    input_proc_exit();
36  fail1:    class_unregister(&input_class);
37     return err;
38 }

2. 那么谁来调用device_create()创建设备?这里直接给出结论,后面再分析过程。

handler->connect函数中会完成设备的创建工作。这里已 evdev_connect()函数为例来分析。

static int evdev_connect(struct input_handler *handler, struct input_dev *dev,const struct input_device_id *id)

  -->for (minor = 0; minor < EVDEV_MINORS; minor++)  确定次设备号

    if (!evdev_table[minor]) break;

  -->evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);确定设备号

  -->evdev->dev.class = &input_class;

  -->dev_set_name(&evdev->dev, "event%d", minor);  设置设备名字

    -->kobject_set_name_vargs(&dev->kobj, fmt, vargs);

  -->device_initialize(&evdev->dev);

  -->device_add(&evdev->dev);

 1 static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
 2              const struct input_device_id *id)
 3 {
 4     struct evdev *evdev;
 5     int minor;
 6     int error;
 7 
 8     for (minor = 0; minor < EVDEV_MINORS; minor++)
 9         if (!evdev_table[minor])
10             break;
11 
12     if (minor == EVDEV_MINORS) {
13         pr_err("no more free evdev devices
");
14         return -ENFILE;
15     }
16 
17     evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
18     if (!evdev)
19         return -ENOMEM;
20 
21     INIT_LIST_HEAD(&evdev->client_list);
22     spin_lock_init(&evdev->client_lock);
23     mutex_init(&evdev->mutex);
24     init_waitqueue_head(&evdev->wait);
25 
26     dev_set_name(&evdev->dev, "event%d", minor);
27     evdev->exist = true;
28     evdev->minor = minor;
29 
30     evdev->handle.dev = input_get_device(dev);
31     evdev->handle.name = dev_name(&evdev->dev);
32     evdev->handle.handler = handler;
33     evdev->handle.private = evdev;
34 
35     evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
36     evdev->dev.class = &input_class;
37     evdev->dev.parent = &dev->dev;
38     evdev->dev.release = evdev_free;
39     device_initialize(&evdev->dev);
40 
41     error = input_register_handle(&evdev->handle);
42     if (error)
43         goto err_free_evdev;
44 
45     error = evdev_install_chrdev(evdev);
46     if (error)
47         goto err_unregister_handle;
48 
49     error = device_add(&evdev->dev);
50     if (error)
51         goto err_cleanup_evdev;
52 
53     return 0;
54 
55  err_cleanup_evdev:
56     evdev_cleanup(evdev);
57  err_unregister_handle:
58     input_unregister_handle(&evdev->handle);
59  err_free_evdev:
60     put_device(&evdev->dev);
61     return error;
62 }
evdev_connect()
 1 int dev_set_name(struct device *dev, const char *fmt, ...)
 2 {
 3     va_list vargs;
 4     int err;
 5 
 6     va_start(vargs, fmt);
 7     err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
 8     va_end(vargs);
 9     return err;
10 }
dev_set_name()

上面的分析没有看到调用device_create()函数,但分析device_create()函数可知起始上面的步骤和device_create()内执行的一致。

struct device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)

  -->device_create_vargs(class, parent, devt, drvdata, fmt, vargs);

    -->dev->class = class;

    -->dev->devt = devt;

    -->kobject_set_name_vargs(&dev->kobj, fmt, args);

    -->device_register(dev);

      -->device_initialize(dev);

      -->device_add(dev);

 1 struct device *device_create(struct class *class, struct device *parent,
 2                  dev_t devt, void *drvdata, const char *fmt, ...)
 3 {
 4     va_list vargs;
 5     struct device *dev;
 6 
 7     va_start(vargs, fmt);
 8     dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
 9     va_end(vargs);
10     return dev;
11 }
device_create()
 1 struct device *device_create_vargs(struct class *class, struct device *parent,
 2                    dev_t devt, void *drvdata, const char *fmt,
 3                    va_list args)
 4 {
 5     struct device *dev = NULL;
 6     int retval = -ENODEV;
 7 
 8     if (class == NULL || IS_ERR(class))
 9         goto error;
10 
11     dev = kzalloc(sizeof(*dev), GFP_KERNEL);
12     if (!dev) {
13         retval = -ENOMEM;
14         goto error;
15     }
16 
17     dev->devt = devt;
18     dev->class = class;
19     dev->parent = parent;
20     dev->release = device_create_release;
21     dev_set_drvdata(dev, drvdata);
22 
23     retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
24     if (retval)
25         goto error;
26 
27     retval = device_register(dev);
28     if (retval)
29         goto error;
30 
31     return dev;
32 
33 error:
34     put_device(dev);
35     return ERR_PTR(retval);
36 }
device_create_vargs()
1 int device_register(struct device *dev)
2 {
3     device_initialize(dev);
4     return device_add(dev);
5 }
device_register()
原文地址:https://www.cnblogs.com/yangjiguang/p/6041500.html