输入子系统(一)字符设备驱动框架分析
很多分析输入子系统的文章已经讲得很清楚了,这里主要是记录自己的学习过程。参考的几篇文章:
输入子系统也是字符设备驱动,也遵循字符设备驱动的流程:
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\n"); 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\n"); 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 }
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 }
上面的分析没有看到调用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 }
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 }
1 int device_register(struct device *dev) 2 { 3 device_initialize(dev); 4 return device_add(dev); 5 }