天天看點

Android從按下開機鍵到啟動發生了什麼

作為一個Android開發者,了解整個系統架構是必須的,是以這篇就總結一下Android手機從按下開機鍵到啟動這一過程發生了什麼。

要了解Android手機啟動過程,我們先來了解一下基于linux系統的電腦從按下電源鍵的那一刻起,發生了什麼,這樣類比可以更好的了解Android手機的啟動過程。

基于Linux的pc啟動過程

我們都知道,所有的程式軟體包括作業系統都是運作在記憶體中的,然而我們的作業系統一般是存放在硬碟上的,當我們按下開機鍵的時候,此時記憶體中什麼程式也沒有,是以需要借助某種方式,将作業系統加載到記憶體中,而完成這項任務的就是BIOS。

裝過系統的人一定知道BIOS這個東西,那麼它究竟是什麼呢?

BIOS:Basic Input/Output System(基本輸入輸出系統),在IBM PC相容系統上,是一種業界标準的固件接口(來自維基百科)。有點難以了解,其實BIOS是我們電腦啟動時加載的第一個程式,這個程式不是由Java語言編寫也不是由C語言編寫,一般是彙程式設計式。BIOS程式固化在主機闆上的一塊晶片上,是連接配接計算機硬體與作業系統的橋梁,它儲存着計算機最重要的基本輸入輸出的程式、開機後自檢程式和系統自啟動程式。

那麼問題來了,BIOS程式又是怎麼啟動的?BIOS的啟動,是由硬體完成的,Intel 80x86

系列的cpu的硬體都設計為加電(即開機瞬間)就進入16位實模式狀态運作,此時将cpu的硬體邏輯設計為強行将CS的值設定為0xFFFF,IP的值設定為0x0000,這樣CS:IP就指向了0xFFFF0這個位置,而這個位置就是BIOS程式的入口位址。是以這是一個硬體廠商之間的約定,所有的BIOS程式入口位址均為0xFFFF0,這樣在開機的時候,就找到這個位址,如果該位址并沒有代碼段,那麼計算機将會當機,如果這個位址處有代碼段,将會執行這個代碼段,并由此執行下去,即BIOS程式開始啟動。

補充:

CS:代碼段寄存器,存在于CPU中,指向CPU目前執行代碼在記憶體中所在的區域。

IP:指令寄存器,存在于CPU中,記錄将要執行的指令在代碼段内的偏移位址,與CS組合即為将要執行的指令的記憶體位址。

當BIOS程式啟動時,就會檢測硬體裝置,比如我們的顯示卡、記憶體等資訊。BIOS會在記憶體中建立中斷向量表和中斷服務程式。中斷向量表中有256個中斷向量,每個中斷向量占4個位元組,每個中斷向量指向一個中斷服務程式,這些中斷服務程式完成了将作業系統由硬碟加載到記憶體中的任務。

基于linux的作業系統而言,計算機将分三批逐次加載作業系統的代碼,第一批由BIOS中斷int 0x19将第一扇區bootsect的内容加載到記憶體;第二批和第三批在bootsect的指揮下,分别加載後面扇區的内容到記憶體中。

經過執行一系列的BIOS代碼後,計算機完成了自檢等操作,計算機硬體體系會與BIOS聯合操作,讓cpu接收到一個int 0x19中斷,cpu接收到這個中斷後,會立即在中斷向量表中找到int 0x19中斷向量,此時會找到對應的中斷服務程式,并由該中斷服務程式将硬碟中第一個扇區的引導程式加在到記憶體中的指定位置。随後,在引導程式的作用下,陸續将作業系統的其他程式載入記憶體,完成實模式到保護模式的轉變,為執行作業系統的入口函數main做準備,後面就是作業系統的初始化工作了,最後完成計算機的啟動。

Android手機的啟動過程

Android系統雖然也是基于linux系統的,但是由于Android屬于嵌入式裝置,并沒有像pc那樣的BIOS程式。取而代之的是Bootloader——系統啟動加載器。它類似于BIOS,在系統加載前,用以初始化硬體裝置,建立記憶體空間的映像圖,為最終調用系統核心準備好環境。在Android裡沒有硬碟,而是ROM,它類似于硬碟存放作業系統,使用者程式等。ROM跟硬碟一樣也會劃分為不同的區域,用于放置不同的程式,在Android中主要劃分為一下幾個分區:

  • /boot:存放引導程式,包括核心和記憶體操作程式
  • /system:相當于電腦c盤,存放Android系統及系統應用
  • /recovery:恢複分區,可以進入該分區進行系統恢複
  • /data:使用者資料區,包含了使用者的資料:聯系人、短信、設定、使用者安裝的程式
  • /cache:安卓系統緩存區,儲存系統最常通路的資料和應用程式
  • /misc:包含一些雜項内容,如系統設定和系統功能啟用禁用設定
  • /sdcard:使用者自己的存儲區,可以存放照片,音樂,視訊等檔案

那麼Bootloader是如何被加載的呢?我們可以想到,應該跟pc一樣,當開機加電的時候,cpu會從cpu制造廠商預設的位址上取指令,這個位址是各廠商約定俗稱的,類似于上面80x86架構裡的0xFFFF0位址,是以Android手機會将固态儲存設備ROM預先映射到該位址上,當開機加電的時候,cpu就會從該位址執行/boot分區下的Bootloader程式,載入linux核心到RAM中。

當linux核心啟動後會初始化各種軟硬體環境,加載驅動程式,挂載根檔案系統,并開始執行根檔案系統的init程式,init程式是Android啟動過程中最重要的核心程式。

init程序是Android系統中使用者程序的鼻祖程序。init程序會啟動各種系統本地服務,如:Media Server、Service Manager、bootanim(開機動畫)等。init程序會在解析init.rc檔案後fork出Zygote,而Zygote是所有Java程序的父程序,我們的App都是由Zygote fork出來的。

Zygote程序主要包含:

  • 加載ZygoteInit類,注冊Zygote Socket服務端套接字;
  • 加載虛拟機;
  • 預加載Android核心類
  • 預加載系統資源

随後Zygote程序會fork出System Server程序,System Server程序負責啟動和管理整個framework,包括Activity Manager,PowerManager等服務。

當System Server将系統服務啟動就緒後,就會通知ActivityManager啟動首個Android程式Home即我們看到的桌面程式。

至此,從Android手機開機到看到桌面程式所有過程分析完了。

最後附一張整體流程圖,幫助更好了解(出處在下面參考連結中)

Android從按下開機鍵到啟動發生了什麼

參考:

http://blog.chinaunix.net/uid-26569496-id-3891554.html

http://ticktick.blog.51cto.com/823160/1659473

http://gityuan.com/2016/01/30/android-boot/

繼續閱讀