android啟動核心分析_第1頁
android啟動核心分析_第2頁
android啟動核心分析_第3頁
android啟動核心分析_第4頁
android啟動核心分析_第5頁
已閱讀5頁,還剩36頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Android 啟動目錄Linux 啟動簡介11.1 概述21.2 系統(tǒng)的啟動31.3 第一階段 boot loader41.1.4 第boot loader51.5 內核5Android 啟動概述82.1 簡介82.2 啟動流程92.2.1 總體流程圖:92.2.2 分布說明9Android 啟動過程詳述183.1 init 進程183.1.1文件.2 服務啟制193.1.3 源代碼分析203.1.4 函數(shù)執(zhí)行流程圖283.1.5 init.rc 啟動的服務列表283.2 Zygote 啟動293.2.1 Zygote 總體介紹293.2.2 啟動 Zygote 流程313

2、.2.3 具體執(zhí)行代碼流程與層次結構323.3 System Server 啟動343.3.1 init1 啟動代碼分析343.3.2 init2 啟動代碼分析353.3.3 init2 啟動的 JAVA 服務373.4 Home 啟動401.Linux 啟動簡介linux 系統(tǒng)的啟動過程是由很多步驟組成的,但是,無論你是啟動一個標準的 x86 桌面計算機,還是一個PowerPC 的目標板,大多數(shù)的流程是驚人得相似的。這篇文章,探索了 linux 從最初的啟動準備到用戶空間中某個程序被開啟之間的啟動過程,跟隨這個流程,你還能學到其他許多與啟動有關的知識,例如,boot loaders,內核解壓

3、縮,初始化內存盤,以及其他一些 linux 啟動的部分。在很早的時候,啟動一個計算機意味著去處理那些包含啟動程序的紙帶,或者通過手工使用面板那密密麻麻的地址/數(shù)據(jù)/化這個流程并非必須的。開關來加載啟動程序,但是,簡讓我們首先從一個較高的高度上來對 linux 的啟動做一個全面的分析,然后,我們會回顧一下,在每一個的過,事情。在這途中的參考源代碼將幫助你在內核樹中不至于迷失方向,并能繼續(xù)深入挖掘下去。1.1概述圖 1 將是對啟動過程的整體回顧:Figure 1. The 20,000-foot view of the Linux boot process開始被啟動,或者重新啟動時,處理器將在眾所

4、周知的位置執(zhí)行代碼。在個人電腦上,這個位置處于基本輸入輸出系統(tǒng)中,也就是我們所說的 BIOS,它是被在主板上的閃存中的。在系統(tǒng)中,處理器(CPU)則將復位區(qū)域激活,來開始執(zhí)行 flash 或者 ROM 中的已知的程序。在其它情況中,基本的過程是一樣的。由于個人電腦提供了眾多靈活的可選設備,BIOS 必須確定,由哪一個設備來執(zhí)行啟動過程。在接下來的文章中涉及這方面的的內容。當找到啟動設備時,第一階段所用的 boot loader 被裝載到 RAM 中并被執(zhí)行。這里的 boot loader 在大小上小于一個扇區(qū)的大小,也就是 512 字節(jié),而它的任務,就是加載第的 boot loader。當負責

5、第的 boot loader 位于內存中并被執(zhí)行時,通常會顯示一個一閃而過的屏幕,然后 linux 以及可選的初始化內存盤(一種臨時的根文件系統(tǒng))會被裝載到器中。鏡像被加載時,第的 boot loader 將把權轉交給內核鏡像,與此同時,內核開始自解壓并初始化。在這個階段,第的 boot loader 會檢查系統(tǒng)的硬件,枚舉那些附加的硬件設備,掛載根設備,之后加載需要的內核模塊。完成之后,第一個用戶空間程序(init)開始執(zhí)行,更次的系統(tǒng)初始化開始。這就是從表面上看,linux 的啟動過程。好了,現(xiàn)在,讓我們更進一步,更深入地探索 linux 啟動過的一些細節(jié)。1.2 系統(tǒng)的啟動系統(tǒng)啟動的階段

6、,依賴于 linux 在哪個硬件設備上啟動。在系統(tǒng)中,被打開或者重新啟動的時候,就要使用啟動加載的環(huán)境。這方面的例子包括 U-BOOT,RedBoot,和 Lucent 推出的 MicroMonitor。平臺通常是綁定置,提供了將執(zhí)行它。除了擁了啟動監(jiān)視器的。這些程序位于目標硬件上 flash器的特linux 內核鏡像到 flash器的方法,并在接下來的過有和啟動 linux 鏡像的功能外,這些啟動監(jiān)視器還能進行一定程度上的系統(tǒng)檢測和硬件初始化。在一個的目標板中,這些啟動監(jiān)視器通常覆蓋了第一階段與第boot loader 的功能。/*/小知識:如何查看你的 MBR 內容。如果你希望查看你 MB

7、R 的具體內容,請用以下命令:# dd if=/dev/hda of=mbr.bin bs=512 count=1# od -xa mbr.bin需要以 root運行的 dd 命令,你的第一個集成電子驅動器或者 IDE 驅動器的前 512 字節(jié),并將他們寫入mbr.bim 文件。od 命令則是以十六進制和 ASCII 碼形式打印出這個二進制文件/*/在個人電腦中,linux 的啟動是從 0xFFFF0 地址開始的。BIOS 的第一步動作就是進行上電自檢(POST)。POST 的工作是檢查硬件設備。BIOS 的第二步動作就是枚舉本地設備并初始化。由于 BIOS 功能使用上的不同,它由兩個部分組成

8、:POST 碼 runtime 服務。POST 完成后,它將從服務會被保留,用于目標操作系統(tǒng)。器中被清除,但是 BIOS runtime為了啟動操作系統(tǒng),BIOS 的 runtime 服務將搜索那些激活狀態(tài)的或是可引導啟動的設備,搜索的順序則由 CMOS 設置決定(也就是我們所謂的在 BIOS 中設置的啟動順序)。一個軟驅,一臺光驅,一個硬盤上的分區(qū),網(wǎng)絡上的設備甚至一個 usb 閃存盤都可以作為一個啟動設備。當然,linux 通常是從硬盤啟動的。硬盤上的 MBR(主啟動)包含有基本的 boot loader,它是一個 512 字節(jié)大小的扇區(qū),位于磁盤的第一個扇區(qū)(0 磁頭 0 磁道 1 扇區(qū)

9、)。當 MBR 被裝載到RAM 中后,BIOS 就會將權轉交給MBR。1.3第一階段 boot loaderFigure 2. Anatomy of the MBR位于 MBR 中的主 boot loader 是一個 512 字節(jié)的鏡像,其中不僅包含了程序代碼,還包含了一個小的分區(qū)表,如圖2 所示。最初的446 字節(jié)是主boot loader, 它里面就包含有可執(zhí)行代碼以及錯誤消息文本。接下來的 64 字節(jié)是分區(qū)表,其中包含有四個分區(qū)的各自的(一個分區(qū)占 16 字節(jié))。MBR 通過特殊數(shù)字0xAA55(譯者注:在電子界中 AA55 確實是具有色彩的數(shù)字,想知道為什么么?將它展開成二進制形式,看

10、看有什么規(guī)律)作為兩個字節(jié)的結束標志。0x55AA 同時也是 MBR 有效的校驗確認。主 boot loader 的工作是尋找并加載第二 boot loader。它通過分析分區(qū)表,找出激活分區(qū)來完成這個任務,當它找到一個激活分區(qū)時,它將繼續(xù)掃描剩下的分區(qū)表中的分區(qū),以便確認他們都是未激活的。確認完畢后,激活分區(qū)的啟動記錄從設備中被讀到 RAM,并被執(zhí)行。1.4 第boot loader起著次作用,或者說是第二 boot loader,可以更加形象得被稱為內核加載程序。這個階段的任務就是加載 linux 內核,以及可選的初始化內存盤。/*/小知識:GRUB 階段的 boot loaders在/b

11、oot/grub 目錄中包含有 stage1,stage2 和 stage1.5 的 boot loaders,同時還有不少可選的 loaders(例如,CD-ROM 使用的就是 iso9660_stage_1_5)/*/把第一階段和第的 boot loaders起來,就是在 x86 個人電腦中,我們所說的 linux loader(LILO)或者 GRand Unified Bootloader(GRUB)。由于 GRUB修正了一些 LILO 中存在的缺陷,因此下面就讓我們來看看 GRUB(如果你希望得到的關于 GRUB,LILO 和與之相關話題的討論,請見文后的參考資料)對于 GRUB 來

12、說,一個比較好的方面就是它包含了 linux 文件系統(tǒng)的知識。與 LILO 使用扇區(qū)不同的是,GRUB 能夠從 ext2 或者 ext3 文件系統(tǒng)中加載 linux 內核。它是通過將本來兩階段的 boot loader 轉換成三個階段的 boot loader。在第一階段(MBR)中會啟動 stage1.5 的 boot loader 來理解 linux 內核鏡像中的特殊的文件系統(tǒng)格式,例如,reiserfs_stage1-5(用于從 reiserf 日志文件系統(tǒng)中進行加載)或 e2fs+stage1_5(用于從 wxt2 或 ext3 文件系統(tǒng)進行加載)。當 stage1.5 的boot l

13、oader 被加載并運行時,stage2 的 boot loader 才能被加載。當 stage2 被加載時,GRUB 能根據(jù)請求的情況顯示一個可選內核的(在.lst 和/etc/grub.conf 中進行定義,同時還有幾個軟符號/etc/grub/etc/grub.conf)。你可以選擇一個內核,修改其附加的內核參數(shù)。同時,你可以選擇使用命令行的 shell 來對啟動過程進行更次的手工。在第boot loader 存在與內存中后,就可以對文件系統(tǒng)進行了,同時,默認的內核鏡像以及初始化內存盤鏡像也被加載到內存中。一切準備完畢之后,第的 boot loader 就會調用內核鏡像。1.5 內核(譯

14、者注:在翻譯本章的時候,譯者發(fā)現(xiàn) IBM上已有譯好的文章,因此從本章開始以2 的引導加載程序上的內容為主)。當內核映像被加載到內存中,并且階段權之后,內核階段就開始了。內核映像并不是一個可執(zhí)行的內核,而是一個壓縮過的內核映像。通常它是一個 zImage(壓縮映像, 小于 512KB)或一個 bzImage(較大的壓縮映像,大于 512KB),它是提前使用zlib 進行壓縮過的。在這個內核映像前面是一個例程,它實現(xiàn)少量硬件設置,并對內核映像中包含的內核進行解壓,然后將其放入高端內存中,如果有初始 RAM磁盤映像,就會將它移動到內存中,并標明以后使用。然后該例并開始啟動內核引導的過程。調用內核,當

15、 bzImage(用于 i386 映像)被調用時,我們從 ./arch/i386/boot/head.S的 start 匯編例程開始執(zhí)行(主要流程圖請參看圖 3)。這個例執(zhí)行一些基startup_32 例本的硬件設置,并調用 ./pressed/head.S 中的程。此例( BSS )(在 ./設置一個基本的環(huán)境(堆棧等),并清除 Block Started by Symbol。然后調用 一 個 叫 做press_kernel的C函 數(shù)pressed/misc.c 中)來解壓內核。當內核被解壓到內存中之后,就可以調用它了。這是另外一個 startup_32 函數(shù),但是這個函數(shù)在 ./arch/

16、i386/kernel/head.S 中。在這個新的 startup_32 函數(shù)(也稱為清除程序或進程 0)中,會對頁表進行初始化,并啟用內存分頁功能。然后會為任何可選的浮點單元(FPU)檢測 CPU的類型,并將其起來供以后使用。然后調用 start_kernel 函數(shù)(在 init/main.c中),它會將您帶入與體系結構無關的 Linux 內核部分。實際上,這就是 Linux內核的 main 函數(shù)。/*/小知識:GRUB 中的手工引導在 GRUB 命令行中,我們可以使用 initrd 映像引導一個特定的內核,方法如下:grub> kernel /bzImage-Lin

17、ux-bzImage, setup=0x1400, size=0x29672egrub> initrd /initrd-.imgLinux-initrd 0x5f13000, 0xcc199 bytesgrub> bootpressing Linux. Ok, booting the kernel.如果您不知道要引導的內核的名稱,只需使用斜線(/)然后按下 Tab 鍵即可。GRUB 會顯示內核和 initrd 映像列表。/*/Figure 3. Major functions flow for the Linux kernel i386 boot通過調用 start

18、_kernel,會調用一系列初始化函數(shù)來設置中斷,執(zhí)行進一步的內存配置, 并加載初始 RAM 磁盤。 最后, 要調用 kernel_thread ( 在arch/i386/kernel/process.c 中)來啟動 init 函數(shù), 這是第一個用戶空間進程(user-space process)。最后,啟動空任務,現(xiàn)在調度器就可以接管權了(在調用 cpu_idle 之后)。通過啟用中斷,搶占式的調度器就可以周期性地接管控制權,從而提供多任務處理能力。在內核引導過,初始 RAM 磁盤(initrd)是由階段 2 引導加載程序加載到內存中的,它會被到 RAM 中并掛載到系統(tǒng)上。這個 initrd

19、 會作為RAM 中的臨時根文件系統(tǒng)使用,并內核在沒有掛載任何物理磁盤的情況下完整地實現(xiàn)引導。由于與設備進行交互所需要的模塊可能是 initrd 的一部分,因此內核可以非常小,但是仍然需要支持大量可能的硬件配置。在內核引導之后,就可以正式裝備根文件系統(tǒng)了(通過 pivot_root):此時會將 initrd 根文件系統(tǒng)卸載掉,并掛載真正的根文件系統(tǒng)。initrd 函數(shù)讓我們可以創(chuàng)建一個小型的 Linux 內核,其中包括作為可加載模塊編譯的驅動程序。這些可加載的模塊為內核提供了磁盤和磁盤上的文件系統(tǒng)的方法,并為其他硬件提供了驅動程序。由于根文件系統(tǒng)是磁盤上的一個文件系統(tǒng),因此 initrd 函數(shù)會

20、提供一種啟動方法來獲得對磁盤的,并掛載真正的根文件系統(tǒng)。在一個沒有硬盤的環(huán)境中,initrd 可以是最終的根文件系統(tǒng),或者也可以通過網(wǎng)絡文件系統(tǒng)(NFS)來掛載最終的根文件系統(tǒng)。六、 init 的介紹與結束語當內核被引導并進行初始化之后,內核就可以啟動的第一個用戶空間應用程序了。這是第一個調用的使用標準 C 庫編譯的程序。在此之前,還沒有執(zhí)行任何標準的C 應用程序。在桌面 Linux 系統(tǒng)上,第一個啟動的程序通常是 /sbin/init。但是這不是一定的。很少有系統(tǒng)會需要使用 init 所提供的豐富初始化功能(這是通過/etc/inittab 進行配置的)。在很多情況下,我們可以調用一個簡單的

21、 shell來啟動必需的應用程序。與 Linux 本身非常類似,Linux 的引導過程也非常靈活,可以支持眾多的處理器和硬件平臺。最初,加載引導加載程序提供了一種簡單的方法,不用任何花架子就可以引導 Linux。LILO 引導加載程序對引導能力進行了擴充,但是它卻缺少文件系統(tǒng)的感知能力。最新一代的引導加載程序,例如 GRUB,文件系統(tǒng)(從 Minix 到 Reise)上進行引導。Linux 從一些2.Android 啟動概述2.1 簡介Android 從 Linux 系統(tǒng)啟動有 4 個步驟:(1) init 進程啟動(2) Native 服務啟動(3) System Server,Androi

22、d 服務啟動(4) Home 啟動2.2 啟動流程2.2.1 總體流程圖:2.2.2 分布說明(1)分析 android 的啟動過程,從內核之上,我們首先應該從文件系統(tǒng)的 init 開始,因為 init 是內核進入文件系統(tǒng)后第一個運行的程序,和其他的基于Linux 的系統(tǒng)一樣,bootloader 加載內核以后,啟動 init 進程.,通常我們可以在 linux令行中指定內核第一個調用誰,如果沒指定那么內核將會到/sbin/, /bin/等目錄下查找默認的 init,如果沒有找到那么就報告出錯。(2) init 通過Usbd Adbd Debuggerd Rild語言init.rc 和init

23、.管理 USB 連接管理 ADB 連接管理調試進程請求管理無線通信x.rc啟動core system services:在 init.c 中調用 parse_config_file(Init.rc)來init.rc 文件。在init.rc 文件時用到了兩個列表,一個隊列:static list_declare(service_list); static list_declare(action_list);static list_declare(action_queue);*.rc*.rc中所有 service關鍵字定義的服務將會添加到 service_list 列表中。中所有 on 關鍵開頭的

24、項將會被會添加到 action_list 列表中。每個 action 列表項 action 執(zhí)行一個列表,此列表用來保存該段落下的 Commands。在 init 的 main 函數(shù)中利用如下函數(shù)調用來實現(xiàn) action 的相應命令執(zhí)行。action_for_each_trigger("early-init", action_add_queue_tail);/首先將從 action_list 中取出 act->name為 early-init 的列表項,再調用/action_add_queue_tail(act)將其drain_action_queue();到隊列 a

25、ction_queue 尾部。/從 action_list 隊列中取出隊列項 ,然后執(zhí)行 act->commands action_for_each_trigger("init", action_add_queue_tail); drain_action_queue();action_for_each_trigger("early-boot", action_add_queue_tail); action_for_each_trigger("boot", action_add_queue_tail); drain_action_

26、queue();/* run all property triggers based on current state of the properties */ queue_all_property_triggers();drain_action_queue(); service 執(zhí)行文件中有這樣一行命令class_start default:啟動所有service 關在init.rc鍵字定義的服務。即啟動 classname 為“default”的服務。我們在文件時,所有的服務的 classname 都默認的取的“default”。所以 service_list中的所有服務將會被執(zhí)行。 守護

27、進程/*進入一個無限循環(huán) to wait for device/property set/child processexit events.例如, 如果 SD 卡入,init 會收到一個設備,它會為這個設備創(chuàng)建節(jié)點。系統(tǒng)中比較重要的進程都是由 init 來 fork 的,所以如果他們誰了,那么 init 將會收到一個 SIGCHLD 信號,把這個信號轉化為子進, 所以在 loop 中,init 會操作進程并且執(zhí)行 *.rc 文件程中定義令。for(;) /*在 for 循環(huán)中會重復調用drain_action_queue(); restart_processes();/* static voi

28、d restart_processes()process_needs_restart = 0; service_for_each_flags(SVC_RESTARTING,restart_service_if_needed);*/通過循環(huán)檢測服務列表 service_list 中每個服務的 svc->flags 標記,如果為SVC_RESTARTING , 那 么 在 滿 足 條 件 的 情 況 下 調 用 : restart_service_if_needed 通過 service_start 來再次啟動該服務。這就是init 守護進程。*/(3) zygote 進程運行 建立 JAV

29、A runtime:創(chuàng)建 JAVA 虛擬機為 JAVA 虛擬機lllandroid 本地函數(shù)第一個 JAVA 類, 是 AndroidRuntime: start 時傳遞進去的參數(shù)ernal.os.ZygoteInit 類中的 main 函數(shù)流程圖如下: 完成zygote進程的自身功能llregisterZygoteSocket();/登記Listen 端口startSystemServer();zygoteinit.main()通過調用 startSystemServer()函數(shù)來完成一次,出來的子進程繼續(xù)初始化 Java 層框架。這個出來的進程就是 syste

30、m_server。進入 Zygote 服務框架。l出上述子進程后,父進程即 zygote 進程返回并進入孵化器狀態(tài),所有的 Android Java 應用程序都通過這個孵化器進程由 Linux 的 fork 機制產(chǎn)生一個新的進程。,回到開始的system_server 完成的地方,接下來的代碼,在 ZygoteInit.java 中:展開了這一過程,在正常情況下使用的是 runSelectLoopMode。runSelectLoopMode 通過system_server 通過 socket由子進程執(zhí)行對應應用的socket 與外界, 需要執(zhí)行新應用時,孵化命令給 zygote,由 zygot

31、e 完成自身,再Java 函數(shù),即可完成應用程序的啟動。這和 Linux啟動新程序的系統(tǒng)調用(先 fork,然后 exec)是一致的,只不過 exec 換成了調用 Java 應用程序的ZygoteConnection.java 中。函數(shù)。 相關的處理流程在 ZygoteInit.java 和Android 使用這樣的方式創(chuàng)建新應用,是非常始化好了每個進程唯一的 Java 虛擬機的開銷。的。Zygote 孵化器已經(jīng)初System_server 加 zygote 孵化器,至此奠定了整個 Android 的 Java 框架運行的基礎。if (ZYGOTE_FORK_MODE) runForkMode

32、(); else runSelectLoopMode();(4)systemServer 進程.ernal.os.ZygoteInit 在Zygote 上fork 了一個進sta程:com.android.server.SystemServer.于是 SystemServer(SystemServer.java)就建立了。 Init1Init1()是在Native 空間實現(xiàn)的(com_andoird_server_systemServer.cpp)。我們一看這個函數(shù)就知道了,init1->system_init() System_init.cpp。l在system_

33、init()中首先start SurfaceFlinger,通過SurfaceFlinger:instantiate()來啟動surfaceFlinger service。啟動下列服務:AudioFlinger,MediaPlayerService,CameraService,AudioPolicyServicel并完成服務的:void SurfaceFlinger:instantiate() defaultServiceManager()->addService(String16("SurfaceFlinger"), new SurfaceFlinger();使用

34、c/c+撰寫的 Android 的底層系統(tǒng)服務(system service)模組時,經(jīng)常需要使用到 ServiceManager 的服務。如上,它使用了 defaultServiceManager()函數(shù)來取得 ServiceManager 模組,然后呼叫其 IServiceManager 里面的 addService()函數(shù)來將 錄到 Binder模組)。物件(SurfaceFlinger 的物件)傳給 ServiceManager 模組,請它登Kernel 里,成為一個可提供遠距離服務的模組(即 ServiceManagerSystemServer.javal調用(frameworksb

35、aseservicesjavacomandroidserver)中的init2函數(shù),完成Android服務,Android Service都運行在一個進:systemsever進程。進入SystemServer循環(huán)閉合管理框架,l關于循環(huán)閉合管理框架: Service 本質結構我們還是從Service 的根本意義分析入手,服務的本質就是響應客戶端請求。要提供服務,就必須建立接收請求,處理請求,應答端的框架在Android Service 設計者也會無時不刻把這個服務本質框圖掛在腦海中。從程序的角度,服務一定要存在一個閉合循環(huán)框架和請求處理框架。Android 設計中,Native Servic

36、e 和Android Service 采用了同一個閉合循環(huán)框架。這個閉合循環(huán)框架放置在Native 的C+ 空間中,,ProcessStateProcessState.cpp和IPCThreadStateIPCThreadState.cpp 兩個類完成了全部工作。Native ServiceNative Service 是在系統(tǒng)Init 階段通過Init.rc建立的服務。首先來看看一個例子mediaservermain_mediaserver.cpp 的建立過程。代碼向下展開了一層,更能看到事物的本質。int main(int argc, char* argv)sp<ProcessSta

37、te> proc(ProcessState:self(); sp<IServiceManager> sm = defaultServiceManager();defaultServiceManager()->addService(String16("media.audio_flinger"), new AudioFlinger();ProcessState:self()->startThreadPool(); IPCThreadState:self()->joinThreadPool();(1) 服務進程建立了ProcessState 對

38、象,并將給對象登記在進程的上下文中。(2) 建立一個新AudioFlinger 對象,并將對象登記Service Manager Service 中。(3) 開始就收請求,處理請求,應答這個循環(huán)閉合框架。Android ServiceAndroids service 是系統(tǒng)(Init2)初始化時建立的服務。Android 的所有服務循環(huán)框架都是建立SystemServer(SystemServer.java ) 上。在SystemServer.java 中看不到循環(huán)結構,只是可以看到建立了init2 的實現(xiàn)函數(shù),建立了一大堆服務,并AddService 到service Manager。在sy

39、stem_init()我們看到了循環(huán)閉合管理框架Call "com/android/server/SystemServer", "init2".ProcessState:self()->startThreadPool();IPCThreadState:self()->joinThreadPool();/循環(huán)閉合管理框架在這主線:層次圖如下: Init2在system_init()函數(shù)中調用init2。init2()SystemServer.java 中建立了Android中所有要用到的服務,這個 init2()建立了一個線程,來 NewSer

40、vice 和 AddService來建立服務。在 ServerThread 類的 run 服務中開啟Power Manager:服務并。比如啟動power = new PowerManagerService(); ServiceManager.addService(Context.POWER_SERVICE, power);即 是 呼 叫 ServiceManager類 的 addService() 函 數(shù) , 將( 就 是PowerManagerService)登錄到 Binder Kernel 里,成為一個可提供遠距離服務服務在此過啟動如下圖:(5) home 的啟動Home 是 Andr

41、oid 設備開啟后第一個與用戶交互的應用程序。在其他應用程序運行于前臺時,Home 也將一直運行于返回到 Home 的用戶界面以供用戶進行啟動的程序。當其他應用程序都時,又要操作,如在應用程序列表中選擇要在 ServerThreadSystemServer.java 后半段,我們可以看到系統(tǒng)在啟動有的 Android 服務后,做了這樣一些動作:(1)使用.systemReady()通知各個服務,系統(tǒng)已經(jīng)就緒。(2)特別對于 ActivityManagerService.systemReady 通知。Home 就是在 ActivityManagerService.systemReady()通知的

42、過ActivityManagerService.systemReady()的偽代碼:systemReady()ActivityManagerService.java建立的。下面是startHomeActivityLocked();/如果是第一個則啟動 HomeActivity。startActivityLocked(。)CATEGORY_HOME。在 systemReady 后開始啟動 Launcher。在尋找 Launcher 的時候是根據(jù) HOME 的 filter(在 Manifest 中定義的<category android:name="ent.

43、category.HOME" />)來過濾。然后根據(jù) filter 出來的 HOME 來啟動,如果只有一個 HOME,則啟動這個HOME,如果用戶裝了 HOME,那就會彈出來一個列表供用戶選擇。的模組(即 PowerManagerService 模組)。Java 指令:ServiceManager.addService(.);相當于 C+的指令:defaultServiceManager()->addService(.);3.Android 啟動過程詳述總體框架圖:3.1 init 進程init 進程,它是一個由內核啟動的用戶級進程。內核自行啟動(已經(jīng)被載入內存,開始運行

44、,并已初始化所有的設備驅動程序和數(shù)據(jù)結構等)之后,就通過啟動一個用戶級程序 init 的方式,完成引導進程。init 始終是第一個進程. Init.rcInit.marvell.rcInit 進程一起來就根據(jù) init.rc 和 init. servicemanamgerzygote。文件建立了幾個基本的服務:.rc文件3.1.1initSystem/Core/InitInit.c: parse_config_file(Init.rc) parse_config_file(Init.marvel.rc)文件:Init.rc 和 Init.x.rc(硬件平臺相關)Init.rc是 Android

45、System/Core/Init/readme.txt)規(guī) 定 的 初 始 化(AndroidInitLanguage,3.1.2 服務啟制我們來看看 Init 是這樣.rc 文件開啟服務的。(1)打開.rc 文件,文件內容 systemcoreinitinit.c將 service 信息放置到 service_list 中。 systemcoreinit parser.c(2)在文件 init.rcclass_start default中有以下一個命令:啟動所有 service 關鍵字定義的服務。class_startclass_start在 act->name為 boot的 act-

46、>commands 列表中,所以當被觸發(fā)后,實際上調用的是函數(shù) do_class_start()int do_class_start(int nargs, char *args)/* Starting a class does not start services* which are explicitly disabled. They must* be started individually.*/service_for_each_class(args1, service_start_if_not_disabled); return 0;void service_for_each_cl

47、ass(const char *classname,void (*func)(struct service *svc)struct listnode *node; struct service *svc;list_for_each(node, &service_list) svc = node_to_item(node, struct service, slist); if (!strcmp(svc->classname, classname) func(svc);因 為 在 調 用 parse_service() 添 加 服 務 列 表 的 時 候 , 所 有 服 務svc-&

48、gt;classname 默認取值:"default",所以 service_list 中的所有服務將會被執(zhí)行。3.1.3 源代碼分析int main(int argc, char *argv)./安裝 SIGCHLD 信號。(如果父進程不等待子進程結束,子進程將成為僵尸進程(zombie)從而占用系統(tǒng) 。因此需要對 SIGCHLD 信號做出處理,回收僵尸 進 程 的 ,避免造成不必要的 浪費。/這個系統(tǒng)調用函數(shù)是將某個信號與 sigaction 結構體進行綁定,也就是說指定這 個信號的處理過程。傳入的參數(shù)有三個:信號值 signum、新的 sigaction、存放原來 s

49、igaction 的 sigaction 結構體 oldaction。的大體過程是這樣的:1) 取出信號的原 sigaction 結構體,放到 oldaction 中。2) 為該信號綁定新的sigaction:將新sigaction到task_struct 的sigation 數(shù)組的 signum-1 處。3) 設置碼:根據(jù)sigaction 中信號選項標志sa_flags 設置sa_mask。sigaction(SIGCHLD, &act, 0);/當我們登錄系統(tǒng)之后創(chuàng)建一個文件總是有一個默認權限的,那么這個權限是怎 的呢?這就是 umask 干的事情。umask 設置了用戶創(chuàng)建文件

50、的默認權限,它與 chmod 的效果剛好相反,umask 設置的是權限“補碼”,而 chmod 設置的是文件權限碼。一般在/etc/profile、$ HOME/.bash_profile 或$HOME/.profile 中設置umask 值。umask(0);/為 rootfs 建立必要的文件夾,并掛載適當?shù)姆謪^(qū)。 /dev (tmpfs) /dev/pts (devpts) /dev/socket /proc (proc)mkdir("/dev", 0755);mkdir("/proc", 0755);mkdir("/sys", 0755);mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755"); mkdir("/dev/pts", 0755);mkdir("/dev/socket", 0755);mount(&quo

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論