Linux Input Subsystem Framework analysis (1)

Source: Internet
Author: User

In Linux input device keyboard, touch screen, mouse, etc. can be used in the input subsystem to achieve the drive. The input subsystem is divided into three layers, the core layer and the device driver layer. The event layer. The core layer and the event layer are implemented by the Linux input subsystem itself, and the device driver layer is implemented by us. We escalate the input event to the core layer input.c at the device driver layer, the core layer finds the matching event layer, passes the event to the event layer processing, and the event layer is processed and passed to the user space.

What we finally have to figure out is how the open and read in the user space are finally handled in the kernel, and who handled the event that escalated to the kernel, and how is it passed to the user space after processing?


The above two graphs are the framework of the input subsystem.

The following example analyzes the workflow of the input subsystem using a key driver.

Device driver Layer:

Call Input_allocate_device () in the Init entry function of the device driver layer, assign return a input_dev struct, populate the struct, call Input_register_device (Button_dev), register the device. Trace Input_register_device such as the following:

List_add_tail (&dev->node, &input_dev_list); Put the INPUT_DEV structure into the input_dev_list list
List_for_each_entry (handler, &input_handler_list, node) traversal input_handler_list Each handler in a linked list

Input_attach_handler (Dev, handler); Compare Input_dev and handler

Input_match_device (handler->id_table, Dev);<*input.c*>
The handler->connect (handler, dev, id);<*input.c*> comparison is done by contrasting handler id_table and Input_dev. If a matching handler is found. Then call handler's Connect method.

Called in the evdev_connect (struct Input_handler *handler, struct input_dev *dev,const struct input_device_id *id) Input_register_handle, call handle before populating member Dev and handler structures in handle.

Evdev->handle.dev = Input_get_device (dev);
Evdev->handle.handler = handler;

in Input_register_handle list_add_tail_rcu (&handle->d_node, &dev->h_list) List_add_tail (& Handle->h_node, &h andler->h_list) Two functions add handle to handler and Dev 's h_list list .

Handle can be found through dev->h_list . Find Handle.handler through handle, the same way. Through Handler->h_list can find handle, and then find Handle.dev.

The key question is coming? What exactly is handler? by whom? handler is the function register of the event layer invocation core layer.

Event layer: (EVDEV.C,KEYBOARD.C,TS.C)

 static struct INPUT_ Handler Evdev_handler = {//handler struct
. Event = evdev_event,
. Connect = Evdev_connect,
. Disconnect = Evdev_disconnect,
. FoPs = &evdev_fops,
. Minor = Evdev_minor_base,
. Name =" Evdev ",
. id_table = Evdev_ids,
};

Call Input_register_handler (&evdev_handler) in the Evdev_init (void) entry function to register the handler, and the handler of the Register will be placed in the input_table[] array.

Core layer: (INPUT.C)

The ingress function of the core layer input_init (void) device input.

When Open is called at the application level, input_open_file (struct inode *inode, struct file *file) is called in the kernel. Based on handler= Input_table[iminor (inode) >> 5]; the corresponding handler of the register is obtained from the array input_table according to the secondary device number of the open file.

New_fops = Fops_get (handler->fops) Gets the new FOP from handler.


File->f_op = New_fops;
Err = New_fops->open (inode, file); Open is finally called Handler->fops->open.

The original device-driven open method is self -written. Now the event layer in the input subsystem helps us to write a device method such as open. Similarly, calling read in the application layer invokes read in the event layer. That is, handler->fops->read, which is evdev_fops. Read, is blocked in read. Until the Input_report_key escalation event is over in the device driver layer:

Input_event (Dev, ev_key, code,!!) Value);

input_handle_event (dev, type, code, value);

Input_pass_event (dev, type, code, value);

handle->handler->event (Handle,type, Code, value); Call the event events method in handler. After processing the escalated item, wake the dormant read and read out the processing result of the event.

Summarize:

Calling open in user space will finally call the open device method of the handler FoPs in the event layer. In detail, the handler to match to EVDEV.C or KEYBOARD.C is based on the id_table of the Input_dev structure populated by the device-driven init entry function.

The user space call to read will call handler's read.

Escalate events to the core layer through input_event in the device driver. Finally, the corresponding handler event method is invoked to handle the events, which are passed through read to the user space.

So we can figure out who called the Open? Who is the call to read?



Linux Input Subsystem Framework analysis (1)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.