Android framework Startup Process

Source: Internet
Author: User

Android framework Startup Process

As we all know, Android mobile phone system is essentially a Linux-based application, which uses the Linux system As the kernel. Therefore, the system starts two phases: Linux kernel startup and Android framework startup.

Linux Kernel startup

1. Load the bootloader
When the Linux kernel starts, it first loads and executes the bootloader boot program, and then enters the kernel program.
2. Load the Linux Kernel
Linux kernel loading mainly includes initializing the kernel core (memory initialization, opening interrupt, initialization progress table, etc.), initializing the driver, starting the kernel background (daemons) thread, and installing the root file system.
Start and execute the first user-level process init at the final stage of Linux loading ("init =/init" is usually set in kernel boot parameters, which is automatically executed by kernel and PID is 1, is the parent process of all processes ). Then, the Android framework is started.

The android framework starts from the init process. This stage is also important in this article. In summary, the startup process can be divided into the following main stages:
1. Start the init process
2. Start the init. rc Script
3. Start the zygote Service
4. Start the System Server process
5. After the Home application is started, we will learn about and summarize the process from the Android5.0 source code and network talents,

In the following learning process, the code snippets are omitted and incomplete. Please refer to the source code. Start the Init process

Init is a process. Specifically, it is the first process in the user space in Linux. Because Android is based on the Linux kernel, init is also the first process in the user space in the Android system. Its Process number is 1.

The init process entry function is main, system \ core \ init. c.

The init process can be found in/system/core/init.
The init. rc file can be found in/system/core/rootdir/init. rc.
Readme.txt can be found in/system/core/init/readme.txt.

 

Int main (int argc, char ** argv) {intdevice_fd =-1; intproperty_set_fd =-1; intsignal_recv_fd =-1; intkeychord_fd =-1; int fd_count; ints [2]; intfd; structsigaction act; chartmp [PROP_VALUE_MAX]; structpollfd ufds [4]; char * tmpdev; char * debuggable; // sets the signal processing function for sub-process exit. This function is sigchld_handler. Act. sa_handler = sigchld_handler; act. sa_flags = SA_NOCLDSTOP; act. sa_mask = 0; act. sa_restorer = NULL; sigaction (SIGCHLD, & act, 0 );...... // create some folders and mount the devices. These are related to Linux and will not be discussed too much. Mkdir ("/dev/socket", 0755); mount ("devpts", "/dev/pts", "devpts", 0, NULL); mount ("proc ", "/proc", "proc", 0, NULL); mount ("sysfs", "/sys", "sysfs", 0, NULL ); // redirect standard input/output/error output to/dev/_ null _. Open_devnull_stdio ();/* set the log output device of init to/dev/_ kmsg __, but the file will be unlinked immediately after it is opened, other processes cannot open this file to read log information. */Log_init (); // The above involves a lot of knowledge related to the Linux system. unfamiliar readers can study it on their own. They do not affect our analysis. // parse init. rc configuration file parse_config_file ("/init. rc ");...... // The following function reads/proc/cpuinfo to get the machine's Hardware name. My HTCG7 mobile phone is bravo. Get_hardware_name (); snprintf (tmp, sizeof (tmp), "/init. % s. rc ", hardware); // parse the configuration file related to the machine. The file corresponding to my G7 mobile phone is init. bravo. rc. Parse_config_file (tmp);/* after the preceding two configuration files are parsed, a series of actions are obtained. The following two statements of code will execute the actions in the early-init stage. Init divides the execution time of an action into four stages: early-init, init, early-boot, and boot. Because some actions can only be executed after other actions are completed, they have different priorities. Which actions belong to which stage is determined by the configuration file. The following describes the configuration file. */Action_for_each_trigger ("early-init", action_add_queue_tail); drain_action_queue ();/* Create a socket that uses Uevent to interact with the Linux kernel. About Uevent, This section describes Vold Analysis in Chapter 9th. */Device_fd = device_init (); // initialize the property-related resource property_init (); // initialize the/dev/keychord device, which is related to debugging, this book does not discuss its usage. Readers can study it on their own. // The content is relatively simple. Keychord_fd = open_keychord ();...... /* INIT_IMAGE_FILE is defined as "/initlogo. rle ", the following function will load this file as the system boot screen, note that it is not the boot animation file loaded by the boot animation control program bootanimation. */If (load_565rle_image (INIT_IMAGE_FILE) {/* if the initlogo is loaded. if the rle file fails (this file may not exist), The/dev/ty0 device is opened and the "ANDROID" text is output as the boot screen. The boot screen shown on the simulator is it. */......}} If (qemu [0]) import_kernel_1_line (1 );...... // call the property_set function to set attribute items. An Attribute item includes the attribute name and attribute value. Property_set ("ro. bootloader", bootloader [0]? Bootloader: "unknown ");...... // execute the action action_for_each_trigger ("init", action_add_queue_tail); drain_action_queue (); // start the property service property_set_fd = start_property_service (); /* call the socketpair function to create two connected sockets. Socketpair is a Linux system call. unfamiliar readers can use man socketpair to query related information. They will be used later. */If (socketpair (AF_UNIX, SOCK_STREAM, 0, s) = 0) {signal_fd = s [0]; signal_recv_fd = s [1]; ......} // execute the early-boot and boot actions in the configuration file. Export ("early-boot", action_add_queue_tail); action_for_each_trigger ("boot", action_add_queue_tail); drain_action_queue (); ...... // init focuses on four things. Ufds [0]. fd = device_fd; // device_fd is used to listen to the Uevent event ufds from the kernel [0]. events = POLLIN; ufds [1]. fd = property_set_fd; // property_set_fd is used to listen for events from the property server ufds [1]. events = POLLIN; // signal_recv_fd is created by socketpair. Its events come from another socket. Ufds [2]. fd = signal_recv_fd; ufds [2]. events = POLLIN; fd_count = 3; if (keychord_fd> 0) {// if the keychord device is initialized successfully, init will also follow events from this device. Ufds [3]. fd = keychord_fd; ufds [3]. events = POLLIN; fd_count ++ ;}...... # if BOOTCHART ...... // It is related to Boot char and will not be discussed. /* Boot chart is a small tool that can analyze the system performance and generate a chart of the system startup process to provide valuable information, the biggest use of this information is to help increase the system startup speed. */# Endiffor (;) {// The init will enter an infinite loop. Int nr, I, timeout =-1; for (I = 0; I <fd_count; I ++) ufds [I]. revents = 0; // execute the action drain_action_queue (); restart_processes (); // restart the dead processes ...... # if BOOTCHART ...... // Boot Chart related # endif // call poll to wait for something to happen nr = poll (ufds, fd_count, timeout );...... // ufds [2] Stores signal_recv_fd, which is used to receive messages from the socket. If (ufds [2]. revents = POLLIN) {// when a sub-process dies, init needs to handle this issue read (signal_recv_fd, tmp, sizeof (tmp); while (! Wait_for_one_process (0); continue;} if (ufds [0]. revents = POLLIN) handle_device_fd (device_fd); // process Uevent event if (ufds [1]. revents = POLLIN) handle_property_set_fd (property_set_fd); // process Attribute Service events. If (ufds [3]. revents = POLLIN) handle_keychord (keychord_fd); // process the keychord event .} Return0 ;}

This function has been simplified. In general, the following commands are executed in the function: Folder creation, mounting, rc file parsing, attribute setting, starting service, executing actions, socket listening ......

In general, the init workflow is simplified as follows:

Create folders and mount devices

Parse the two configuration files init. rc and init. hardware. rc. the parsing of the init. rc file will be analyzed.
Execute the actions at each stage and create Zygote.
Call property_init to initialize the resources related to the property and start the property service through property_start_service.

Init enters an infinite loop and waits for something to happen. Focus on how init handles issues related to socket and property servers.

 

1. parse Init. rc

Android has specific formats and rules for the init. rc file. In Android, we call it the Android initialization language.
The Android initialization language consists of four types of statements: Actions (Action), Commands (command), Services (service), and Options (Options ).
Action: an Action is named after a command flow. A trigger determines whether an Action occurs.
Syntax
On
 
   Service: A Service is a program started by the init process. When the Service exits, the init process restarts the Service as needed.
Syntax


Service [] *


...
Options)
The option is the description of the service. They affect how and when the init process starts the service.
Let's take a look at the default init. rc file. Here I only list the main events and services.

Action/Service description
On early-init, set the priority of the init process and its created sub-processes, and set the security environment of the init process.
On init sets the global environment and creates a cgroup (resource control) mount point for cpu accounting
Mount mtd partitions on fs
On post-fs changes the access permission of the system directory
On post-fs-data Change/data directory and its sub-Directory Access Permissions
On boot basic network initialization, memory management, etc.
Service servicemanager starts all local services managed by the System Manager, such as location, audio, Shared preference, etc...
Service zygote starts zygote as the application process
At this stage, you can see the "Android" logo on the screen of the device.

 

Init. some important services are configured in the rc Script file. The init process starts these services by creating sub-processes. All the services created here belong to the native service and run in the Linux space, provides specific services through the socket to the upper layer and runs in the background as a daemon. The service definition in the script is as follows:
service servicemanager /system/bin/servicemanager      class core      user system      group system      critical      onrestart restart zygote  08    onrestart restart media    service ril-daemon /system/bin/rild      class main      socket rild stream 660 root radio      socket rild-debug stream 660 radio system      user root      group radio cache inet misc audio sdcard_rw log    service surfaceflinger /system/bin/surfaceflinger      class main      user system      group graphics      onrestart restart zygote    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server      class main      socket zygote stream 666      onrestart write /sys/android_power/request_state wake      onrestart write /sys/power/state on      onrestart restart media      onrestart restart netd    service media /system/bin/mediaserver      class main      user media      group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc      ioprio rt 4


The following important services are started through the init. rc Script system:
1) servicemanager: Start the binder IPC to manage all Android system services
2) mountd: Daemon is installed on the device and is responsible for device installation and status notifications.
3) debugadh: Start the debug system to process the request of the debugging process.
4) rild: Start the radio interface layer daemon service to process telephone-related events and requests.
5) mediaserver: starts AudioFlinger, MediaPlayerService and CameraService, and is responsible for multimedia playback functions, including audio and video decoding and display and output.
6) zygote: Process incubator, which starts Android Java VMRuntime and systemserver. It is responsible for the hatching of the Android application process. When parsing the rc Script file, it puts the corresponding types into the respective List:

\ System \ core \ init \ Init_parser.c: init_parse_config_file () is saved to action_queue, action_list, and service_list. You can check the parse_config function during parsing, similar to the state machine form.

This includes services: adbd, servicemanager, vold, ril-daemon, debugadh, surfaceflinger, zygote, media ...... 2. After the Nativie service is started (including ServiceManager) file is parsed, put the service into service_list.

\ System \ core \ init \ builtins. c

The Service is started in the do_class_start function:


Int do_class_start (int nargs, char ** args) {service_for_each_class (args [1], service_start_if_not_disabled); return 0;} traverses all names as classname, start void service_for_each_class (const char * classname, void (* func) (struct Service * svc )){......}
static void service_start_if_not_disabled(struct service *svc){    if (!(svc->flags & SVC_DISABLED)) {        service_start(svc, NULL);    }}

Do_class_start:

KEYWORD (class_start, COMMAND, 1, do_class_start)


In the init. rc file, search for class_start: class_start main, class_start core ,......

Main and core are the classname parameters of do_class_start.

In the init. rc file, the Service class names are all main:

Service drm/system/bin/drmserver

Class main

Service surfaceflinger/system/bin/surfaceflinger

Class main

So we can traverse all services through the main name and start it.

Do_class_start call:

In init. rc

On boot // action
Class_start core // Execute command corresponding to do_class_start
Class_start main

In the main function of the Init process:
In system/core/init. c:
Int main () {// mount the file // parse the configuration file: init. rc ...... // Initialize the action queue ...... For (;) {execute_one_command (); restart_processes (); for (I = 0; I <fd_count; I ++) {if (ufds [I]. revents = POLLIN) {if (ufds [I]. fd = get_property_set_fd () handle_property_set_fd (); else if (ufds [I]. fd = get_keychord_fd () handle_keychord (); else if (ufds [I]. fd = get_signal_fd () handle_signal ();}}}}

Call service_start cyclically to start SVC_RESTARTING and set the status of the started service to SVC_RUNNING.
Pid = fork ();
Execve ();

In the message loop: The Init process executes the Android Command and starts NativeService of Android. It listens to Service changes and processes Signal.

The Init process is used as a Property service to maintain these NativeService. Init. some important services are configured in the rc Script file. The init process starts these services by creating sub-processes. All the services created here belong to the native service and run in the Linux space, provides specific services through the socket to the upper layer and runs in the background as a daemon
Focus on the description of servicemanager in the. rc Script file:

Service servicemanager/system/bin/servicemanager
Class core
User system
Group system
Critical
Onrestart restart zygote
Onrestart restart media
Onrestart restart surfaceflinger
Onrestart restart drm


ServiceManager is used to manage all the binder services in the system. Both local c ++ implementation and java implementation require
The most important management of this process is to register and add services to obtain services. All services must be registered in servicemanager before use.

Do_find_service ()
Do_add_service ()
Svcmgr_handler ()
Code Location: frameworks \ base \ cmds \ servicemanager \ Service_manager.c3 and zygote services are started in Java. We know that different virtual machine instances allocate different memory for different applications. If the Android Application should be started as quickly as possible, but if the Android system starts different Dalvik Virtual Machine instances for each application, it will consume a lot of memory and time. Therefore, to overcome this problem, the Android system has created "Zygote ". Zygote allows Dalvik virtual machines to share code, reduce memory usage, and minimize startup time. Zygote is a virtual machine process, as we mentioned in the previous step, starting at system boot. Zygote pre-load and initialize the core library class. Generally, these core classes are read-only and are part of the Android SDK or core framework. In a Java virtual machine, each instance has its own core library file and heap object copy.


The zygote process incubated all Android application processes, which are the basis of the Android Framework. the startup of the process also marks the start of Framework initialization. Main functions of the zygote service process:


1) register the JNI function of the underlying function to the VM.
2) pre-load java classes and resources
3) fork and start the core process of System Server
4) load the ZygoteInit class as a daemon listener to process requests for "incubating new processes". Source Code:/frameworks/base/core/java/com/android/internal/OS/ZygoteInit. java
RegisterZygoteSocket () registers a server socket for the zygote command connection.
PreloadClassed "preloaded-classes" is a simple text file that contains a series of pre-loaded classes. You can find the "preloaded-classes" file in/frameworks/base.
PreloadResources () preloadResources also means that the local topic, layout, and everything contained in the android. R file will be loaded using this method.
In this phase, you can see the startup animation.


As described above, zygote is started through the init script:


Service zygote/system/bin/app_process-Xzygote/system/bin -- zygote -- start-system-server
Class main
Socket zygote stream 666
Onrestart write/sys/android_power/request_state wake
Onrestart write/sys/power/state on
Onrestart restart media
Onrestart restart netd
The preceding script is used as the hatching process (-Xzygote parameter) to start the zygote service through system/bin/app_process, and start the SystemServer (-- start-system-server parameter) process. The source code of the executable file app_process corresponding to this service is located in frameworks/base/cmds/app_process.


The zygote service is started in the app_main.cpp: main () function. The key code of this function is as follows:
1) Create an AndroidRuntime object:


AppRuntime runtime; // android runtime Space
2) Start zygote and systemserver:


Runtime. start ("com. android. internal. OS. ZygoteInit ",
StartSystemServer? "Start-system-server ":"");
The method start () code is located in frameworks/base/core/jni/AndroidRuntime. cpp. The main logic is as follows:
--- Call startVM to create a vm: Use the following code to create a vm object:


If (JNI_CreateJavaVM (pJavaVM, pEnv, & initArgs) <0 ){
LOGE ("JNI_CreateJavaVM failed \ n ");
Goto bail;
}
--- Register the JNI function of the underlying function to JNIEnv: starregulatory ()
--- Call the env-> GetStaticMethodID and env-> CallStaticVoidMethod () function to run main () of Java class ZygoteInit ()
The first Java class executed after the VM is started is ZygoteInit. java and enters the ZygoteInit. java: main () function. The main function implements the following logic:
1) Start the Socket port on the server:
The registerZygoteSocket () method is called to accept requests for creating new processes.
2) pre-load the specified java class and resource:
Call preloadClasses () to pre-load the specified java class and call preloadResources () to pre-load the specified Resources. In particular, the incubator process will share these pre-loaded classes and resources to all APK application processes, effectively solving the issue of Framework classes and resource sharing.
3) Start the System Server process:
Call startSystemServer () to create (fork) The SystemServer process. The key code of this function is as follows:
--- Set information about the startup process, such as the process name and the first java class loaded after startup.
--- Call forkSystemServer () to hatch a new process from the current zygote Process
--- Call the hanldeSystemServerProcess () function to close the Socket inherited from the Zygote process and call RuntimeInit. zygoteInit () to start the SystemServer. java: main () function.
4) requests from the new Dalvik process incubated by loop listening:
Call runSelectLoopMode () to enter an infinite loop: Listen to the socket connection of the client and hatch new application processes based on requests. The Process class saves the client socket and is managed by ActivityManagerService. Whenever you need to start a new Dalvik application process, ActivityManagerService will communicate with the socket server of the Zygote process through this socket Client, requesting Zygote to hatch a new process.
So far, the process of starting the zygote service is complete. Note that the zygote process is the process of the app_process executable program.
4. The System Server process starts the SystemServer process and plays a "Neural hub" role in the running environment of Android. Most System services that Android applications can directly interact with are running in this process, such as WindowManagerServer, ActivityManagerSystemService, and PackageManagerServer. These system services exist in the SystemServer process as independent threads. Main functions of the System Server process:

1) load the underlying function library of android servers
2) Start the native service in the android system
3) Create, register, and start the Android system service and run it in an independent thread.
4) create a logoff message loop to process event messages in the System Server process


Call the startSystemServer () function in the zygote process to create and start the Server process. The first function executed by the process is SystemServer. java: main (). The main logic of this function is:
1) load the android_servers function library
2) Start the native service:
Call the local function init1 (). The source code of this function is located in the system_init () function in the file frameworks/base/services/jni/com_android_server_systemService.cpp () in the file frameworks/base/cmds/system_server/library/system_init.cpp.
3) Start various system services of the Android system:
Call the function init2 () implementation. The function first creates a ServerThread object, which is a thread and then runs the thread directly, as shown in the following code:


Public static final void init2 (){
Slog. I (TAG, "Entered the Android system server! ");
Thread thr = new ServerThread ();
Thr. setName ("android. server. ServerThread ");
Thr. start ();
}
Start various service threads from inside the run () method of ServerThread.
--- Create an Android service object and register it with ServiceManager
--- Establish logoff message loop in the SystemServer process: implemented through logoff. prepare and logoff. loop
--- System ready notification: Call systemReady () to notify various services


The core step in the process of starting the System Server process is "Starting various System services of the Android System". These System services constitute the foundation of the entire Android framework (), the Binder IPC provides various functions for upper-layer applications. Zygote creates a new process to start the system service. You can find the source code in the "startSystemServer" method of the ZygoteInit class. This section describes the functions of several important system services.


1) ActivityManagerService
Activity management service. Its main functions include:
--- Manage and schedule the activities of each application in a unified manner, and maintain all application tasks and activities running in the system
--- Memory management: the corresponding process is still running when the application is closed. When the system memory is insufficient, kill the process with a lower priority according to the policy.
--- Process Management: maintains and manages all processes running in the system, and provides APIs for querying process information.
--- Provider, Service, and Broadcast management and scheduling


2) WindowManagerService
Window Management Service. It provides the following functions: allocate windows to applications and manage these windows. The window size can be allocated, the order of overlapping windows can be adjusted, and the window size can be hidden or displayed. The window is deleted when the program exits.


3) PackageManagerService
The package Management Service provides the following functions:
--- Search for matched activities, providers, and services based on intent
--- Perform a permission check. When an application calls a function that requires certain permissions, the system can determine whether the caller has the permission.
--- Provides APIs for installing and deleting applications


4) icationicationmanagerservice
The notification Management Service is responsible for managing and notifying the occurrence of background events. Combined with the statusbar service, a response icon is usually added to the statusbar. You can use this to know what happened in the system background.


5) AudioService
The audio management service is the upper-Layer Management encapsulation of AudioFlinger. It mainly manages the volume, sound effects, sound channels, and ringtones.


6) TelephonyRegistry
Telephone Service Management is used to monitor and report the phone status, including incoming calls, calls, and signal changes.

By now, the launch of the Android Framework has been completed, and various services provided in the Framework have been ready for normal operation and response to various operation requests of the application.Once the system service runs in the memory, Android completes the boot process. When "ACTION_BOOT_COMPLETED" is started, the broadcast will be sent.

Core Services:

Start the Power Manager;
Create Activity manager;
Start Phone registration;
Start the Package Manager;
Set Activity management service as a system process;
Start the context manager;
Start the SYSTEM Context Providers;
Start the battery service;
Start the timer manager;
Start the sensor service;
Start the window manager;
Start the Bluetooth service;
Start the Mount service.
Other services:

Start the status bar service;
Start the hardware service;
Start the network status service;
Start the network connection service;
Start the notification manager;
Start the device storage monitoring service;
Start the locating manager;
Start the search service;
Start the clipboard service;
Start the registration service;
Start the wallpaper service;
Start the audio service;
Start the headset listener;
Start AdbSettingsObserver (process the adb command ).


After the home application is started, you need to start the home application to enter the main page of the mobile phone. This is described in Section 5th below.


5. When the Home application is started, the ActivityManagerService. self (). systemReady method is called at the end of the ServerThread: run () function. The following code is implemented to start the first Activity:

MMainStack. resumeTopActivityLocked (null );
public void systemReady(final Runnable goingCallback) {    ……    //ready callback       if (goingCallback != null)              goingCallback.run();       synchronized (this) {              // Start up initial activity.              // ActivityStack mMainStack;              mMainStack.resumeTopActivityLocked(null);       }……}final boolean resumeTopActivityLocked(ActivityRecord prev) {  // Find the first activity that is not finishing.  ActivityRecord next = topRunningActivityLocked(null);  if (next == null) {    // There are no more activities!  Let's just start up the    // Launcher...    if (mMainStack) {      //ActivityManagerService mService;      return mService.startHomeActivityLocked();    }  }  ……}


Because the system does not have any Activity object at startup, the code will call the ActivityManagerService: startHomeActivityLocked function to start the Home application:


Intent intent = new Intent (
MTopAction,
MTopData! = Null? Uri. parse (mTopData): null );
Intent. setComponent (mTopComponent );
If (mFactoryTest! = SystemServer. FACTORY_TEST_LOW_LEVEL ){
Intent. addCategory (Intent. CATEGORY_HOME );
} Finally use a picture to summarize the Image Source: http://blog.csdn.net/zirconsdu/article/details/8574049

Related Article

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.