A brief analysis of the Android system startup process

Abstract: The process of Android system startup can be summarized as init process startup, Native service startup, SystemServer, Android service startup and Home startup 4 steps. The various steps are closely linked to each other, forming a unified whole.

Keywords: init process; Zygote process; SystemServer

1 Android OS architecture

The Android system uses a layered architecture, divided into 4 levels, from the high-level to the bottom-level are the application layer, the application layer and the framework layer, the system runtime layer, and the Linux core layer. Observing the Android system architecture diagram, we can find that the basic applications (Home, Camera, Dialer, Browser, etc.) provided by it run on the application framework. For developers, developers can use the Android SDK to call the application framework API to develop applications that also run on the application framework layer.


 
                         A brief analysis of the Android OS startup process-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

                                             Android system architecture diagram

    Each level of the Android system has different functions, so I won’t give an overview here, but just a preliminary understanding.

2 init process and its startup

The init process is a user-level process, init has many important tasks , such as starting getty (for user login), to achieve operational level, as well as deal with orphan processes , etc. . init is always the first process.

When starting, first load the Linux kernel through the bootloader (system loader). When Linux loads the boot kernel, it is the same as the normal Linux boot process. The kernel is initialized first, and then the init process is called.

                                 A brief analysis of the Android OS startup process-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

                                        The init process startup process

It can be seen from the init process startup diagram that the init process is executed last after the start_kernel() function, init_post() function, and run_init_process() function are executed sequentially. The code to start the init process is as follows:

Static int noinline init_post(void)

{

    if(execute_command){

       run_init_process(execute_command);

    }

   run_init_process(“/sbin/init”);

   run_init_process(“/etc/init”);

   run_init_process(“/bin/init”);

}

The Android init process initializes various devices and runs various Daemon, ServiceManager, Zygote, etc. required by the Android Framework. Among them, ServiceManager is an important process for managing Android system services. System services are an important component of the Android Framework, providing important APIs required for camera, audio, video, processing and various application production.

The init process not only performs the termination processing of the child process, but also generates the device node file when the application program accesses the device driver, provides attribute services, and saves the environment variables required for system operation. In addition, it will analyze the init.rc startup script file and execute corresponding functions based on the content contained in the relevant file.

When Android starts, the init.rc script file is used to set the system environment and record the process to be executed; the second is the content related to the action list and the service list, which are generated by the init process according to init.rc. The Init.rc file structure is as follows

                                                               A brief analysis of the Android OS startup process-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

init.rc file structure

2.1 Action List

    In the "on init" paragraph of the action list, you mainly set environment variables, generate files or directories required for system operation, modify corresponding permissions, and mount directories related to system operation.

                     A brief analysis of the Android OS startup process-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

                                                  on init paragraph 

    In the "on init" root file system mounting part, the two directories /system and /data are mainly mounted. After the two directories are mounted, the Android root file system is ready.

2.2 Service List

In the init.rc script file, the "service" paragraph is used to record the process started by the init process. The child process started by the init process is either a one-time program, or a ServiceManager process related to application programs and system service management running in the background.

                             A brief analysis of the Android OS startup process-Hongye Ningxiang-Mu Yu Xiaoxiao
 
                      A brief analysis of the Android OS startup process-Hongye Ningxiang-Mu Yu Xiaoxiao
 


 

Finally, the init process does not exit, but acts as a property service.

3 Zygote process

Literally, Zygote means "fertilized egg, binder, and conjugator". To run a new application in the Android system, it needs to be combined with the Zygote process (having various elements and conditions required by the application to run) just like the fertilization and division of an egg before it can be executed. Zygote is a very important process in the Android system application, its main function

It is to execute Android applications.

When the Zygote process is running, it will initialize the Dalvik virtual machine and start it. Android applications are written by java. They cannot run directly on Linux as a local process, but can only run in the Dalvik virtual machine. At this point, we can correspond to the Android architecture, and the system has already run to the system runtime layer. Android services and applications are all started and run by the Zygote process.

Run ZygoteInit class by app_process

Zygote is written in java and cannot be started and run directly by the init process. If you want to run the Zygote class, you must first generate the Dalvik virtual machine, and then load and run the ZygoteInit class on the Dalvik virtual machine. The app_process process performs this task. When the app_process process is executed, the AppRuntime object is first common. Part of the source code is as follows

int main () {

     ...

    AppRuntime runtime;

    ..

    //Everything up to ‘--’ or first non ‘-’ arg goes to the *vm

    int i = runtime.addVmArguments(argc,argv);

    //Next arg is parent directory

    if(i

       runtime.mParentDir = argv[i++];

    }

}

The AppRuntime class inherits from the AndroidRuntime class. The AndroidRuntime class runs before initializing and running the Dalvik virtual machine. Through the AppRuntime object, the environment variables and operating parameters are analyzed, and virtual machine options are generated. After analyzing the parameters to be passed to the virtual machine, and save them to the object of the AppRuntime class, then load the object and call the main() method of the object.

int main(int argc ,const char* const argv[]){

   ...

   if(i 

     arg = argv [i ++];

   if(0 == strcmp(“--zygote”,arg)){

      bool startSyatemServer = (i < argc)?

            strcmp(argv[i],”--start-system-server”) == 0:false;

      setArgv0(argv0,”zygote”);

      set_process_name(“zygote”);

      //Generate and initialize the virtual machine

      runtime.start(“com.android.internal.os.ZygoteInit”

             ,startSystemSever);

   }else {...}

   }

   ...

}

The Dalvik virtual machine is started and initialized by the runtime (see the note above), and then the ZygoteInit class is loaded into the virtual machine and the main method is executed.

The ZygoteInit class has four main functions: binding /dev/socket/zygote sockets, loading classes and platform resources in the application Framework, running SystemServer, and running new Android applications. Here we only briefly explain some of the functions. The main function of ZygoteInit::main() method is as follows:

                      A brief analysis of the Android OS startup process-Hongye Ningxiang-Mu Yu Xiaoxiao         

                                                     ZygoteInit function diagram

Let's take a look at part of the source code of the ZygoteInit class.

public static void main(String argv[]){

     try{

        //Bind socket, accept new Android application request

        registerZygoteSocket();

        ...

        //Load class resources used by Android Application Framework

        preloadClasses();

        preloasResources();

        ...

        //Run SystemSever

        if(argv[1].equals(“true”)){

           startSystemServer();

        }

        ...

        if(ZYGOTE_FORK_MODE){

            runForkMode();

        }else {

            //Processing new Android application running request

            runSelectLoopMode();

        }

        closeSeverSocket();

    }catch(MethodANdArgsCaller caller){

        caller.run();

    }catch(RuntimeException ex){

        log.e(TAG,”Zygote died with exception”,ex);

        closeServerSocket();

        throw ex;

    }

}

The ZygoteInit class will call the preloadClasses() and preloadResources() methods. These two methods are used to load the classes in the application Framework, as well as resources such as icons, images, and strings, into the memory, and control the loaded classes Generate link information with resources. When the newly generated Android application uses these loaded classes or resources, it can be used directly. At this point, the Dalvik virtual machine has been started and initialized, and a socket has been bound to receive application creation requests. In addition, the classes and resources contained in the application framework are also loaded into memory. Therefore, the ZygoteInit class is ready to receive a request to create an application and run it. But before ZygoteInit processes the application creation request, another job is to run SystemServer.

After the Zygote process starts the Dalvik virtual machine, it will generate a Dalvik virtual machine instance to run the java service named SystemServer, which is used to run Audio Flinger and Surface Flinger local services. After running the required local services, SystemServer starts to run Android Framework services, such as ActivityManager (Activity for managing Android applications), PackageManager (setting or installing applications), etc.

4 Home startup and startup of other applications

4.1 Starting the application 

   After SystemSever runs, the program enters a loop to process requests from the bound socket. If ZYGOTE_FORK_MODE is false, the program will call the runSelectLoopMode() method, which will not return until the zygote process terminates.

Next, take a look at some of the source code of runSelectLoopMode.

private static void runSelectLoopMode() throws MethodAndArgsCaller{

      ......

      fds.add(sSeverSocket.getFileDescriptor());

       while(true){

           ......

           index = selectReadable(fdArray);

           ......

           if(index <0){

               throw new RuntimeException("Error in select()");

           }

           else if(index ==0){

              ZygoteConnection newPeer = acceptCommandPeer();

              peers.add(newPeer);

              fds.add(newPeer.getFileDescriptor());

           }

           else {

               boolean done;

               done = peers.get(index).runOnce();

               if(done){

                   peers.remove(index);

                   fds.remove(index);

               }

           }

       }

}

donr = peers.get(index).runOnce() This line of code is used to process the newly connected input and output sockets and generate a new Android application. The specific process is as follows.

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller{

     ...

     try{

        args = readArgumentList();

        ...

     }

     ...

     int pid;

     try{

        parseArgs =new Arguments(args);

        applyUidSecurityPolicy(pareseArgs,peer);

        applyDebuggerSecurityPolicy(parseArgs);

        applyRlimitSecurityPolicy(parsedArgs,peer);

        applyCapailitiesSecurityPolicy(parseArgs,peer);

       int[][] rlimits = null;

       if(parsedArgs.rlimits != null){

          rlimits = paresedArgs.rlimits.toArry (intArray2d);

       }

       pid = Zygote.forkAndSpecialize(parsedArgs.uid,parsedArgs.gid,parsedArgs.gids,parsedArgs.debugFlagd,rlimits);

     }

     ......

}

The runOnce() function analyzes the string array in the request information and sets various options for the running process, including setting the gid and uid of the application, debugging mark processing, setting rlimit, and checking running permissions. After that, a new process can be created. The Zygote.forkAndSpecialize() method accepts the parameters analyzed above and calls the local method forkAndSpecialize() of the Zygote class. Then call the local function fork() to create a new process, and set uid, gid, rlimit, etc. according to the options passed by the newly created process. At this point, the newly running application has been started. The newly-running application is dynamically loaded by the ZygoteInit class, and is loaded into the parent process to generate virtual machine code. In addition, the link information of the classes and resources in the application FrameWork is shared, which greatly speeds up the creation and startup of the application.

4.2 Start of Home

The start of Activity must be related to the start of ActivityManagerService. The following is the relevant source code for SystemServer to execute init2().

public static final void init2() {   

    //Create thread to process

       Thread thr = new ServerThread();      

       thr.setName("android.server.ServerThread");

       thr.start();

}

 

//Look at what is done in the thread ServerThread?

public void run() {

    addBootEvent(new String("Android:SysServerInit_START"));

    Looper.prepare();

    android.os.Process.setThreadPriority(

    android.os.Process.THREAD_PRIORITY_FOREGROUND);

 

    //Initialize services, create various service instances, such as: power, network, Wifi, Bluetooth, USB, etc.,

  //Add to ServiceManager after initialization,

    //We use Context.getSystemService (String name) to get the corresponding service

    PowerManagerService power = null;

    NetworkManagementService networkManagement = null;

    WifiP2pService wifiP2p = null;

    WindowManagerService wm = null;

    BluetoothService bluetooth = null;

    UsbService usb = null;

    NotificationManagerService notification = null;

    StatusBarManagerService statusBar = null;

    ……

 

    power = new PowerManagerService();

    ServiceManager.addService(Context.POWER_SERVICE, power);

    ……

 

    // ActivityManagerService as the most important service of ApplicationFramework

    ActivityManagerService.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, notify each module

    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...

                  ActivityManagerService.systemReady( );

                  appWidgetF.systemReady(safeMode);

                  wallpaperF.systemReady();

           }

    });

 

    //

    //BOOTPROF

    addBootEvent(new String("Android:SysServerInit_END"));

    Looper.loop();

}

It can be seen from the above that the system has done such actions after starting all Android services, using xxx.systemReady() to notify each service that the system is ready. Which also includes ActivityManagerService.system-

Callback for Ready( ). Home is established during the notification process of ActivityManagerService.systemReady( ).

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

    }

  }

  ……

}

From the above analysis, it is concluded that HomeActivity is executing mService.startHomeAct-

Start after ivityLocked. The Home interface starts, completing the entire Android startup process.

                                               A brief analysis of the Android OS startup process-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

5 Conclusion

   The Android system hierarchy is divided into four application layers: application layer, application layer and framework layer, system runtime library layer, and Linux core layer, application layer and framework layer, system runtime library layer, and Linux core layer. Each layer has its own function. The Linux core layer faces the underlying hardware, the system operation layer supports the entire system, the application layer supports the application layer, and the application layer faces the user to provide users with a good interactive interface. This article is based on the Linux core layer, bypassing the hardware layer and briefly explains the startup process of the Android system.

   There are many places to add my own understanding about this article, and there are many shortcomings I hope to understand

Guess you like

Origin blog.csdn.net/u014440645/article/details/41019439