Un breve análisis del proceso de inicio del sistema Android

Resumen: El proceso de inicio del sistema Android se puede resumir como inicio del proceso de inicio, inicio del servicio nativo, SystemServer, inicio del servicio Android y inicio de 4 pasos. Los distintos pasos están estrechamente vinculados entre sí, formando un todo unificado.

Palabras clave: proceso init; proceso Zygote; SystemServer

1 arquitectura del sistema operativo Android

El sistema Android utiliza una arquitectura en capas, dividida en 4 niveles, desde el nivel superior hasta el nivel inferior son la capa de aplicación, la capa de aplicación y la capa de marco, la capa de tiempo de ejecución del sistema y la capa central de Linux. Observando el diagrama de la arquitectura del sistema Android, podemos encontrar que las aplicaciones básicas (Inicio, Cámara, Marcador, Navegador, etc.) que proporciona se ejecutan en el marco de la aplicación. Para los desarrolladores, los desarrolladores pueden usar el SDK de Android para llamar a la API del marco de la aplicación para desarrollar aplicaciones que también se ejecutan en la capa del marco de la aplicación.


 
                         Un breve análisis del proceso de inicio del sistema operativo Android: Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

                                             Diagrama de arquitectura del sistema Android

    Cada nivel del sistema Android tiene diferentes funciones, por lo que no daré una descripción general aquí, sino solo una comprensión preliminar.

2 proceso de inicio y su inicio

El proceso init es un proceso a nivel de usuario, init tiene muchas tareas importantes , como iniciar getty (para la conexión del usuario), para lograr el nivel operacional, así como tratar con los procesos huérfanos , etc. . init es siempre el primer proceso.

Al comenzar, primero cargue el kernel de Linux a través del cargador de arranque (cargador del sistema). Cuando Linux carga el kernel de arranque, es lo mismo que el proceso de arranque normal de Linux: primero se inicializa el kernel y luego se llama al proceso init.

                                 Un breve análisis del proceso de inicio del sistema operativo Android: Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

                                        El proceso de inicio del proceso de inicio

Se puede ver en el diagrama de inicio del proceso init que el proceso init se ejecuta en último lugar después de que la función start_kernel (), la función init_post () y la función run_init_process () se ejecuten secuencialmente. El código para iniciar el proceso de inicio es el siguiente:

Estático int noinline init_post (void)

{

    if (ejecutar_comando) {

       run_init_process (ejecutar_comando);

    }

   run_init_process (“/ sbin / init”);

   run_init_process (“/ etc / init”);

   run_init_process (“/ bin / init”);

}

El proceso de inicio de Android inicializa varios dispositivos y ejecuta varios Daemon, ServiceManager, Zygote, etc., requeridos por Android Framework. Entre ellos, ServiceManager es un proceso importante para administrar los servicios del sistema Android. Los servicios del sistema son un componente importante del marco de Android, y proporcionan API importantes necesarias para la cámara, el audio, el video, el procesamiento y la producción de varias aplicaciones.

El proceso init no solo realiza el procesamiento de terminación del proceso hijo, sino que también genera el archivo de nodo del dispositivo cuando el programa de aplicación accede al controlador del dispositivo, proporciona servicios de atributos y guarda las variables de entorno necesarias para el funcionamiento del sistema. Además, analizará el archivo de secuencia de comandos de inicio init.rc y ejecutará las funciones correspondientes según el contenido del archivo correspondiente.

Cuando se inicia Android, el archivo de script init.rc se usa para configurar el entorno del sistema y registrar el proceso a ejecutar; el segundo es el contenido relacionado con la lista de acciones y la lista de servicios, que son generados por el proceso init de acuerdo con init.rc. La estructura del archivo Init.rc es la siguiente

                                                               Un breve análisis del proceso de inicio del sistema operativo Android: Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

estructura de archivo init.rc

2.1 Lista de acciones

    En el párrafo "on init" de la lista de acciones, usted establece principalmente variables de entorno, genera archivos o directorios necesarios para el funcionamiento del sistema, modifica los permisos correspondientes y monta directorios relacionados con el funcionamiento del sistema.

                     Un breve análisis del proceso de inicio del sistema operativo Android: Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

                                                  en el párrafo de inicio 

    En la parte de montaje del sistema de archivos raíz "on init", los dos directorios / system y / data se montan principalmente. Una vez montados los dos directorios, el sistema de archivos raíz de Android está listo.

2.2 Lista de servicios

En el archivo de script init.rc, el párrafo "servicio" se usa para registrar el proceso iniciado por el proceso init. El proceso hijo iniciado por el proceso init es un programa de una sola vez o un proceso ServiceManager relacionado con los programas de aplicación y la gestión de servicios del sistema que se ejecutan en segundo plano.

                             Un breve análisis del proceso de inicio del sistema operativo Android: Hongye Ningxiang-Mu Yu Xiaoxiao
 
                      Un breve análisis del proceso de inicio del sistema operativo Android: Hongye Ningxiang-Mu Yu Xiaoxiao
 


 

Finalmente, el proceso init no sale, pero actúa como un servicio de propiedad.

3 Proceso del cigoto

Literalmente, cigoto significa "huevo fertilizado, aglutinante y conjugador". Para ejecutar una nueva aplicación en el sistema Android, debe combinarse con el proceso Zygote (que tiene varios elementos y condiciones requeridos por la aplicación para ejecutarse) al igual que la fertilización y división de un huevo antes de que pueda ejecutarse. Zygote es un proceso muy importante en la aplicación del sistema Android, su función principal

Es para ejecutar aplicaciones de Android.

Cuando el proceso Zygote se esté ejecutando, inicializará la máquina virtual Dalvik y la iniciará. Las aplicaciones de Android están escritas por Java. No pueden ejecutarse directamente en Linux como un proceso local, sino que solo pueden ejecutarse en la máquina virtual Dalvik. En este punto, podemos corresponder a la arquitectura de Android, y el sistema ya se ha ejecutado en la capa de tiempo de ejecución del sistema. Los servicios y aplicaciones de Android se inician y ejecutan mediante el proceso Zygote.

Ejecute la clase ZygoteInit por app_process

Zygote está escrito en Java y el proceso init no puede iniciarlo ni ejecutarlo directamente. Si desea ejecutar la clase Zygote, primero debe generar la máquina virtual Dalvik y luego cargar y ejecutar la clase ZygoteInit en la máquina virtual Dalvik El proceso app_process realiza esta tarea. Cuando se ejecuta el proceso app_process, el objeto AppRuntime es el primero en común. Parte del código fuente es el siguiente

int main () {

     ...

    Tiempo de ejecución de AppRuntime;

    ..

    // Todo hasta '-' o el primer argumento que no sea '-' va al * vm

    int i = tiempo de ejecución.addVmArguments (argc, argv);

    // El siguiente argumento es el directorio padre

    si yo

       runtime.mParentDir = argv [i ++];

    }

}

La clase AppRuntime hereda de la clase AndroidRuntime. La clase AndroidRuntime se ejecuta antes de inicializar y ejecutar la máquina virtual Dalvik. A través del objeto AppRuntime, se analizan las variables de entorno y los parámetros operativos, y se generan las opciones de la máquina virtual. Después de analizar los parámetros que se pasarán a la máquina virtual y guardarlos en el objeto de la clase AppRuntime, luego cargue el objeto y llame al método main () del objeto.

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

   ...

   si yo 

     arg = argv [i ++];

   if (0 == strcmp ("- cigoto", arg)) {

      bool startSyatemServer = (i <argc)?

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

      setArgv0 (argv0, ”cigoto”);

      set_process_name ("cigoto");

      // Genera e inicializa la máquina virtual

      runtime.start ("com.android.internal.os.ZygoteInit"

             , startSystemSever);

   } más {...}

   }

   ...

}

La máquina virtual Dalvik es iniciada e inicializada por el tiempo de ejecución (vea la nota anterior), y luego la clase ZygoteInit se carga en la máquina virtual y se ejecuta el método principal.

La clase ZygoteInit tiene cuatro funciones principales, que son enlazar sockets / dev / socket / zygote, cargar clases y recursos de plataforma en el marco de la aplicación, ejecutar SystemServer y ejecutar nuevas aplicaciones de Android. Aquí solo explicamos brevemente algunas de las funciones. La función principal del método ZygoteInit :: main () es la siguiente:

                      Un breve análisis del proceso de inicio del sistema operativo Android: Hongye Ningxiang-Mu Yu Xiaoxiao         

                                                     Diagrama de la función ZygoteInit

Echemos un vistazo a parte del código fuente de la clase ZygoteInit.

public static void main (String argv []) {

     tratar{

        // Enlazar socket, aceptar nueva solicitud de aplicación de Android

        registerZygoteSocket ();

        ...

        // Cargar recursos de clase usados ​​por Android Application Framework

        preloadClasses ();

        preloasResources ();

        ...

        // Ejecutar SystemSever

        if (argv [1] .equals ("verdadero")) {

           startSystemServer ();

        }

        ...

        si (ZYGOTE_FORK_MODE) {

            runForkMode ();

        } más {

            // Procesando una nueva solicitud de ejecución de una aplicación de Android

            runSelectLoopMode ();

        }

        closeSeverSocket ();

    } catch (MethodANdArgsCaller caller) {

        caller.run ();

    } catch (RuntimeException ex) {

        log.e (TAG, ”Zygote murió con excepción”, ex);

        closeServerSocket ();

        tirar ex;

    }

}

La clase ZygoteInit llamará a los métodos preloadClasses () y preloadResources (). Estos dos métodos se utilizan para cargar las clases en el marco de la aplicación, así como recursos como iconos, imágenes y cadenas, en la memoria y controlar las clases cargadas. Genere información de enlace con recursos. Cuando la aplicación de Android recién generada usa estas clases o recursos cargados, se puede usar directamente. En este punto, la máquina virtual de Dalvik se ha iniciado e inicializado y se ha vinculado un socket para recibir solicitudes de creación de aplicaciones. Además, las clases y los recursos contenidos en el marco de la aplicación también se cargan en la memoria. Por lo tanto, la clase ZygoteInit está lista para recibir una solicitud para crear una aplicación y ejecutarla. Pero antes de que ZygoteInit procese la solicitud de creación de la aplicación, otro trabajo es ejecutar SystemServer.

Una vez que el proceso Zygote inicia la máquina virtual Dalvik, generará una instancia de la máquina virtual Dalvik para ejecutar el servicio java llamado SystemServer, que se utiliza para ejecutar los servicios locales Audio Flinger y Surface Flinger. Después de ejecutar los servicios locales requeridos, SystemServer comienza a ejecutar los servicios de Android Framework, como ActivityManager (Actividad para administrar aplicaciones de Android), PackageManager (configurar o instalar aplicaciones), etc.

4 Inicio desde casa y inicio de otras aplicaciones

4.1 Iniciar la aplicación 

   Después de que SystemSever se ejecuta, el programa entra en un bucle para procesar las solicitudes del socket vinculado. Si ZYGOTE_FORK_MODE es falso, el programa llamará al método runSelectLoopMode (), que no regresará hasta que termine el proceso del cigoto.

A continuación, eche un vistazo a algunos de los códigos fuente de runSelectLoopMode.

private static void runSelectLoopMode () lanza MethodAndArgsCaller {

      ......

      fds.add (sSeverSocket.getFileDescriptor ());

       while (verdadero) {

           ......

           índice = selectReadable (fdArray);

           ......

           si (índice <0) {

               lanzar nueva RuntimeException ("Error en select ()");

           }

           más si (índice == 0) {

              ZygoteConnection newPeer = acceptCommandPeer ();

              peers.add (newPeer);

              fds.add (newPeer.getFileDescriptor ());

           }

           else {

               booleano hecho;

               hecho = peers.get (índice) .runOnce ();

               if (hecho) {

                   peers.remove (índice);

                   fds.remove (índice);

               }

           }

       }

}

donr = peers.get (index) .runOnce () Esta línea de código se utiliza para procesar los sockets de entrada y salida recién conectados y generar una nueva aplicación de Android. El proceso específico es el siguiente.

boolean runOnce () lanza ZygoteInit.MethodAndArgsCaller {

     ...

     tratar{

        args = readArgumentList ();

        ...

     }

     ...

     int pid;

     tratar{

        parseArgs = nuevos argumentos (argumentos);

        applyUidSecurityPolicy (pareseArgs, par);

        applyDebuggerSecurityPolicy (parseArgs);

        applyRlimitSecurityPolicy (parsedArgs, par);

        applyCapaity.comSecurityPolicy (parseArgs, par);

       int [] [] rlimits = null;

       if (parsedArgs.rlimits! = null) {

          rlimits = paresedArgs.rlimits.toArry(intArray2d);

       }

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

     }

     ......

}

La función runOnce () analiza la matriz de cadenas en la información de la solicitud y establece varias opciones para el proceso en ejecución, incluida la configuración del gid y el uid de la aplicación, la depuración del procesamiento de marcas, la configuración de rlimit y la verificación de los permisos de ejecución. Después de eso, se puede crear un nuevo proceso El método Zygote.forkAndSpecialize () acepta los parámetros analizados anteriormente y llama al método local forkAndSpecialize () de la clase Zygote. Luego llame a la función local fork () para crear un nuevo proceso y configure uid, gid, rlimit, etc. de acuerdo con las opciones pasadas por el proceso recién creado. En este punto, se ha iniciado la aplicación recién ejecutada. La aplicación recién ejecutada se carga dinámicamente mediante la clase ZygoteInit y se carga en el proceso principal para generar código de máquina virtual. Además, se comparte la información de enlace de las clases y recursos en la aplicación FrameWork, lo que acelera enormemente la creación y puesta en marcha de la aplicación.

4.2 Inicio del hogar

El inicio de Activity debe estar relacionado con el inicio de ActivityManagerService. El siguiente es el código fuente relevante para que SystemServer ejecute init2 ().

public static final void init2 () {   

    // Crear hilo para procesar

       Thread thr = new ServerThread ();      

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

       thr.start ();

}

 

// Mira lo que se hace en el hilo ServerThread?

public void run () {

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

    Looper.prepare ();

    android.os.Process.setThreadPriority (

    android.os.Process.THREAD_PRIORITY_FOREGROUND);

 

    // Inicializar servicios, crear varias instancias de servicio, tales como: energía, red, Wifi, Bluetooth, USB, etc.,

  // Agregar a ServiceManager después de la inicialización,

    // Usamos Context.getSystemService (String name) para obtener el servicio correspondiente

    PowerManagerService power = null;

    NetworkManagementService networkManagement = null;

    WifiP2pService wifiP2p = nulo;

    WindowManagerService wm = null;

    BluetoothService bluetooth = nulo;

    UsbService usb = null;

    Notificación de NotificationManagerService = nulo;

    StatusBarManagerService statusBar = null;

    ……

 

    poder = nuevo PowerManagerService ();

    ServiceManager.addService (Context.POWER_SERVICE, poder);

    ……

 

    // ActivityManagerService como el servicio más importante de ApplicationFramework

    ActivityManagerService.setSystemProcess ();

    ActivityManagerService.installSystemProviders ();

    ActivityManagerService.self (). SetWindowManager (wm);   

  // Ahora le decimos al administrador de actividades que está bien ejecutar un tercero

  // código. Volverá a llamarnos una vez que haya llegado al estado

  // donde el código de terceros realmente puede ejecutarse (pero antes de que realmente

  // comenzamos a lanzar las aplicaciones iniciales), para que podamos completar nuestro

  // inicialización.

  // La inicialización del servicio del sistema está lista, notifique a cada módulo

    ActivityManagerService.self (). SystemReady (new Runnable () {

 

           public void run () {

                  startSystemUi (contextF);

                  batteryF.systemReady ();

                  networkManagementF.systemReady ();

                  usbF.systemReady ();

                  ……

 

                  // Ahora está bien dejar que los distintos servicios del sistema inicien su

                  // código de terceros ...

                  ActivityManagerService.systemReady ();

                  appWidgetF.systemReady (safeMode);

                  wallpaperF.systemReady ();

           }

    });

 

    //

    // BOOTPROF

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

    Looper.loop ();

}

Se puede ver en lo anterior que el sistema ha realizado tales acciones después de iniciar todos los servicios de Android, usando xxx.systemReady () para notificar a cada servicio que el sistema está listo. Que también incluye ActivityManagerService.system-

Devolución de llamada para Ready (). El inicio se establece durante el proceso de notificación de ActivityManagerService.systemReady ().

public void systemReady (final Runnable goingCallback) {

    ……

    // devolución de llamada lista

       if (goingCallback! = null)

              goingCallback.run ();

 

       sincronizado (esto) {

              // Iniciar actividad inicial.

              // ActivityStack mMainStack;

              mMainStack.resumeTopActivityLocked (nulo);

       }

……

 

}

resumen booleano finalTopActivityLocked (ActivityRecord prev) {

  // Encuentra la primera actividad que no está terminando.

 ActivityRecord siguiente = topRunningActivityLocked (nulo);

  si (siguiente == nulo) {

    // ¡No hay más actividades! Vamos a poner en marcha el

    // Lanzador ...

    if (mMainStack) {

      // ActivityManagerService mService;

      return mService.startHomeActivityLocked ();

    }

  }

  ……

}

Del análisis anterior, se concluye que HomeActivity está ejecutando mService.startHomeAct-

Empiece después de ivityLocked. Se inicia la interfaz de inicio, completando todo el proceso de inicio de Android.

                                               Un breve análisis del proceso de inicio del sistema operativo Android: Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

5. Conclusión

   La jerarquía del sistema Android se divide en cuatro capas de aplicación: capa de aplicación, capa de aplicación y capa de marco, capa de biblioteca de tiempo de ejecución del sistema y capa de núcleo de Linux, capa de aplicación y capa de infraestructura, capa de biblioteca de tiempo de ejecución del sistema y capa de núcleo de Linux. Cada capa tiene su propia función. La capa central de Linux se enfrenta al hardware subyacente, la capa de operación del sistema es compatible con todo el sistema, la capa de aplicación es compatible con la capa de aplicación y la capa de aplicación se enfrenta al usuario para proporcionar a los usuarios una buena interfaz interactiva. Este artículo se basa en la capa central de Linux, sin pasar por la capa de hardware y explica brevemente el proceso de inicio del sistema Android.

   Hay muchos lugares para agregar mi propia comprensión sobre este artículo, y hay muchas deficiencias que espero comprender.

Supongo que te gusta

Origin blog.csdn.net/u014440645/article/details/41019439
Recomendado
Clasificación