轉 android launch flow

來源:互聯網
上載者:User

標籤:

Android系統開機主要經曆三個階段:
  1. bootloader啟動
  2. Linux啟動
  3. Android啟動

 

開機檔案:

對於機器從通電到載入Linux系統一般需要三個檔案:bootloader(引導檔案)、kernel(核心檔案)、rootfs (根檔案系統 能讓作業系統正常啟動並執行檔案夾和檔案的大集合,在Android中是ramdisk)。這些檔案在ROM Build的時候會編譯成IMAGE的形式打包到ROM中。

 

Android系統主要分為兩個區。system分區包含有Android運行時架構、系統APP以及預裝的第三方APP等;boot分區包含有kernel。刷入到system分區和boot分區的兩個鏡像稱為system.img和boot.img

 

Ramdisk 是將一部分固定大小的RAM空間類比出硬碟分區,在引導時核心以唯讀方式掛載它。它並非一個實際的檔案系統,而是一種將實際的檔案系統裝入記憶體的機制,並且可以作為根檔案系統。將一些經常被訪問而又不會更改的檔案 ( 如唯讀根檔案系統 ) 通過 Ramdisk 放在記憶體中,可以明顯地提高系統的效能。但是對於這些檔案的修改,掉電後就會丟失,只能修改IMG並重刷。

 

ramdisk.img是一個唯讀image分區,包含了Linux主要的目錄機構,可以單獨編譯或編譯到核心。主要是存放android啟動後第一個使用者進程init可執行檔和init.*.rc等相關啟動指令碼以及sbin目錄下的adbd工具。而system, data,dev,proc,sys等目錄都是空的,用來掛載對應的分區的。

 

通過刷機可以將這些IMG檔案刷入到手機的Flash儲存中。而一般手機Flash主要有兩類:

 

NOR Flash:特點是晶片內執行(XIP, eXecute In Place),這樣應用程式可以直接在flash快閃記憶體內運行,不必再把代碼讀到系統RAM中。NOR的傳輸效率很高,在1~4MB的小容量時具有很高的成本效益,但是很低的寫入和擦除速度大大影響了它的效能。


NAND Flash

NAND結構能提供極高的單元密度,可以達到高儲存密度,並且寫入和擦除的速度也很快。

 

啟動流程:

1. Bootloader啟動

bootloader是嵌入式系統的引導載入程式,是系統通電後啟動並執行第一段程式,主要作用是引導作業系統,類似PC上的BIOS程式。一般會分為BL1和BL2兩個階段,分別是初始化硬體和載入作業系統。準系統如下:

a)        硬體裝置初始化:主要包括屏蔽所有中斷,設定CPU的速度和時鐘頻率,關閉處理器內部指令,資料cache等;

b)        初始化RAM:設定CPU寄存器,為載入Kernel做準備;

c)        初始化串口:主要用來進行互動,輸出調試資訊;

d)        檢查CPU類型: Linux核心啟動時需要根據CPU類型調用相應的初始化程式;

e)        設定Linux啟動參數: Linux會根據參數進行相應的初始化操作;

f)         調用Linux Kernel Image:載入kernel和ramdisk到RAM指定地址,並轉跳到此地址開始執行Kernel的第一條指令。

 

啟動bootloader過程:

當機器通電後,ARM CPU的PC(程式計數器)寄存器的值是0x0,於是CPU會從這個地址取指令執行,所有嵌入式裝置都會把相關的ROM或Flash映射到這個地址(通過硬體引腳電平高低實現http://blog.csdn.net/yapingmcu/article/details/7248890)。如果bootloader存放在NOR Flash中,則0x0就是Flash中第一條指定地址,一般BL1在NOR中執行,而BL2載入到RAM執行提高速度; 如果存放在NANDFlash中,則需要將BL1載入到RAM執行,然後載入並執行BL2,不同晶片載入BL1的這個過程是不同的。

 

Bootloader還支援互動式啟動,在BL1完成後不是馬上執行BL2,而是等待使用者操作,這種啟動模式就叫做fastboot。

 

2. Linux啟動

a)        Kernel鏡像zImage解壓

b)        Kernel的彙編啟動: 根據BL中傳遞的參數,執行相應的初始化操作(與硬體平台相關),主要的一步是建立頁表,為核心建立4M的記憶體映射

c)        Kernel 的C啟動:執行init/main.c中start_kernel方法。它主要完成剩餘的與硬體平台相關的初始化操作。初始化核心進程調度器和中斷處理函數、建立檔案和系統緩衝、初始化記憶體管理MMU、初始化記憶體。

d)        rest_init()函數,kernel_thread()啟動第一個核心線程執行kernel_init()

                        i.             載入系統裝置和驅動程式,並進行初始化

                      ii.             載入Binder,建立/dev/binder裝置檔案,並註冊為misc裝置

                     iii.             將ramdisk作為rootfs掛載到根目錄/

                     iv.             調用execve()建立系統的第一個使用者進程Init (/system/core/init/init.c)

                      v.             解析並執行Init.rc檔案,啟動系統服務,此時線程進入使用者空間運行。

 

3. Android啟動

 

a)        解析並執行init.rc檔案(\system\core\rootdir\init.rc) (Android系統啟動過程比PC要簡單,init.rc與PC的內容也不相同,包含了4種不同操作稱為AndroidInit Launage 在system/core/Init/readme.txt有具體描述)

b)        建立dev、proc、system、data等目錄並掛載對應的分區,設定目錄和檔案的使用者和許可權。

c)        執行四種操作中的Action和Commands,然後啟動Native 空間的Service如console、adbd、vold、netd、media、ril-daemon、surfaceflinger、ril-daemon等等。

d)        啟動ServiceManager服務:是Binder的守護進程,主要負責整個系統service的管理,系統中所有的服務都必須在SMgr中註冊,擷取服務是也需要向Smgr申請,通過它獲得遠程服務的Binder實體。Android的IPC由Client、Service、ServiceManager和Binder組成,Binder驅動完成實際IPC功能,而SMgr則對service進行管理。

(frameworks\native\cmds\servicemanager\service_manager.c)

 

e)        啟動Zygote服務: Zygote進程也叫孵化進程,Android世界中所有的進程都是從此進程孵化而來(fork()),它負責應用程式架構層的其它進程的建立和啟動工作。

(frameworks/base/cmds/app_process/app_main.cpp) (Android L中啟動Zygote的指令碼不在init.rc檔案中,而是有單獨的init.zygote_xx.rc檔案來啟動,用於支援64位作業系統)

 

                           i.             Zygote建立AppRuntime並啟動,調用startVm,裡面會調用JNI_CreateJavaVM來啟動Davlik虛擬機器。並載入需要的庫和jar包,這樣每次fork出新的進程就不需要在載入VM了。

                          ii.             調用startReg()註冊Android的JNI方法

                        iii.             通過JNI從Native層調用Java層的com.android.internal.os.ZygoteInit類的main函數,這個函數主要做了下面3件事情:

  1. Zygote註冊一個socket用了進行進程通訊,當我們需要啟動一個Android應用程式時,AMS會通過Socket通知Zygote為這個應用程式建立一個新的進程。
  2. Zygote進程fork出一個SystemServer進程,SystemServer進程負責啟動系統的關鍵服務,如包管理服務PackageManagerService和應用程式組件管理服務ActivityManagerService。具體運行過程見f
  3. Zygote執行runSelectLoopMode進入迴圈來監聽socket請求

f)         運行SystemServer:被建立後會運行handleSystemServerProcess(),此進程將負責啟動其他的Android服務

(frameworks\base\services\java\com\android\server\SystemServer.java)

                        i.             關閉進程中的socket,因為是從Zygote進程fork出來的,但不需要使用。

                      ii.             載入libandroid_servers.so

                     iii.             執nativeInit ()啟動Native空間的Sensor Service,並註冊到ServiceManager (frameworks/base/services/core/jni/com_android_server_SystemServer.cpp)

                     iv.             執行ServerThread.initAndLoop()啟動Java空間的Service,並註冊到ServiceManage(主要包括AMS/WMS/ConnectivityService/InputManagerService等)

                      v.             調用每個service的systemReady方法通知service系統已經啟動完成

                     vi.             調用Looper.loop() 在主線程啟動訊息迴圈

 

PS: 我看Kitkat代碼和網上介紹的老版本不太一樣,老版本使用init1()和init2()兩個函數來啟動Native和Java的Service,而且init1中啟動了很多service,主要包括:Sensor/AudioFlinger/MediaPlayer/Camera/AudioPolicy,而這裡只啟動了sensor的服務。還不知道其他服務在那裡啟動。

 

g)        啟動Home:

                        i.             AMS的systemReady方法被調用,其中會調用resumeTopActivityLocked()

                      ii.             最終會調用到ActivityStack.java中的resumeTopActivityLocked

                     iii.             發現沒有其他任何的Activity,調用ActivityStackSupervisor.resumeHomeActivity

                     iv.             getHomeIntent擷取intent, Intent的category為Intent.CATEGORY.HOME,然後調用AMS.startHomeActivityLocked傳遞Intent

                      v.             調用ActivityStackSupervisor. startHomeActivity, 調用startActivityLocked()

                     vi.             通過resolveActivityInfo函數向 PackageManagerService 查詢 CATEGORY 類型為 HOME 的應用

                   vii.             最後AMS會通知Zygote啟動一個新的進程

h)        至此Android系統啟動過程全部完成

 

 

 

參考:

 

ROM、PROM、EPROM、EEPROM、Flash ROM的區別

 

Linux下Fork與Exec使用

http://www.cnblogs.com/hicjiajia/archive/2011/01/20/1940154.html

 

ARM Linux啟動過程分析

http://www.go-gddq.com/html/QianRuShiXiTong-JiShu/2012-08/1042290p2.htm

 

Android armlinux kernel啟動流程

http://blog.csdn.net/yili_xie/article/details/5716837

 

Android的init過程詳解(一)

http://www.cnblogs.com/nokiaguy/archive/2013/04/14/3020774.html

 

Android的init過程(二):初始化語言(init.rc)解析

http://www.cnblogs.com/nokiaguy/p/3164799.html

轉 android launch flow

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.