Analysis on Android 2.1 vold

Source: Internet
Author: User

 

Android vold (volume Daemon)

Daemon for attaching and deleting large-capacity storage devices.

The service is enabled in init. RC:

 

Service vold/system/bin/vold <br/> socket vold stream 0660 root Mount

 

 

This article consists of two parts:

 

· Vold Architecture Analysis

· Vold function Summary

 

1. vold Architecture Analysis

 

Android vold is responsible for receiving information sent by the kernel about loading and deleting external storage devices, and then sending the information to the mountservice at the framework layer. It is also responsible for executing commands sent by mountservice.

The communication between these CMD and MES is mainly implemented through socket communication (the details of socket communication are not described here ).

The following briefly analyzes the implementation of this process from the code perspective:

1.1 In vold. C, first establish communication with the framework layer:

If (door_sock = android_get_control_socket (vold_socket) <0) {<br/> LogE ("obtaining file descriptor socket '% s' failed: % s ", <br/> vold_socket, strerror (errno); <br/> exit (1); <br/>}< br/> If (Listen (door_sock, 4) <0) {<br/> LogE ("unable to listen on FD '% D' for socket' % s': % s", <br/> door_sock, vold_socket, strerror (errno); <br/> exit (1); <br/>} 

Vold_socket is created in the INIT process. android_get_control_socket () is used to obtain the file descriptor of vold_socket.

Listern () is used to listen to socket connection requests from other framework layers.

 

When the framewok layer and mountservice are enabled, a new thread is created. In the constructor of class mountservice:

 

If (action. equals (intent. action_boot_completed) {<br/> thread = new thread (mlistener, mountlistener. class. getname (); <br/> thread. start (); <br/>}

 

 

Class mountlistener implements the runnable interface and creates an infinite loop in its inherited run () method:

While (true) {<br/> listentosocket (); <br/>} 

 

In the listentosocket () method:

 

Socket = new localsocket (); <br/> localsocketaddress address = new localsocketaddress (vold_socket, <br/> localsocketaddress. namespace. reserved); <br/> socket. connect (Address); <br/> inputstream = socket. getinputstream (); <br/> moutputstream = socket. getoutputstream (); <br/> ···································· <br/> while (true) {<br/> int COUNT = inputstream. read (buffer); <br/> If (count <0) break; <br/> int start = 0; <br/> for (INT I = 0; I <count; I ++) {<br/> If (buffer [I] = 0) {<br/> string event = new string (buffer, start, i-Start); <br/> handleevent (event); <br/> Start = I + 1; <br/>}< br/>}

First, instantiate a local localsocket for communication with Vold, and then establish a connection with vold_socket. Create a file input stream to save the MES sent from vold to the buff. Finally, read the buff content in a wireless loop and execute handleevent ().

In handleevent (), use the if else statement to process the sent event.

 

If (event. equals (vold_evt_ums_enabled) {<br/> ................ <br/>} else if (event. equals (vold_evt_ums_disabled) {<br/> ................ <br/>} else if (event. equals (vold_evt_external_ums_connected) {<br/> ............... <br/> mservice. notifyumsconnected (PATH); <br/> ..................... <br/>} else if (event. equals (vold_evt_ums_connected) {<br/> ........................... <br/> mservice. notifyumsconnected (PATH); <br/>} else if (event. equals (vold_evt_external_ums_disconnected) {<br/> .........................

 

Processing of one of the events, such as. policyumsconnected ():

 

Finally, the command to be executed after processing is sent to vold.

 

So far, we have established the communication between vold and mountservice.

 

1.2 establish socket communication with the kernel

.................... <Br/> intent = new intent (intent. action_ums_connected); <br/> mcontext. sendbroadcast (intent); <br/> ....................

If (uevent_sock = socket (pf_netlink, <br/> sock_dgram, netlink_kobject_uevent) <0) {<br/> ........ <br/>}< br/> If (setsockopt (uevent_sock, sol_socket, so_rcvbufforce, & uevent_sz, <br/> sizeof (uevent_sz) <0) {<br/> ....... <br/>}< br/> If (BIND (uevent_sock, (struct sockaddr *) & nladdr, sizeof (nladdr) <0) {<br/> ...... <br/>} 

Create a uevent_sock to establish communication with the kernel. The setsockopt () function is mainly used to set the uevent_sock option. BIND () is used to bind the socket of the kernel to the uevent_sock for address binding.

 

1.3 Mount existing storage devices

 

The volmgr_bootstrap () function first parses the configuration file vold. conf;

Finally, the device information to be mounted will be placed in a global variable linked list val_root.

Static volume_t * vol_root = NULL;

1.4 mount the MMC/sdcard

Volmgr_bootstrap (); <br/> simulate_uevent () determines whether the uevent action is 'add', 'delete', or 'change '; <br/> If (rc = volmgr_readconfig ("/system/etc/vold. conf ") <0) {<br/> LogE (" unable to process config "); <br/> return RC; <br/>} 

Mmc_bootstrap ()

 

Dipatch_uevent (): determines the uevent processing Handle Based on uevent-> subsystem.

 

 

Struct uevent {<br/> const char * Action; <br/> const char * path; <br/> const char * subsystem; <br/> const char * firmware; <br/> int Major; <br/> int minor; <br/> };

 

 

The final Mount operation is implemented after mountservice is enabled.

Processing of 1.5 USB large capacity storage ums_bootstrap ()

 

1.6 switch_bootstrap ()

 

1.7 main service (endless loop)

 

Struct uevent_dispatch {<br/> char * subsystem; <br/> int (* dispatch) (struct uevent *); <br/> };

 

While (1) {<br/>... <br/> fd_zero (& read_fds ); // initialization file description set <br/> fd_set (door_sock, & read_fds); // Add door_sock to the file description set <br/> If (door_sock> MAX) <br/> max = door_sock; <br/> fd_set (uevent_sock, & read_fds); // Add event_sock to the file description set. <br/> If (uevent_sock> MAX) <br/> max = uevent_sock; <br/> If (fw_sock! =-1) {<br/> fd_set (fw_sock, & read_fds); // Add fw_sock to the file description set <br/> If (fw_sock> MAX) <br/> max = fw_sock; <br/>}< br/> // when all file descriptors are not changed, blocked thread <br/> If (rc = select (MAX + 1, & read_fds, null, null, & to) <0) {<br/> LogE ("select () failed (% s)", strerror (errno); <br/> sleep (1); <br/> continue; <br/>}< br/> If (! RC) {<br/> continue; <br/>}< br/> // checks the connection to the framework if it is door_sock, and send MSG <br/> If (fd_isset (door_sock, & read_fds) {<br/> struct sockaddr ADDR; <br/> socklen_t Alen; <br/> Alen = sizeof (ADDR); <br/> If (fw_sock! =-1) {<br/> LogE ("dropping duplicate framework connection"); <br/> int TMP = accept (door_sock, & ADDR, & Alen ); <br/> close (TMP); <br/> continue; <br/>}< br/> If (fw_sock = accept (door_sock, & ADDR, & Alen )) <0) {<br/> LogE ("unable to accept framework connection (% s)", <br/> strerror (errno )); <br/>}< br/> log_vol ("accepted connection from framework"); <br/>/* For inand */<br/> volmgr_usb_bootstrap (); <br/> If (rc = volmgr_send_states () <0) {<br/> LogE ("unable to send volmgr status to Framework (% d)", RC ); <br/>}< br/> // if it is fw_sock, execute the command from the Framework <br/> If (fd_isset (fw_sock, & read_fds )) {<br/> If (rc = process_framework_command (fw_sock) <0) {<br/> If (rc =-econnreset) {<br/> LogE ("framework disconnected"); <br/> close (fw_sock); <br/> fw_sock =-1; <br/>} else {<br/> LogE ("Error Processing Framework command (% s)", <br/> strerror (errno )); <br/>}< br/> // if it is uevent_sock, A uevent event is generated. <br/> If (fd_isset (uevent_sock, & read_fds) {<br/> If (rc = process_uevent_message (uevent_sock) <0) {<br/> LogE ("error processing uevent MSG (% s )", strerror (errno); <br/>}< br/>}// while <br/> 

 

2. Summary of vold Functions

1) create a connection:
As a daemon, vold receives the driver information and sends the information to the application layer. It also accepts the commands at the upper layer and performs corresponding operations.
Therefore, there are two connections:
· Vold socket: responsible for transferring information between vold and the application layer;
· Access udev socket: Responsible for vold and underlying information transmission;
Both connections are created at the beginning of the process.

 

2) Boot:
Here, the processing of existing peripheral storage devices is mainly performed when the vold is started.

· First, load and parse vold. conf and check whether the mount point has been mounted;

· Second, mount the mmccard;

· Finally, process USB large-capacity storage.

 

3) event handling:
Here, we listen to two connections to process dynamic events and respond to upper-layer application operations.

Supplement:

Telechips compared to Google native Android's vold porting mainly in the following two aspects:

1. telchips supports multiple storage devices, such as NAND, SATA, SCSI, MMC/SD. In terms of code, it mainly adds handling handles for these device events;

2. Support for NTFs is added to telchips. Three processing functions are added: ntfs_check (), ntfs_identify (), and ntfs_mount ();

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.