Android Init Process Analysis Ueventd

Source: Internet
Author: User

Transferred from: http://blog.csdn.net/freshui/article/details/2132299

(Lazy people recently think of me and csdn for a long time, this Android init is lying in my draft box for almost 5 years, a little change to send it out)

UEVENTD is mainly responsible for the creation of device nodes, permission settings and other tasks. The service uses Uevent to monitor the messages sent by the driver for further processing.
Ueventd Actual and Init are the same binary, just walk the different branches and see the previous section.

Ueventd's overall code is relatively simple, mainly three parts:

    • Parsing ueventd.rc
    • Initializing device information
    • Looping polling uevent messages

The main functions and related functions are as follows:

[CPP]View PlainCopy
  1. int Ueventd_main (int argc, char **argv)
  2. {
  3. //As with INIT, no std input and output
  4. Open_devnull_stdio ();
  5. //Initialize kernel log, let Ueventd log output to the string via kernel PRINTK log
  6. Klog_init ();
  7. //parsing and processing of UEVENTD RC files
  8. Import_kernel_cmdline (0, Import_kernel_nv);
  9. Get_hardware_name (Hardware, &revision);
  10. Ueventd_parse_config_file ("/ueventd.rc");
  11. SNPRINTF (TMP, sizeof (TMP), "/ueventd.%s.rc", hardware);
  12. Ueventd_parse_config_file (TMP);
  13. //Device initialization
  14. Device_init ();
  15. //Polling uevent messages to manage the device
  16. Ufd.events = Pollin;
  17. UFD.FD = GET_DEVICE_FD ();
  18. While (1) {
  19. ufd.revents = 0;
  20. NR = Poll (&UFD, 1,-1);
  21. if (nr <= 0)
  22. continue;
  23. if (ufd.revents = = Pollin)
  24. HANDLE_DEVICE_FD (); //Polling to message, handling event message
  25. }
  26. }

Processing and parsing ueventd.rc
This part compared to init.rc, giant simple, nothing special. Mainly through the RC file, to control the permissions of the directory node. Such as:

[Plain]View PlainCopy
    1. /DEV/TTYUSB2 0666 Radio Radio
    2. /dev/ts0710mux* 0640 Radio Radio
    3. /DEV/PPP 0666 Radio VPN
    4. # SYSFS Properties
    5. /sys/devices/virtual/input/input* Enable 0666 System system
    6. /sys/devices/virtual/input/input* Poll_delay 0666 System System

Details should not need to be expanded, basically can understand.

Device initialization
Kernel when the device is loaded, the Uevent event is sent through the socket to userspace, in Init, to create the node of the device by accepting these uevent events. The main function is Device_init ()

The initialization function is Device_init, as follows

[CPP]View PlainCopy
  1. void Device_init (void)
  2. {
  3. suseconds_t t0, T1;
  4. struct STAT info;
  5. int fd;
  6. Sehandle = NULL;
  7. if (is_selinux_enabled () > 0) {
  8. Sehandle = Selinux_android_file_context_handle ();
  9. }
  10. / * is 256K enough udev uses 16mb! * /
  11. DEVICE_FD = Uevent_open_socket (256*1024, true);
  12. if (device_fd < 0)
  13. return;
  14. Fcntl (DEVICE_FD, F_SETFD, fd_cloexec);
  15. Fcntl (DEVICE_FD, F_SETFL, O_nonblock);
  16. if (stat (Coldboot_done, &info) < 0) {
  17. T0 = Get_usecs ();
  18. Coldboot ("/sys/class");
  19. Coldboot ("/sys/block");
  20. Coldboot ("/sys/devices");
  21. T1 = Get_usecs ();
  22. FD = open (Coldboot_done, o_wronly| o_creat, 0000);
  23. Close (FD);
  24. Log_event_print ("Coldboot%ld us\n", ((long) (t1-t0)));
  25. } Else {
  26. Log_event_print ("Skipping coldboot, already done\n");
  27. }
  28. }

Open_uevent_socket ();
This is the socket that opens the uevent. The uevent here is used to netlink the kernel event to the User state notification (netlink_kobject_uevent) function, is the kernel and the user configuration for two-way data transmission of the very good way, in addition to eventd outside, NETD and Vold are also used in uevent.
In the initialization function, the comparison to pay attention to the Coldboot this function, the literal meaning is cold start, it is the role of those in the Uventd before the start, already add on the driver, and then re-operation, let them send an event message, the upper number targeted processing.
Here, the devices under/sys/class,/sys/block and/sys/devices are traversed again:

[CPP]View PlainCopy
  1. static void Do_coldboot (DIR *d)
  2. {
  3. struct dirent *de;
  4. int DFD, FD;
  5. DFD = DIRFD (d);
  6. FD = Openat (DFD, "Uevent", o_wronly);
  7. if (fd >= 0) {
  8. Write (FD, "add\n", 4);
  9. Close (FD);
  10. HANDLE_DEVICE_FD ();
  11. }
  12. While ((de = Readdir (d))) {
  13. DIR *d2;
  14. if (de->d_type! = Dt_dir | | de->d_name[0] = = '. ')
  15. continue;
  16. FD = Openat (DFD, de->d_name, O_rdonly | O_directory);
  17. if (FD < 0)
  18. continue;
  19. D2 = Fdopendir (FD);
  20. if (D2 = = 0)
  21. Close (FD);
  22. else {
  23. Do_coldboot (D2);
  24. Closedir (D2);
  25. }
  26. }
  27. }

Write (FD, "add\n", 4) activates the kernel, re-sends the UEVENT,HANDLE_DEVICE_FD () of the Add event, and responds to the event message.

Uevent Message Processing

After the initialization is good, daemon program as long as polling new event events, polling to, call HANDLE_DEVICE_FD (), to handle, you can look at this function:

[CPP]View PlainCopy
  1. void Handle_device_fd ()
  2. {
  3. Char msg[uevent_msg_len+2];
  4. int n;
  5. While ((n = uevent_kernel_multicast_recv (DEVICE_FD, MSG, uevent_msg_len)) > 0) {
  6. if (n >= uevent_msg_len) /* Overflow--Discard * /
  7. continue;
  8. Msg[n] = ' + ';
  9. MSG[N+1] = ' + ';
  10. struct uevent uevent;
  11. Parse_event (msg, &uevent);
  12. Handle_device_event (&uevent);
  13. Handle_firmware_event (&uevent);
  14. }
  15. }

The function is to accept the inside of the event message, and then parser this message to process the corresponding message event.

Over here:

[CPP]View PlainCopy
  1. static void handle_device_event (struct uevent *uevent)
  2. {
  3. if (!strcmp (Uevent->action,"add") | |!strcmp (uevent->action, "Change"))
  4. Fixup_sys_perms (Uevent->path);
  5. if (!strncmp (Uevent->subsystem, "block", 5)) {
  6. Handle_block_device_event (uevent);
  7. } Else if (!strncmp (Uevent->subsystem, "platform", 8)) {
  8. Handle_platform_device_event (uevent);
  9. } Else {
  10. Handle_generic_device_event (uevent);
  11. }
  12. }

The main function is to create/delete device nodes based on the uevent sent, and update some node permissions with the permission settings described in Ueventd.rc.

[CPP]View PlainCopy
  1. static void handle_firmware_event (struct uevent *uevent)
  2. {
  3. pid_t pid;
  4. int ret;
  5. if (strcmp (Uevent->subsystem, "firmware"))
  6. return;
  7. if (strcmp (Uevent->action, "Add"))
  8. return;
  9. / * We fork, to avoid making large memory allocations in init proper * /
  10. PID = fork ();
  11. if (!pid) {
  12. Process_firmware_event (uevent);
  13. Exit (exit_success);
  14. }
  15. }

If there is a coprocessor, but also to download the coprocessor firmware, here is the processing coprocessor to download firmware instructions, fork a child process processing.

Android Init Process Analysis Ueventd

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.