Android系統的啓動流程簡要分析

這是我結合網上的資料以及自己分析android4.4的源碼整理的筆記,對整個安卓系統的流程啓動進行了梳理,很多細節並未展開,只是簡要的進行了介紹.


一.Android系統的架構介紹


Android的整個系統分爲四層,從上至下爲應用層、框架層、系統庫、Linux內核層.




1.應用層


各種系統應用,比如電話、瀏覽器、日曆等.


2.框架層


也就是Framework層,提供各種服務,比如下圖的一些.




3.系統庫


3.1. 提供核心類庫,比如OpenGl,SQlite

3.2.提供Davlik虛擬機和Java核心類庫

如下圖舉例




4.Linux內核層


提供各種驅動和硬件抽象層.


二.Android系統的啓動流程

先放張啓動流程圖,跟着流程走



Linux內核啓動後會啓動init進程,init是所有進程的父進程,代碼位於根目錄下 system\core\init



init進程的作用主要是顯示開機動畫,通過解析init.rc腳本然後啓動一系列服務和進程.
這裏的服務包括媒體服務MediaServer和服務管理者ServiceManager,ServiceManager是服務的管家,添加、註冊和獲取服務都通過它.
這裏的進程包括安裝app、內存管理、Zygote等進程等.
最核心的的是Zygote進程,它是Android系統的第一個Java進程. ,它是由init進程執行app_process程序啓動的,app_process 程序代碼位於frameworks/base/cmds/app_process


在app_main.cpp裏啓動ZygoteInit和Davlik虛擬機

 if (zygote) {
    	//啓動ZygoteInit,Davlik虛擬機
    	runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");
    } else if (className) {
        
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        return 10;
    }


看下ZygoteInit這個類,它位於frameworks\base\core\java\com\android\internal\os目錄下.




它的代碼如下,看它在main方法裏究竟做了有一些什麼事情.


public static void main(String argv[]) {
        try {
            // 初始化Zygote
            SamplingProfilerIntegration.start();
            //註冊ZygoteSocket服務
            registerZygoteSocket();
            
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            //預加載Framework大部分的類和資源
            preload();
            
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            //完成Zygote的初始化
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // 在啓動之後做一次垃圾回收
            gc();
          
            //禁止追蹤,以便於派生的進程不繼承這個標記
            Trace.setTracingEnabled(false);
     
            //	如果有需求,直接從Zygote啓動system server             
            if (argv.length != 2) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }
            
            if (argv[1].equals("start-system-server")) {
            	// fork一個新的進程system_server
            	startSystemServer();
            
            } else if (!argv[1].equals("")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

            Log.i(TAG, "Accepting command socket connections");

            //處理客戶端連接請求
            runSelectLoop();

            //關閉服務Socket
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }


1.初始化Zygote

在這裏開啓對系統性能的統計


2.註冊ZygoteSocket服務

創建了一個Socket接口,用來和AMS(ActivityManagerService)通信


3.預加載Framework大部分的類和資源


它會開啓3個線程分別預加載3個東西:類、資源和OpenGl


static void preload() {
    	Thread preloadClasses = new Thread(new Runnable() {
			public void run() {
		        //加載類
				preloadClasses();
			}
		});
    	Thread preloadResources = new Thread(new Runnable() {
			public void run() {
				//加載資源
				preloadResources();
			}
		});
    	Thread preloadOpenGL = new Thread(new Runnable() {
			public void run() {
				//加載OpenGL
				preloadOpenGL();
			}
		});
    	
    	preloadClasses.start();
    	preloadResources.start();
    	preloadOpenGL.start();
    	try {
			preloadClasses.join();
			preloadResources.join();
			preloadOpenGL.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    }


4.完成Zygote的初始化

結束統計並生成結果文件

5.在啓動之後做一次垃圾回收

6.fork一個新的進程system_server

fork是linux的的方法,會複製出一個與原來進程一樣的進程,但是如果初始參數或者傳入的變量不同,兩個進程也可以做不同的事.

startSystemServer的代碼如下

/**
     * 準備參數和fork 系統服務進程 
     */ 
    private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {
        long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_KILL,
            OsConstants.CAP_NET_ADMIN,
            OsConstants.CAP_NET_BIND_SERVICE,
            OsConstants.CAP_NET_BROADCAST,
            OsConstants.CAP_NET_RAW,
            OsConstants.CAP_SYS_MODULE,
            OsConstants.CAP_SYS_NICE,
            OsConstants.CAP_SYS_RESOURCE,
            OsConstants.CAP_SYS_TIME,
            OsConstants.CAP_SYS_TTY_CONFIG,
            OsConstants.CAP_BLOCK_SUSPEND
        );
        /* 啓動系統服務的核心命令行 */       	 
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
            "--capabilities=" + capabilities + "," + capabilities,
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        //進程id
        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* 請求fork系統服務進程 */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* 對新fork出的系統進程,執行handleSystemServerProcess() */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }
代碼裏會fork出SystemServer.之後進入到SystemServer.java這個類中.

代碼位於:frameworks/base/services/java/com/android/server/SystemServer.java

SystemServer的main方法會調用

ServerThread thr = new ServerThread();
thr.initAndLoop();

開啓一個線程ServerThread,在這裏面加載各種服務,比如WindowManagerServer(Wms)、ActivityManagerService(Ams)、PackageManagerServer(Pms)等.

7.runSelectLoop

處理客戶端的連接請求,等待其他進程的請求.

8.closeServerSocket()

關閉服務Socket.


至此,整個系統服務已經運行起來了,至於怎麼安裝程序、啓動桌面等,以後再寫.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章