AndroidInitProcess analysis experience (3)

Source: Internet
Author: User

All the way down, we can finally see the command element we want to see. In every act element, there is also a string of sorted linked lists created by comand with the act element, each comand element has a functionpointer of func. this function pointer is specified by kw_func macro.


[Cpp]
// System \ core \ init \ init_parser.c
# Define kw_func (kw) (keyword_info [kw]. func)

// System \ core \ init \ init_parser.c
# Define kw_func (kw) (keyword_info [kw]. func)

 

As you can see from this macro, the function specified by the macro is determined by the parameter kw specified by kw_func macro through keyword_infomapping table.

Return to the execute_one_command function of the execution process for further analysis. The functions contained in cur_command are related to the functions recorded in keyword_info mapping table. Example:

[Cpp]
// System \ core \ rootdir \ init. rc
Write/proc/sys/kernel/panic_on_oops 1

// System \ core \ rootdir \ init. rc
Write/proc/sys/kernel/panic_on_oops 1


The keyword_info mapping table

[Cpp] view plaincopyprint? KEYWORD (write, COMMAND, 2, do_write)

KEYWORD (write, COMMAND, 2, do_write)

Call

[Cpp]
\ System \ core \ init \ builtins. c
Int do_write (int nargs, char ** args)
{
Const char * path = args [1];
Const char * value = args [2];
Char prop_val [PROP_VALUE_MAX];
Int ret;
 
Ret = expand_props (prop_val, value, sizeof (prop_val ));
If (ret ){
ERROR ("cannot expand '% s' while writing to' % s' \ n", value, path );
Return-EINVAL;
}
Return write_file (path, prop_val );
}

\ System \ core \ init \ builtins. c
Int do_write (int nargs, char ** args)
{
Const char * path = args [1];
Const char * value = args [2];
Char prop_val [PROP_VALUE_MAX];
Int ret;

Ret = expand_props (prop_val, value, sizeof (prop_val ));
If (ret ){
ERROR ("cannot expand '% s' while writing to' % s' \ n", value, path );
Return-EINVAL;
}
Return write_file (path, prop_val );
}


Create filesystem path node

Init process is a Startup process of android. When initprocess is started, some file systems are constructed.

[Cpp]
// System \ core \ init. c
Mkdir ("/dev", 0755 );
Mkdir ("/proc", 0755 );
Mkdir ("/sys", 0755 );
 
Mount ("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode = 0755 ");
Mkdir ("/dev/pts", 0755 );
Mkdir ("/dev/socket", 0755 );
Mount ("devpts", "/dev/pts", "devpts", 0, NULL );
Mount ("proc", "/proc", "proc", 0, NULL );
Mount ("sysfs", "/sys", "sysfs", 0, NULL );

// System \ core \ init. c
Mkdir ("/dev", 0755 );
Mkdir ("/proc", 0755 );
Mkdir ("/sys", 0755 );

Mount ("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode = 0755 ");
Mkdir ("/dev/pts", 0755 );
Mkdir ("/dev/socket", 0755 );
Mount ("devpts", "/dev/pts", "devpts", 0, NULL );
Mount ("proc", "/proc", "proc", 0, NULL );
Mount ("sysfs", "/sys", "sysfs", 0, NULL );


First, create three directories: dev, proc, sys, and phase.

/Dev
In Linux, any peripheral device is stored in this directory as a file. To control the peripheral device, you only need to perform file read and write operations on the file path under this directory.
 
/Proc
It is a virtual file system, and all the archive data stored in it will be stored in the memory. That is to say, only when the device is executing will the archive appear in this directory ..
 
/Sys
It is a virtual file system, which is different from the files stored in/proc. It stores data related to the core or hardware device information detected by the core ..
 

After that, you will find that other directories are mounted and subdirectories are constructed under these three main directories.

 

Monitor System attribute changes and events

The objects monitored by Init process include property, signal, keychord. Init process, which performs initialize actions on these three objects at startup.


[Cpp]
// System \ core \ init. c
Queue_builtin_action (keychord_init_action, "keychord_init ");
Queue_builtin_action (property_service_init_action, "property_service_init ");
Queue_builtin_action (signal_init_action, "signal_init ");

// System \ core \ init. c
Queue_builtin_action (keychord_init_action, "keychord_init ");
Queue_builtin_action (property_service_init_action, "property_service_init ");
Queue_builtin_action (signal_init_action, "signal_init ");

 

The queue_builtin_action function only wraps the first function into a command, then uses the command to form an act data element, and then adds the act to action_list, then, the new act data element is sent to the actionqueue through action_add_queue_tail. the functions included in its command will call the execute_one_command function discussed earlier.

Since the three object initialization types are similar, here we will introduce the property to illustrate what actions are performed during the initial process.

[Cpp]
// System \ core \ init. c
Static int property_service_init_action (int nargs, char ** args)
{
/* Read any property files on system or data and
* Fire up the property service. This must happen
* After the ro. foo properties are set above so
* That/data/local. prop cannot interfere with them.
*/
Start_property_service ();
Return 0;
}
 
// System \ core \ init \ property_service.c
Void start_property_service (void)
{
Int fd;
 
Load_properties_from_file (PROP_PATH_SYSTEM_BUILD );
Load_properties_from_file (PROP_PATH_SYSTEM_DEFAULT );
Load_override_properties ();
/* Read persistent properties after all default values have been loaded .*/
Load_persistent_properties ();
 
Fd = create_socket (PROP_SERVICE_NAME, sosock_stream, 0666, 0, 0 );
If (fd <0) return;
Fcntl (fd, F_SETFD, FD_CLOEXEC );
Fcntl (fd, F_SETFL, O_NONBLOCK );
 
Listen (fd, 8 );
Property_set_fd = fd;
}

// System \ core \ init. c
Static int property_service_init_action (int nargs, char ** args)
{
/* Read any property files on system or data and
* Fire up the property service. This must happen
* After the ro. foo properties are set above so
* That/data/local. prop cannot interfere with them.
*/
Start_property_service ();
Return 0;
}

// System \ core \ init \ property_service.c
Void start_property_service (void)
{
Int fd;

Load_properties_from_file (PROP_PATH_SYSTEM_BUILD );
Load_properties_from_file (PROP_PATH_SYSTEM_DEFAULT );
Load_override_properties ();
/* Read persistent properties after all default values have been loaded .*/
Load_persistent_properties ();

Fd = create_socket (PROP_SERVICE_NAME, sosock_stream, 0666, 0, 0 );
If (fd <0) return;
Fcntl (fd, F_SETFD, FD_CLOEXEC );
Fcntl (fd, F_SETFL, O_NONBLOCK );

Listen (fd, 8 );
Property_set_fd = fd;
}


The property configuration file will be downloaded from the beginning. The path of these files is defined in _ system_properties.h.

[Cpp]
// Bionic \ libc \ include \ sys \ _ system_properties.h
# Define PROP_PATH_RAMDISK_DEFAULT "/default. prop"
# Define PROP_PATH_SYSTEM_BUILD "/system/build. prop"
# Define PROP_PATH_SYSTEM_DEFAULT "/system/default. prop"
# Define PROP_PATH_LOCAL_OVERRIDE "/data/local. prop"

// Bionic \ libc \ include \ sys \ _ system_properties.h
# Define PROP_PATH_RAMDISK_DEFAULT "/default. prop"
# Define PROP_PATH_SYSTEM_BUILD "/system/build. prop"
# Define PROP_PATH_SYSTEM_DEFAULT "/system/default. prop"
# Define PROP_PATH_LOCAL_OVERRIDE "/data/local. prop"


Configuration files for all android systems are read from these files as soon as they are started. as for how to edit propertyconfig file, this is not in the scope here. so this is not the case. after downloading the set values of all properties, enable the socket to wait for changes. and pass filedescriptor to the global variable property_set_fd.

After initialization, start the monitoring process.

[Cpp]
// System \ core \ init. c
Int main (int argc, char ** argv)
{
//...
For (;;){
// Execute the command of act in the action list.
// Check whether a service needs to be restarted
(1)
If (! Property_set_fd_init & get_property_set_fd ()> 0 ){
Ufds [fd_count]. fd = get_property_set_fd ();
Ufds [fd_count]. events = POLLIN;
Ufds [fd_count]. revents = 0;
Fd_count ++;
Property_set_fd_init = 1;
}
 
//....
(2)
Nr = poll (ufds, fd_count, timeout );
If (nr <= 0)
Continue;
(3)
For (I = 0; I <fd_count; I ++ ){
If (ufds [I]. revents = POLLIN ){
If (ufds [I]. fd = get_property_set_fd ())
Handle_property_set_fd ();
//....
}
}
 
}
Return 0;
}

// System \ core \ init. c
Int main (int argc, char ** argv)
{
//...
For (;;){
// Execute the command of act in the action list.
// Check whether a service needs to be restarted
(1)
If (! Property_set_fd_init & get_property_set_fd ()> 0 ){
Ufds [fd_count]. fd = get_property_set_fd ();
Ufds [fd_count]. events = POLLIN;
Ufds [fd_count]. revents = 0;
Fd_count ++;
Property_set_fd_init = 1;
}

//....
(2)
Nr = poll (ufds, fd_count, timeout );
If (nr <= 0)
Continue;
(3)
For (I = 0; I <fd_count; I ++ ){
If (ufds [I]. revents = POLLIN ){
If (ufds [I]. fd = get_property_set_fd ())
Handle_property_set_fd ();
//....
}
}

}
Return 0;
}


(1) register the pollfd structure. The value obtained by the get_property_set_fd function is the filedescriptor that previously enabled the socket during the initial period.

(2) start to go to the polling monitoring change. Only the third step will be continued after the change. Otherwise, the next polling monitoring will be skipped.

(3) Compare the registered filedescriptor as soon as there is a change. As mentioned before, there are three android (4.2) Monitored Objects. Finally, they enter handlefunction.

 

 

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.