Androidシステムの起動プロセスの簡単な分析

要約:Androidシステムの起動プロセスは、initプロセスの起動、ネイティブサービスの起動、SystemServer、Androidサービスの起動、およびホームの起動の4つのステップに要約できます。さまざまなステップは互いに密接にリンクしており、統一された全体を形成しています。

キーワード:initプロセス、Zygoteプロセス、SystemServer

1 Android OSアーキテクチャ

Androidシステムは、アプリケーションレイヤー、アプリケーションレイヤーとフレームワークレイヤー、システムランタイムレイヤー、およびLinuxコアレイヤーの4つのレベルに分割された、高レベルから最下位までの階層化されたアーキテクチャを使用します。Androidシステムアーキテクチャ図を見ると、それによって提供される基本的なアプリケーション(ホーム、カメラ、ダイヤラ、ブラウザなど)がアプリケーションフレームワークで実行されていることがわかります。開発者は、Android SDKを使用してアプリケーションフレームワークAPIを呼び出し、アプリケーションフレームワークレイヤーでも実行されるアプリケーションを開発できます。


 
                         Android OS起動プロセスの簡単な分析-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

                                             Androidシステムアーキテクチャ図

    Androidシステムの各レベルにはさまざまな機能があるため、ここでは概要を説明せず、予備的な理解のみを行います。

2 initプロセスとその起動

initプロセスは、ユーザレベルのプロセスであるinitは、多くの重要なタスクがある孤児プロセスと運用レベルだけでなく、取引を達成するために、(ユーザーのログイン用)のgettyを起動するように、など、initは常に最初のプロセスです。

起動時に、まずブートローダー(システムローダー)を介してLinuxカーネルをロードします。Linuxがブートカーネルをロードするとき、それは通常のLinuxブートプロセスと同じで、最初にカーネルが初期化され、次にinitプロセスが呼び出されます。

                                 Android OS起動プロセスの簡単な分析-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

                                        initプロセスの起動プロセス

initプロセスのスタートアップ図からわかるように、init_processは、start_kernel()関数、init_post()関数、run_init_process()関数が順次実行された後に最後に実行されます。initプロセスを開始するコードは次のとおりです。

静的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”);

}

Android initプロセスは、さまざまなデバイスを初期化し、Androidフレームワークに必要なさまざまなデーモン、ServiceManager、Zygoteなどを実行します。その中でも、ServiceManagerはAndroidシステムサービスを管理するための重要なプロセスです。システムサービスは、Androidフレームワークの重要なコンポーネントであり、カメラ、オーディオ、ビデオ、処理、およびさまざまなアプリケーションの作成に必要な重要なAPIを提供します。

initプロセスは、子プロセスの終了処理を実行するだけでなく、アプリケーションプログラムがデバイスドライバーにアクセスするときにデバイスノードファイルを生成し、属性サービスを提供し、システム操作に必要な環境変数を保存します。さらに、init.rc起動スクリプトファイルを分析し、関連ファイルに含まれる内容に基づいて対応する機能を実行します。

Androidが起動すると、init.rcスクリプトファイルを使用して、システム環境を設定し、実行するプロセスを記録します。2番目は、init.rcに従ってinitプロセスによって生成されるアクションリストとサービスリストに関連するコンテンツです。Init.rcファイルの構造は次のとおりです

                                                               Android OS起動プロセスの簡単な分析-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

init.rcファイルの構造

2.1アクションリスト

    アクションリストの「on init」段落では、主に環境変数を設定し、システム操作に必要なファイルまたはディレクトリを生成し、対応する権限を変更し、システム操作に関連するディレクトリをマウントします。

                     Android OS起動プロセスの簡単な分析-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

                                                  初期段落 

    「on init」ルートファイルシステムのマウント部分では、2つのディレクトリ/ systemおよび/ dataが主にマウントされます。2つのディレクトリがマウントされると、Androidルートファイルシステムの準備が整います。

2.2サービス一覧

init.rcスクリプトファイルでは、「service」段落は、initプロセスによって開始されたプロセスを記録するために使用されます。initプロセスによって開始される子プロセスは、1回限りのプログラムか、バックグラウンドで実行されているアプリケーションプログラムとシステムサービス管理に関連するServiceManagerプロセスです。

                             Android OS起動プロセスの簡単な分析-Hongye Ningxiang-Mu Yu Xiaoxiao
 
                      Android OS起動プロセスの簡単な分析-Hongye Ningxiang-Mu Yu Xiaoxiao
 


 

最後に、initプロセスは終了しませんが、プロパティサービスとして機能します。

3接合プロセス

文字通り、受精卵は「受精卵、つなぎ、接合子」を意味します。Androidシステムで新しいアプリケーションを実行するには、受精と卵の分割が実行される前に、それをZygoteプロセス(アプリケーションの実行に必要なさまざまな要素と条件を持つ)と組み合わせる必要があります。接合体は、Androidシステムアプリケーション、その主な機能で非常に重要なプロセスです。

Androidアプリを実行することです。

Zygoteプロセスが実行されると、Dalvik仮想マシンが初期化され、起動されます。AndroidアプリケーションはJavaで作成されており、Linuxでローカルプロセスとして直接実行することはできませんが、Dalvik仮想マシンでのみ実行できます。この時点で、Androidアーキテクチャに対応でき、システムはすでにシステムランタイムレイヤーで実行されています。Androidサービスとアプリケーションはすべて、Zygoteプロセスによって起動および実行されます。

app_processでZygoteInitクラスを実行する

ZygoteはJavaで記述されており、initプロセスで直接起動および実行することはできません。Zygoteクラスを実行する場合は、最初にDalvik仮想マシンを生成してから、Dalvik仮想マシンでZygoteInitクラスをロードして実行する必要があります。app_processプロセスがこのタスクを実行します。app_processプロセスが実行されると、AppRuntimeオブジェクトが最初に共通になります。ソースコードの一部は以下の通りです

int main(){

     ...

    AppRuntimeランタイム。

    ..

    //「-」までのすべて、または「-」以外の最初の引数はすべて* vm

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

    //次の引数は親ディレクトリです

    もし私が

       runtime.mParentDir = argv [i ++];

    }

}

AppRuntimeクラスはAndroidRuntimeクラスを継承しています。AndroidRuntimeクラスは、Dalvik仮想マシンを初期化して実行する前に実行されます。AppRuntimeオブジェクトを介して、環境変数と操作パラメーターが分析され、仮想マシンオプションが生成されます。仮想マシンに渡されるパラメーターを分析し、AppRuntimeクラスのオブジェクトに保存した後、オブジェクトをロードして、オブジェクトのmain()メソッドを呼び出します。

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

   ...

   もし私が 

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

      //仮想マシンを生成して初期化します

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

             、startSystemSever);

   }そうしないと {...}

   }

   ...

}

Dalvik仮想マシンは、ランタイムによって起動および初期化され(上記の注を参照)、次にZygoteInitクラスが仮想マシンにロードされ、mainメソッドが実行されます。

ZygoteInitクラスには4つの主要な機能があります。/dev/socket/zygoteソケットのバインド、アプリケーションフレームワークへのクラスとプラットフォームリソースのロード、SystemServerの実行、新しいAndroidアプリケーションの実行です。ここでは、一部の機能について簡単に説明します。ZygoteInit :: main()メソッドの主な機能は次のとおりです。

                      Android OS起動プロセスの簡単な分析-Hongye Ningxiang-Mu Yu Xiaoxiao         

                                                     ZygoteInit関数図

ZygoteInitクラスのソースコードの一部を見てみましょう。

public static void main(String argv []){

     試す{

        //ソケットをバインドし、新しいAndroidアプリケーション要求を受け入れます

        registerZygoteSocket();

        ...

        // Android Application Frameworkによって使用されるクラスリソースをロードします

        preloadClasses();

        preloasResources();

        ...

        // SystemSeverを実行します

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

           startSystemServer();

        }

        ...

        if(ZYGOTE_FORK_MODE){

            runForkMode();

        }そうしないと {

            //リクエストを実行する新しいAndroidアプリケーションを処理しています

            runSelectLoopMode();

        }

        closeSeverSocket();

    } catch(MethodANdArgsCaller caller){

        caller.run();

    } catch(RuntimeException ex){

        log.e(TAG、” Zygoteが例外で死亡しました”、ex);

        closeServerSocket();

        exを投げる;

    }

}

ZygoteInitクラスは、preloadClasses()メソッドとpreloadResources()メソッドを呼び出します。これらの2つのメソッドは、アプリケーションフレームワークのクラスと、アイコン、画像、文字列などのリソースをメモリに読み込むために使用されます。リソースとのリンク情報を生成します。新しく生成されたAndroidアプリケーションがこれらのロードされたクラスまたはリソースを使用する場合、それを直接使用できます。この時点で、Dalvik仮想マシンは起動および初期化されており、アプリケーション作成要求を受信するためにソケットがバインドされています。さらに、アプリケーションフレームワークに含まれるクラスとリソースもメモリに読み込まれます。したがって、ZygoteInitクラスはアプリケーションを作成して実行するリクエストを受け取る準備ができています。しかし、ZygoteInitがアプリケーション作成要求を処理する前に、別のジョブはSystemServerを実行することです。

ZygoteプロセスがDalvik仮想マシンを開始した後、Dalvik仮想マシンインスタンスを生成して、System Serverという名前のjavaサービスを実行します。これは、Audio FlingerおよびSurface Flingerローカルサービスを実行するために使用されます。必要なローカルサービスを実行した後、SystemServerは、ActivityManager(Androidアプリケーションを管理するためのアクティビティ)、PackageManager(アプリケーションの設定またはインストール)などのAndroidフレームワークサービスの実行を開始します。

4ホームの起動と他のアプリケーションの起動

4.1アプリケーションの開始 

   SystemSeverの実行後、プログラムは、バインドされたソケットからの要求を処理するループに入ります。ZYGOTE_FORK_MODEがfalseの場合、プログラムはrunSelectLoopMode()メソッドを呼び出します。このメソッドは、zygoteプロセスが終了するまで戻りません。

次に、runSelectLoopModeのソースコードをいくつか見てみましょう。

プライベート静的void runSelectLoopMode()はMethodAndArgsCaller {をスローします

      ……

      fds.add(sSeverSocket.getFileDescriptor());

       while(true){

           ……

           index = selectReadable(fdArray);

           ……

           if(index <0){

               新しいRuntimeException( "select()のエラー");

           }

           else if(index == 0){

              ZygoteConnection newPeer = acceptCommandPeer();

              peers.add(newPeer);

              fds.add(newPeer.getFileDescriptor());

           }

           そうしないと {

               ブール演算が完了しました。

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

               if(done){

                   peers.remove(index);

                   fds.remove(index);

               }

           }

       }

}

donr = peers.get(index).runOnce()このコード行は、新しく接続された入力ソケットと出力ソケットを処理し、新しいAndroidアプリケーションを生成するために使用されます。具体的なプロセスは次のとおりです。

boolean runOnce()はZygoteInit.MethodAndArgsCaller {をスローします

     ...

     試す{

        args = readArgumentList();

        ...

     }

     ...

     int pid;

     試す{

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

     }

     ……

}

runOnce()関数は、リクエスト情報の文字列配列を分析し、アプリケーションのgidとuidの設定、マーク処理のデバッグ、rlimitの設定、実行権限のチェックなど、実行プロセスのさまざまなオプションを設定します。Zygote.forkAndSpecialize()メソッドは、上記で分析したパラメーターを受け入れ、ZygoteクラスのローカルメソッドforkAndSpecialize()を呼び出します。次に、ローカル関数fork()を呼び出して新しいプロセスを作成し、新しく作成されたプロセスによって渡されたオプションに従って、uid、gid、rlimitなどを設定します。この時点で、新しく実行中のアプリケーションが開始されています。新しく実行されるアプリケーションは、ZygoteInitクラスによって動的に読み込まれ、親プロセスに読み込まれて仮想マシンコードを生成します。さらに、アプリケーションFrameWorkのクラスとリソースのリンク情報が共有されるため、アプリケーションの作成と起動が大幅に高速化されます。

4.2ホームの開始

Activityの開始は、ActivityManagerServiceの開始に関連している必要があります以下は、SystemServerがinit2()を実行するための関連するソースコードです。

public static final void init2(){   

    //処理するスレッドを作成

       スレッドthr = new ServerThread();      

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

       thr.start();

}

 

//スレッドServerThreadで何が行われているかを確認します。

public void run(){

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

    Looper.prepare();

    android.os.Process.setThreadPriority(

    android.os.Process.THREAD_PRIORITY_FOREGROUND);

 

    //サービスを初期化し、電源、ネットワーク、Wifi、Bluetooth、USBなどのさまざまなサービスインスタンスを作成します。

  //初期化後にServiceManagerに追加し、

    //Context.getSystemService(文字列名)を使用して、対応するサービスを取得します

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

    ……

 

    // ApplicationFrameworkの最も重要なサービスとしてのActivityManagerService

    ActivityManagerService.setSystemProcess();

    ActivityManagerService.installSystemProviders();

    ActivityManagerService.self()。setWindowManager(wm);   

  //ここで、アクティビティマネージャーにサードパーティを実行してもよいと伝えます

  //コード。状態になったらコールバックします

  //サードパーティのコードが実際に実行できる場所(ただし、実際に実行される前)

  //最初のアプリケーションの起動を開始しました)。

  //初期化。

  //システムサービスの初期化の準備ができました。各モジュールに通知してください

    ActivityManagerService.self()。systemReady(new Runnable(){

 

           public void run(){

                  startSystemUi(con​​textF);

                  batteryF.systemReady();

                  networkManagementF.systemReady();

                  usbF.systemReady();

                  ……

 

                  //これで、さまざまなシステムサービスを開始できるようになりました

                  //サードパーティコード...

                  ActivityManagerService.systemReady();

                  appWidgetF.systemReady(safeMode);

                  wallpaperF.systemReady();

           }

    });

 

    //

    // BOOTPROF

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

    Looper.loop();

}

上記から、システムがすべてのAndroidサービスを開始した後、xxx.systemReady()を使用してシステムの準備ができたことを各サービスに通知することで、システムがそのようなアクションを実行したことがわかります。これにはActivityManagerService.system-も含まれます

Ready()のコールバック。ホームは、ActivityManagerService.systemReady()の通知プロセス中に確立されます。

public void systemReady(final Runnable goingCallback){

    ……

    //準備完了のコールバック

       if(goingCallback!= null)

              goingCallback.run();

 

       同期(これ){

              //初期アクティビティを開始します。

              // ActivityStack mMainStack;

              mMainStack.resumeTopActivityLocked(null);

       }

……

 

}

final boolean resumeTopActivityLocked(ActivityRecord prev){

  //終了していない最初のアクティビティを見つけます。

 ActivityRecord next = topRunningActivityLocked(null);

  if(next == null){

    //これ以上活動はありません!始めましょう

    //ランチャー...

    if(mMainStack){

      // ActivityManagerService mService;

      mService.startHomeActivityLocked();を返します。

    }

  }

  ……

}

上記の分析から、HomeActivityがmService.startHomeAct-

ivityLockedの後に開始します。ホームインターフェースが起動し、Android起動プロセス全体が完了します。

                                               Android OS起動プロセスの簡単な分析-Hongye Ningxiang-Mu Yu Xiaoxiao
 

 

5。結論

   Androidシステム階層は、アプリケーションレイヤー、アプリケーションレイヤーとフレームワークレイヤー、システムランタイムライブラリレイヤー、Linuxコアレイヤー、アプリケーションレイヤーとフレームワークレイヤー、システムランタイムライブラリレイヤー、Linuxコアレイヤーの4つのアプリケーションレイヤーに分かれています。各レイヤーには独自の機能があります。Linuxコアレイヤーは基盤となるハードウェアに面し、システム操作レイヤーはシステム全体をサポートし、アプリケーションレイヤーはアプリケーションレイヤーをサポートし、アプリケーションレイヤーはユーザーに面して、ユーザーに優れたインタラクティブインターフェイスを提供します。この記事は、ハードウェアレイヤーをバイパスしてLinuxコアレイヤーに基づいており、Androidシステムの起動プロセスについて簡単に説明しています。

   この記事について私自身の理解を追加する場所はたくさんあります、そして私が理解したい多くの欠点があります

おすすめ

転載: blog.csdn.net/u014440645/article/details/41019439