Android Startup Process

Source: Internet
Author: User

First, the Android framework architecture diagram: (from the Internet, I think this picture looks clear)

  

After the Linux kernel is started, go to the Android Init process and start Android-related services and applications.

The process of starting is shown in: (the image is from the Internet and is followed by an address)

   


  

The following describes how to learn about and summarize the process from the Android4.0 source code and network talents,

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

1. Start the Init process

Init process, which is a user-level process started by the kernel. The kernel is started by itself (it has been loaded into the memory and started to run,

After all the device drivers and data structures are initialized, a user-level program init is started to complete the boot process. Init is always the first process.

The startup process is the main function Execution Process in code init. c: system \ core \ init. c

In the function, execute: Folder creation, mounting, rc file parsing, attribute setting, starting the service, executing the action, socket listening ......

The following describes two important processes: rc file parsing and service startup.

1 rc file parsing

The. rc file is the initialization script file used by Android (which is described in System/Core/Init/readme.txt:

Four broad classes of statements which areActions,Commands,Services, AndOptions.)

Command is a series of commands supported by the system, such as export, hostname, mkdir, mount, and so on. Some of them are linux commands,

Some are added for android, such as class_start. : Start the service, class_stop : Close the service.

Here, Options is for Service Options.

The actions to be triggered during system initialization, the services to be started, and their respective attributes are defined in the rc Script file. Take a look at the Startup Script: \ system \ core \ rootdir \ init. rc

When parsing the rc Script file, put the corresponding types into their respective lists:

\ System \ core \ init \ Init_parser.c: init_parse_config_file () is saved

In action_queue, action_list, and service_list, you can look at the parse_config function during the parsing process. Similar to the state machine form, it is quite interesting.

This includes services: adbd, servicemanager, vold, ril-daemon, debugadh, surfaceflinger, zygote, media ......

2. Start the service

After the file is parsed, add the service to service_list.

After the file is parsed, add the service to 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;}

Traverse all services whose names are classname and whose status is not SVC_DISABLED to 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)

Search in the init. rc fileClass_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

ClassMain

Service surfaceflinger/system/bin/surfaceflinger

ClassMain

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 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();            }        }       }}

Loop callService_startTo start SVC_RESTARTING and set the service status 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.

2. Start ServiceManager

Description of zygote 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 path: frameworks \ base \ cmds \ servicemanager \ Service_manager.c

Startup of three Zygote Processes

Zygote is a very important process. The establishment of Zygote is the real Android runtime space, and the initialized services are all Navtive services.

(1) Description of zygote in the. rc Script File:

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 parameter: -- zygote -- start-system-server

Code path: frameworks/base/cmds/app_process/app_main.cpp

The above parameters will be used here to determine whether to start and start those processes.

int main( ){       AppRuntime runtime;       if (zygote) {              runtime.start("com.android.internal.os.ZygoteInit",                startSystemServer ? "start-system-server" : "");       }}class AppRuntime : public AndroidRuntime{};

(2) Go To The AndroidRuntime class:

Frameworks \ base \ core \Jni\ AndroidRuntime. cpp

Void start (const char * className, const char * options) {// start the JNIEnv * env of the virtual machine Java running in the virtual machine; if (startVm (& mJavaVM, & env )! = 0) {return;} // register the JNI Local interface with the newly created virtual machine if (starregulatory (env) <0) {return;} // call the java method by jni, obtain the static main method jmethodID startMeth = env-> GetStaticMethodID (startClass, "main", "([Ljava/lang/String;) V") of the corresponding class "); // jni calls the java method and calls the main function jclass startClass = env-> FindClass (className) of the ZygoteInit class; env-> CallStaticVoidMethod (startClass, startMeth, strArray );}

To the static main function in ZygoteInit. java

(3) ZygoteInit

Real Zygote process:

Frameworks \ base \ core \ java \ com \ android \ internal \ OS \ ZygoteInit. java

Public static void main (String argv []) {// Registers a server socket for zygote command connections registerZygoteSocket (); // Loads and initializes commonly used classes and // used resources that can be shared using SS processes preload (); // Do an initial gc to clean up after startup gc (); if (argv [1]. equals ("start-system-server") {startSystemServer ();}/*** Runs the zygote process's select loop. accepts new connections as * they happen, and reads commands from connections one spawn-request's * worth at a time. */runSelectLoopMode (); // loop/*** Close and clean up zygote sockets. called on shutdown and on the * child's exit path. */closeServerSocket ();}

Zygote has been established. It uses Socket Communication to receive requests, Fork application processes, and enters the Zygote process service framework.

Four SystemServer startup

(1) startSystemServer () is called before the Zygote process enters the loop ();

Private static boolean startSystemServer () {/* Request to fork the system server process incubates a new process */ZygoteConnection. arguments parsedArgs = null; pid = Zygote. forkSystemServer (parsedArgs. uid, parsedArgs. gid, parsedArgs. gids, parsedArgs. debugFlags, null, parsedArgs. permittedCapabilities, parsedArgs. effectiveCapabilities);/* For child process set */if (pid = 0) {handleSystemServerProcess (parsedArgs);} void handleSystemServerProcess (parsedArgs) {closeServerSocket (); // "system_server" Process. setArgV0 (parsedArgs. niceName); // Pass the remaining arguments to SystemServer. runtimeInit.zygoteInit(parsedArgs.tar getSdkVersion, parsedArgs. remainingArgs);/* shoshould never reach here */}

(2) In RuntimeInit:

Frameworks \ base \ core \ java \ com \ android \ internal \ OS \ RuntimeInit. java

// The main function called when started through the zygote process. void zygoteInit (int targetSdkVersion, String [] argv) {applicationInit (targetSdkVersion, argv);} void applicationInit (int targetSdkVersion, String [] argv) {// Remaining arguments are passed to the start class's static main invokeStaticMain (args. startClass, args. startArgs);} void invokeStaticMain (String className, String [] argv) {Class
 Cl; cl = Class. forName (className); // obtain the main Method of SystemServer, and throw the MethodAndArgsCaller exception Method m; m = cl. getMethod ("main", new Class [] {String []. class}); int modifiers = m. getModifiers (); throw new ZygoteInit. methodAndArgsCaller (m, argv );}

(3)SlaveStartSystemServerNo methods are called to start execution,

Only the main method is obtained through reflection, the MethodAndArgsCaller is paid, and a MethodAndArgsCaller exception is thrown.

Where is this exception handled?

Return to the call of the startSystemServer () function:

In the main function of ZygoteInit:

Public static void main (String argv []) {try {...... If (argv [1]. equals ("start-system-server") {startSystemServer (); // if an exception is thrown here, skip the following process} runSelectLoopMode (); // loop ...... } Catch (MethodAndArgsCaller caller) {caller. run (); // handle exceptions }}

If startSystemServer throws an exception and skips the execution cycle of the ZygoteInit process, what is the problem?

The exception in startSystemServer is thrown by handleSystemServerProcess, while

Pid = Zygote.ForkSystemServer()

/* For child process only sets the new sub-process */

If (pid = 0 ){

HandleSystemServerProcess(ParsedArgs );

}

// Zygote.ForkSystemServerA sub-process is generated based on the fork parameter. If the sub-process is successfully called, two times are returned:

One return is the pid of the zygote process, with a value greater than 0; one return is the subprocess pid, with a value equal to 0; otherwise, an error is returned-1;

Caller.Run();

MethodAndArgsCaller run function: Call the aforementioned

// SystemServer main method

M = cl. getMethod ("main", new Class [] {String []. class });

Started the SystemServer process.

(4) Execution of SystemServer init1 ()

// Frameworks \ base \ services \ java \ com \ android \ server \ SystemServer. java

Public static void main (String [] args) {System. loadLibrary ("android_servers");/** This method is called from Zygote to initialize the system. * This will cause the native services (SurfaceFlinger, AudioFlinger, etc ..) * to be started. after that it will call back * up into init2 () to start the Android services. */init1 (args); // call init2 ()} after native finishes callback // init1: frameworks/base/services/jni/com_android_server_SystemServer.cpp: android_server_SystemServer_init1: system_initextern "C" status_t system_init () {sp
 
  
Proc (ProcessState: self (); sp
  
   
Sm = defaservicservicemanager (); // start SurfaceFlinger and sensor property_get ("handler", propBuf, "1"); SurfaceFlinger: instantiate (); property_get ("handler", propBuf, "1"); SensorService: instantiate (); // And now start the Android runtime. we have to do this bit // of nastiness because the Android runtime initialization requires // some of the core system services to already be started. // All other servers shoshould just start the Android runtime at // the beginning of their processes's main (), before calling // the init function. androidRuntime * runtime = AndroidRuntime: getRuntime (); // calls back com. android. server. systemServer init2 method JNIEnv * env = runtime-> getJNIEnv (); jclass clazz = env-> FindClass ("com/android/server/SystemServer "); jmethodID methodId = env-> GetStaticMethodID (clazz, "init2", "() V"); env-> CallStaticVoidMethod (clazz, methodId ); // start the thread pool as the binder service ProcessState: self ()-> startThreadPool (); IPCThreadState: self ()-> joinThreadPool (); return NO_ERROR ;}
  
 

ProcessState:

Each process needs to maintain a ProcessState instance to describe the binder status of the current process when using the binder Mechanism for communication.

ProcessState has the following two main functions:

1. Create a thread to communicate with the binder module in the kernel. This thread is called a Pool thread;

2. Create a BpBinder object for the specified handle and manage all BpBinder objects in the process.

Pool thread:

In Binder IPC, all processes start a thread to directly communicate with BD, that is, to read and write BD without stopping,

The implementation subject of this thread is an IPCThreadState object. This type is described below.

The following describes how to start a Pool thread:

ProcessState: self ()->StartThreadPool();

IPCThreadState:

IPCThreadState is also designed in singleton mode. Because each process only maintains one ProcessState instance and ProcessState starts only one Pool thread,

That is to say, each process only starts one Pool thread, so each process only needs one IPCThreadState.

The actual content of Pool thread is:

IPCThreadState: self ()->JoinThreadPool();

(5) Execution of SystemServer init2 ()

Public static final void init2 () {// create a Thread to process Thread thr = new ServerThread (); thr. setName ("android. server. serverThread "); thr. start ();}// Check what is done in the thread ServerThread?Public void run () {addBootEvent (new String ("Android: SysServerInit_START"); logoff. prepare (); android. OS. process. setThreadPriority (android. OS. process. THREAD_PRIORITY_FOREGROUND); // initialize the service and create various service instances, such as power supply, network, Wifi, Bluetooth, and USB. // After initialization, add them to ServiceManager, // We use Context. getSystemService (String name) obtains the corresponding service PowerManagerService power = null; NetworkManagementService networkManagement = null; WifiP2pSer Vice wifiP2p = null; WindowManagerService wm = null; BluetoothService bluetooth = null; UsbService usb = null; icationicationmanagerservice notification = null; StatusBarManagerService statusBar = null ;...... Power = new PowerManagerService (); ServiceManager. addService (Context. POWER_SERVICE, power );...... // ActivityManagerService is the most important service of ApplicationFramework. setSystemProcess (); ActivityManagerService. installSystemProviders (); ActivityManagerService. self (). setWindowManager (wm); // We now tell the activity manager it is okay to run third party // code. it will call back into us once it has gotten to the state // where third party code can really run (but before it has actually // Started launching the initial applications), for us to complete our // initialization. // System Service Initialization is ready to notify each module of ActivityManagerService. self (). systemReady (new Runnable () {public void run () {startSystemUi (contextF); batteryF. systemReady (); networkManagementF. systemReady (); usbF. systemReady ();...... // It is now okay to let the various system services start their // third party code... appWidgetF. systemReady (safeMode); wallpaperF. systemReady () ;}}); // BOOTPROF addBootEvent (new String ("Android: SysServerInit_END"); Looper. loop ();}

Now the XxxServiceManager of the ApplicationFramework layer is ready. You can start running the upper-layer application. Our first upper-layer application, HomeLauncher.

How does HomeActivity start?

ActivityManagerService must be used to start an Activity.

What does ActivityManagerService. systemReady () do.

5. Start the Home interface

 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();    }  }  ……}

Then the Home interface is started to complete the Android startup process.

The process is as follows:

  

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.