[TOC]
Android 簡介
Android 操作系統(tǒng)是基于Linux內(nèi)核, Google使用Linux內(nèi)核構(gòu)建了一個可移植和健壯的手機平臺,而并沒有使用傳統(tǒng)Linux的任何其他的東西. Android并不完全依賴于Linux內(nèi)核, 但是Android底層的開發(fā)和傳統(tǒng)的嵌入式Linux系統(tǒng)開發(fā)關(guān)系非常密切, Android系統(tǒng)的驅(qū)動與Linux的驅(qū)動在開發(fā)上幾乎保持了完全一致, 另外,Android底層開發(fā)和移植的環(huán)境也與嵌入式Linux的環(huán)境保持了基本一致.
Android是Google于2007年宣布的基于Linux平臺的開源手機操作系統(tǒng). Android是一個包括操作系統(tǒng), 中間件, 用戶界面,和關(guān)鍵應(yīng)用的移動設(shè)備軟件堆. 換句話說就是Android是基于Java并運行在Linux內(nèi)核上的輕量級操作系統(tǒng).
Android 移植
Android 移植分為兩個部分: 應(yīng)用移植和系統(tǒng)移植.
-
應(yīng)用移植:
- 為保證應(yīng)用程序能在新的平臺上正常運行,需要對源代碼就行一些修改,因為硬件平臺之間以及Android SDK API之前都可能存在差異。如果無法獲取應(yīng)用程序的源代碼,只能重新在新的硬件平臺上實現(xiàn);
- Android應(yīng)用移植不涉及驅(qū)動和HAL程序庫(注:HAL程序庫是Android新增加的硬件抽象層);
-
系統(tǒng)移植:
使操作系統(tǒng)在特定硬件平臺上運行的條件:
- 操作系統(tǒng)支持硬件平臺上的CPU架構(gòu)。Linux內(nèi)核本身支持很多常用的CPU架構(gòu),如ARM,X86,PowerPC,因此不需要做過多的改動,但不代表不做改動;
- 識別硬件平臺上的各種硬件。這些工作主要也是由Linux內(nèi)核完成的,主角是Linux驅(qū)動。
HAL
- 位于第二層,也是普通的Linux程序庫(.so文件),Android SDK通過HAL之間訪問Linux驅(qū)動(一般的Linux系統(tǒng)都是由應(yīng)用程序直接訪問驅(qū)動)。
總結(jié):
- Android移植的主要工作:移植Linux驅(qū)動和移植HAL;
- Android驅(qū)動與Linux驅(qū)動的區(qū)別就是Android增加了HAL,一般的Android驅(qū)動會有對應(yīng)的HAL,但也不是必須的, 通過NDK也可以直接訪問Linux驅(qū)動(Android O還可以嗎?).
- Android 并不能夠使用從www.kernel.org下載的Linux內(nèi)核,必須使用Google提供的網(wǎng)址下載可以供Android使用的Linux內(nèi)核源代碼;
- Android移植的基本原則是盡可能找到驅(qū)動和HAL的源代碼,在源代碼的基礎(chǔ)上改比從頭開始編寫容易得多,實在無法獲取源代碼,就只能從頭開始做起了;
- Android移植很大程度上是Linux內(nèi)核移植,Linux內(nèi)核移植主要是移植驅(qū)動程序。不同Linux版本的驅(qū)動程序不能通用,需要修改源代碼,并在新的Linux內(nèi)核下重新編譯才可以運行在新的Linux內(nèi)核版本下。
Android 系統(tǒng)架構(gòu)
Android O 之前的系統(tǒng)劃分
Android從高層到低層分別是應(yīng)用程序?qū)?、?yīng)用程序框架層、系統(tǒng)運行庫層和linux核心層。Linux內(nèi)核和應(yīng)用程序框架層之間的HAL層主要是對linux內(nèi)核驅(qū)動的封裝,將硬件抽象化,屏蔽掉了底層的實現(xiàn)細節(jié)。HAL規(guī)定了一套應(yīng)用層對硬件層讀寫和配置的統(tǒng)一接口,本質(zhì)上就是將硬件的驅(qū)動分為用戶空間和內(nèi)核空間兩個層面;Linux內(nèi)核驅(qū)動程序運行于內(nèi)核空間,硬件抽象層運行于用戶空間。
Android 并不是Linux
- 它沒有本地窗口系統(tǒng)
- 它沒有g(shù)libc支持
- 它并不包括一整套標(biāo)準(zhǔn)的Linux使用程序
- Android專有的驅(qū)動程序
Linux內(nèi)核層
包括驅(qū)動程序以及管理內(nèi)存、進程、電源等資源的程序,因為Android是基于Linux內(nèi)核的,所以Android和其他Linux系統(tǒng)的核心部分的差異很?。徊煌姹镜腁ndroid使用的Linux內(nèi)核版本有差異,所以不同Android版本的驅(qū)動程序可能不通用;
c/c++代碼庫
包括使用C/C++編寫的代碼庫(Linux下的.so文件使用C/C++編寫的),以及嵌入到APK程序中的NDK代碼,也包括Dailvk虛擬機的
運行時(Runtime);
Dailvk虛擬機是Google公司設(shè)計的基于Android平臺的虛擬機,它可以支持已轉(zhuǎn)換為 .dex(即Dalvik Executable)格式的Java應(yīng)用程序的運行;這些庫能被Android系統(tǒng)中不同的組件使用,通過Android應(yīng)用程序為開發(fā)者提供服務(wù);
一些核心庫:
- 系統(tǒng)C庫:一個從BSD繼承來的標(biāo)準(zhǔn)C系統(tǒng)函數(shù)庫(libc),是專門為基于embedded linux的設(shè)備定制的;
- 媒體庫:基于PacketVideo OpenCORE,支持多種常用的音頻、視頻格式回放和錄制,同時支持靜態(tài)圖像文件。編碼格式包括MPEG4,H.264,MP3,AAC,AMR,JPG,PNG;
- Surface Manager:對顯示子系統(tǒng)的管理,并且為多個應(yīng)用程序提供了2D和3D圖層的無縫融合
- LibWebCore:最新的web瀏覽器引擎,支持Android瀏覽器和一個可嵌入的web視圖;
- SGL:底層的2D圖形引擎;
- 3D Libraries:基于OpenGL ES 1.0 APIs實現(xiàn),該庫可以使用硬件3D加速(如果可用)或者使用高度優(yōu)化的3D軟加速;
- FreeType:位圖和矢量字體顯示;
- SQLite:一個對于所有應(yīng)用程序可用,功能強勁的輕型關(guān)系數(shù)據(jù)庫引擎;
Android運行庫:
Android包括了一個核心庫,該核心庫提供了Java編程語言核心庫的大多數(shù)功能。每一個Android應(yīng)用程序都在自己的進程中運行,都擁有一個獨立的Dalvik虛擬機實例,Dalvik被設(shè)計成一個設(shè)備可以同時高效地運行多個虛擬系統(tǒng)。Dalvik虛擬機執(zhí)行.dex的Dalvik可執(zhí)行文件,該格式文件針對小內(nèi)存使用做了優(yōu)化。同時虛擬機是基于寄存器的,所有的類都經(jīng)由Java編譯器編譯,然后通過SDK中的dx工具轉(zhuǎn)化成.dex格式由虛擬機執(zhí)行;
Android SDK API
直接面向應(yīng)用程序的Java APK. 這一層可以成為Java API層,因為Android SDk API是用Java語言編寫的。實際上這一層就是用Java編寫的各種Library,只不過這些library是基于Dalvik虛擬機格式的。
應(yīng)用程序
這一層是所有的Android用戶都要接觸到的,因為這一層相當(dāng)于Android的UI。所有的Android應(yīng)用程序(包括拍照,電話,短信,Android的桌面,瀏覽器以及各種游戲)都屬于這一層。主要依靠第三層中的Android SDK API來完成各種功能。
Android 啟動流程
當(dāng)你按下電源開關(guān)后Android設(shè)備執(zhí)行了以下步驟:
Android 系統(tǒng)運行所需要的三大部件: bootloader,kernel , ramdisk.
- bootloader: 作為引導(dǎo)系統(tǒng),引導(dǎo)linux內(nèi)核的加載.如uboot
- kernel: Linux內(nèi)核
- Ramdisk : 文件系統(tǒng)
移植前的準(zhǔn)備
目標(biāo)硬件平臺: 樹莓派 ARM-V9 四核
開發(fā)環(huán)境: ubuntu 17.04-64 位
編譯器 :
Android 源碼: Android 8.0
嵌入式交叉編譯環(huán)境的搭建
? 交叉編譯環(huán)境的搭建是Android移植的第一步,不同的體系結(jié)構(gòu),不同的操作內(nèi)容甚至是不同版本的內(nèi)核,都會用到不同的交叉編譯器. gcc用來生成交叉編譯器,主要生成arm-linux-gcc交叉編譯工具, 之后用此交叉編譯來編譯Linux內(nèi)核. 我們通常使用網(wǎng)上已有的交叉編譯器而不是自己生成, 廣泛使用的是crosstool的交叉編譯工具鏈.可以在crosstool的docs中查看使用說明.
準(zhǔn)備三大部件.
- Bootloader模塊: 燒寫U-boot到開發(fā)板
- Kernel模塊: 燒寫Linux內(nèi)核鏡像到開發(fā)板
- Ramdisk模塊: 燒寫文件系統(tǒng)鏡像到開發(fā)板
U-Boot鏡像的下載與燒寫
1. 簡介
? bootloader是系統(tǒng)上電后最初加載運行的代碼。它提供了處理器上電復(fù)位后最開始需要執(zhí)行的初始化代碼。通過這一小段程序,我們可以初始化硬件設(shè)備、建立內(nèi)存空間的映射表,從而建立適當(dāng)?shù)南到y(tǒng)軟硬件環(huán)境,為最終調(diào)用操作系統(tǒng)內(nèi)核做好準(zhǔn)備。在PC機上引導(dǎo)程序一般由BIOS開始執(zhí)行,BIOS完成硬件檢測和資源分配之后,將位于硬盤MBR(Main Boot Record,主引導(dǎo)記錄)中的OS Bootloader(例如LILO或GRUB)讀到系統(tǒng)的RAM當(dāng)中,然后將控制權(quán)交給OS Bootloader,并進一步引導(dǎo)操作系統(tǒng)的啟動,主要完成的工作是將內(nèi)核印象從硬盤上讀到RAM當(dāng)中, 然后跳轉(zhuǎn)到內(nèi)核的入口點去執(zhí)行, 即開始啟動操作系統(tǒng)。然而在嵌入式系統(tǒng)中通常沒有像BIOS那樣的固件程序,因此整個系統(tǒng)的加載啟動就完全由bootloader來完成。
? 比如在一個基于ARM7TDMI core的嵌入式系統(tǒng)中,系統(tǒng)在上電或復(fù)位時通常都從地址0x00000000處開始執(zhí)行,而在這個地址處安排的通常就是系統(tǒng)的Boot Loader程序。(先想一下,通用PC和嵌入式系統(tǒng)為何會在此處存在如此的差異呢?)
? Bootloader進行所謂的“kernel引導(dǎo)”,其過程不過是從bootloader里的一句跳轉(zhuǎn)代碼,跳轉(zhuǎn)到kernel代碼處(執(zhí)行kernel中的第一個函數(shù)),所謂傳遞參數(shù)也不過是bootloader和kernel約定一個內(nèi)存地點存放。在這個過程中,bootloader和kernel雖然都處于同一個內(nèi)存里,但是它們除了“引導(dǎo)”與“傳遞有限的參數(shù)”這樣的關(guān)系,并無其它關(guān)系,完全是兩個獨立的程序。之所以在kernel之前用一個bootloader來引導(dǎo)(為什么開機不能直接執(zhí)行kernel,所有事情都交給kernel做?),其思想類似于一個板級支持包:kernel假定執(zhí)行的時候已經(jīng)具備了一個基本的硬件運行條件,這個環(huán)境的初始化(最底層的一些硬件初始化、硬件信息設(shè)定)需要bootloader來完成,也許這樣kernel的設(shè)計才能保持一定的一致性。
? Bootloader是基于特定硬件平臺來實現(xiàn)的,因此幾乎不可能為所有的嵌入式系統(tǒng)建立一個通用的Bootloader,不同的處理器架構(gòu)都有不同的Bootloader,Bootloader不但依賴于cpu的體系結(jié)構(gòu),還依賴于嵌入式系統(tǒng)板級設(shè)備的配置。對于2塊不同的板子而言,即使他們使用的是相同的處理器,要想讓運行在一塊板子上的Bootloader程序也能運行在另一塊板子上,一般也需要修改Bootloader的源程序。
? U-Boot,全稱 Universal Boot Loader,是遵循GPL條款的開放源碼項目。U-Boot的作用是系統(tǒng)引導(dǎo)。U-Boot不僅僅支持嵌入式Linux系統(tǒng)的引導(dǎo),它還支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS, android嵌入式操作系統(tǒng)。U-Boot除了支持PowerPC系列的處理器外,還能支持MIPS、 x86、ARM、NIOS、XScale等諸多常用系列的處理器。
? 一個嵌入式的存儲設(shè)備通常包括四個分區(qū):
存放bootloader(通常是U-boot).
存放bootloader要傳遞給系統(tǒng)內(nèi)核的參數(shù).
系統(tǒng)內(nèi)核
-
根文件系統(tǒng)
U-boot目錄結(jié)構(gòu)
- board 目標(biāo)板相關(guān)文件,主要包含SDRAM、FLASH驅(qū)動;
- common 獨立于處理器體系結(jié)構(gòu)的通用代碼,如內(nèi)存大小探測與故障檢測;
- cpu 與處理器相關(guān)的文件。如mpc8xx子目錄下含串口、網(wǎng)口、LCD驅(qū)動及中斷初始化等文件;
- driver 通用設(shè)備驅(qū)動,如CFI FLASH驅(qū)動(目前對INTEL FLASH支持較好)
- doc U-Boot的說明文檔;
- examples可在U-Boot下運行的示例程序;如hello_world.c,timer.c;
- include U-Boot頭文件;尤其configs子目錄下與目標(biāo)板相關(guān)的配置頭文件是移植過程中經(jīng)常要修改的文件;
- lib_xxx 處理器體系相關(guān)的文件,如lib_ppc, lib_arm目錄分別包含與PowerPC、ARM體系結(jié)構(gòu)相關(guān)的文件;
- net 與網(wǎng)絡(luò)功能相關(guān)的文件目錄,如bootp,nfs,tftp;
- post 上電自檢文件目錄。尚有待于進一步完善;
- rtc RTC驅(qū)動程序;
- tools 用于創(chuàng)建U-Boot S-RECORD和BIN鏡像文件的工具;
工作模式
? U-boot的3種映像格式(U-Boot , U-Boot.srec , U-Boot.bin)都可以燒寫到Flash中, 但是需要看加載器是否能夠識別這些格式. 最常使用的是U-Boot.bin格式, U-Boot的工作模式有啟動加載模式和下載模式。
- 啟動加載模式(Flash 啟動方式): Bootloader的正常工作模式,嵌入式產(chǎn)品發(fā)布時,Bootloader必須工作在這種模式下,Bootloader將嵌入式操作系統(tǒng)從FLASH中加載到SDRAM中運行,整個過程是自動的。Flash有NOR Flash和NAND Flash兩種。NOR Flash可以支持隨機訪問,所以代碼可以直接在Flash上執(zhí)行,Bootloader一般是存儲在Flash芯片上的。另外Flash上還存儲著參數(shù)、內(nèi)核映像和文件系統(tǒng)。這種啟動方式與網(wǎng)絡(luò)啟動方式之間的不同之處就在于,在網(wǎng)絡(luò)啟動方式中,內(nèi)核映像和文件系統(tǒng)首先是放在主機上的,然后經(jīng)過網(wǎng)絡(luò)傳輸下載進目標(biāo)板的,而這種啟動方式中內(nèi)核映像和文件系統(tǒng)則直接是放在Flash中的,這兩點在我們u-boot的使用過程中都用到了。
- 下載模式(網(wǎng)絡(luò)啟動方式): Bootloader通過某些通信手段將內(nèi)核映像或根文件系統(tǒng)映像等從PC機中下載到目標(biāo)板的FLASH中。用戶可以利用Bootloader提供的一些命令接口來完成自己想要的操作。
啟動流程
? 大多數(shù)BootLoader都分為stage1和stage2兩大部分,U-boot也不例外。依賴于cpu體系結(jié)構(gòu)的代碼(如設(shè)備初始化代碼等) 通常都放在stage1且可以用匯編語言來實現(xiàn),而stage2則通常用C語言來實現(xiàn),這樣可以實現(xiàn)復(fù)雜的功能,而且有更好的可讀性和移植性。
-
stage1(start.s代碼結(jié)構(gòu))
U-boot的stage1代碼通常放在start.s文件中,它用匯編語言寫成,其主要代碼部分如下:
定義入口
_start
。由于一個可執(zhí)行的image必須有一個入口點,并且只能有一個全局入口,通常這個入口放在rom(Flash)的0x0地址,因此,必須通知編譯器以使其知道這個入口,該工作可通過修改連接器腳本來完成。-
設(shè)置異常向量(exception vector)。這樣在CPU發(fā)生異常的時候就跳轉(zhuǎn)到/cpu/xxxx/interrupts中去執(zhí)行相應(yīng)的中斷代碼. 在interrupts文件中大部分的異常代碼都沒有實現(xiàn)具體的功能,只是打印一些異常消息,其中關(guān)鍵的是reset中斷代碼,跳到reset入口地址。
reset復(fù)位入口之前有一些段的聲明。
- 在reset中,首先是將cpu設(shè)置為svc32模式下,并屏蔽所有irq和fiq。
- 在u-boot中除了定時器使用了中斷外,其他的基本上都不需要使用中斷,比如串口通信和網(wǎng)絡(luò)等通信等,在u-boot中只要完成一些簡單的通信就可以了,所以在這里屏蔽掉了所有的中斷響應(yīng)。
- 初始化外部總線。這部分首先設(shè)置了I/O口功能,包括串口、網(wǎng)絡(luò)接口等的設(shè)置,其他I/O口都設(shè)置為GPIO。然后設(shè)置BCFG0~BCFG3,即外部總線控制器。這里bank0對應(yīng)Flash,設(shè)置為16位寬度,總線速度設(shè)為最慢,以實現(xiàn)穩(wěn)定的操作;Bank1對應(yīng)DRAM,設(shè)置和Flash相同;Bank2對應(yīng)RTL8019。
設(shè)置CPU的速度、時鐘頻率、系統(tǒng)重映射(告訴處理器在系統(tǒng)發(fā)生中斷的時候到外部存儲器中去讀取中斷向量表)及中斷控制寄存器。
初始化內(nèi)存控制器 。
將rom中的程序復(fù)制到ram中。通常把stage2加載到RAM空間中來執(zhí)行,因此必須為加載Boot Loader的stage2準(zhǔn)備好一段可用的RAM空間范圍??臻g大小最好是memory page大小(通常是4KB)的倍數(shù). 一般而言,1M的RAM空間已經(jīng)足夠了。flash中存儲的u-boot可執(zhí)行文件中,代碼段、數(shù)據(jù)段以及BSS段都是首尾相連存儲的, 所以在計算搬移大小的時候就是利用了用BSS段的首地址減去代碼的首地址,這樣算出來的就是實際使用的空間。程序用一個循環(huán)將代碼搬移到0x81180000,即RAM底端1M空間用來存儲代碼。然后程序繼續(xù)將中斷向量表搬到RAM的頂端。由于stage2通常是C語言執(zhí)行代碼,所以還要建立堆棧區(qū)。
初始化堆棧 。在堆棧區(qū)之前還要將malloc分配的空間以及全局數(shù)據(jù)所需的空間空下來,他們的大小是由宏定義給出的,可以在相應(yīng)位置修改。
轉(zhuǎn)到ram中執(zhí)行,該工作可使用指令ldrpc來完成。
-
stage2(C語言代碼部分)
? 這個部分是相對變化不大的部分, 我們針對不同的板子改變它調(diào)用的一些初始化函數(shù),并且通過設(shè)置一些宏定義來改變初始化的流程,所以這些代碼在移植的過程中并不需要修改,也是錯誤相對較少出現(xiàn)的文件。在文件的開始先是定義了一個函數(shù)指針數(shù)組,通過這個數(shù)組,程序通過一個循環(huán)來按順序進行常規(guī)的初始化,并在其后通過一些宏定義來初始化一些特定的設(shè)備。在最后程序進入一個循環(huán),main_loop。這個循環(huán)接收用戶輸入的命令,以設(shè)置參數(shù)或者進行啟動引導(dǎo)。
?lib_arm/board.c中的start armboot是C語言開始的函數(shù),也是整個啟動代碼中C語言的主函數(shù),同時還是整個u-boot(armboot)的主函數(shù),該函數(shù)主要完成如下操作:
- 調(diào)用一系列的初始化函數(shù)。
- 初始化flash設(shè)備。
- 檢測系統(tǒng)內(nèi)存映射,初始化系統(tǒng)內(nèi)存分配函數(shù)。
- 如果目標(biāo)系統(tǒng)擁有nand設(shè)備,則初始化nand設(shè)備。
- 如果目標(biāo)系統(tǒng)有顯示設(shè)備,則初始化該類設(shè)備。
- 初始化相關(guān)網(wǎng)絡(luò)設(shè)備,填寫ip,c地址等。
- 將內(nèi)核從Flash讀取到RAM中并為內(nèi)核設(shè)置啟動參數(shù).
- 進入命令循環(huán)(即整個boot的工作循環(huán)),接受用戶從串口輸入的命令,然后進行相應(yīng)的工作。
U-boot上電啟動之后,可以按任意鍵退出自動啟動狀態(tài),進入命令行模式.[圖片上傳失敗...(image-c0b0df-1517988532965)]
在命令行模式下可以執(zhí)行U-Boot的命令并執(zhí)行. U-Boot可以支持幾十個常用的命令,通過這些命令,可以對開發(fā)版進行調(diào)試,可以引導(dǎo)Linux內(nèi)核, 還可以擦寫Flash完成系統(tǒng)部署等功能. 掌握這些命令才能順利的進行嵌入式系統(tǒng)的開發(fā). 輸入help可以得到當(dāng)前U-Boot的所有命令列表.
編譯Android 源碼
Android源碼目錄結(jié)構(gòu)
以下的Android 源碼目錄結(jié)構(gòu)相關(guān)的內(nèi)容來自mr_raptor的CSND博客,Android編譯的相關(guān)內(nèi)容也可以查看其博客.
在Android源碼中,按照不同功能代碼被放在不同的目錄下:
目錄 | 描述 |
---|---|
bionic | 針對Android系統(tǒng)定制的仿生標(biāo)準(zhǔn)C庫、鏈接器等所在目錄,Android系統(tǒng)并沒有使用Linux的glibc庫,bioinc C庫針對嵌入式系統(tǒng)做了優(yōu)化,添加了一些Android特定的函數(shù)API同時大大減少庫的體積,也避免了LGPL版權(quán)的問題。 |
bootable | Android系統(tǒng)引導(dǎo)啟動代碼,用來引導(dǎo)系統(tǒng)、更新系統(tǒng)、恢復(fù)系統(tǒng)。 |
build | Android的編譯系統(tǒng)目錄,里面包含大量的Makefile,用來編譯目標(biāo)系統(tǒng)、Host主機開發(fā)環(huán)境等。 |
cts | 兼容性測試工具目錄。 |
dalvik | Dalvik虛擬機,Android系統(tǒng)得以運行的虛擬執(zhí)行環(huán)境。 |
development | 程序開發(fā)所需要的模板和工具。 |
external | Android系統(tǒng)使用的其它開源代碼目錄,如jpeg圖片解碼開源庫、opencore開源代碼等。 |
frameworks | 框架層代碼,frameworks/base目錄下存放目標(biāo)系統(tǒng)的框架庫,frameworks/policies/base下存放應(yīng)用程序框架代碼。 |
hardware | HAL(Hardware Abstraction Layer)硬件抽象層代碼。 |
kernel | Linux內(nèi)核目錄,默認下載的Android源碼里沒有,需單獨下載。 |
packages | Android系統(tǒng)級應(yīng)用程序源碼目錄,如攝像應(yīng)用、電話應(yīng)用等。 |
prebuilt | 主機編譯工具目錄,如arm-linux-gcc交叉系統(tǒng)工具鏈等。 |
sdk | SDK及模擬器。 |
system | init進程、藍牙、無線WIFI工具、uevent進程目錄。 |
devices | 廠商設(shè)備配置目錄,針對不同設(shè)備,由不同的子目錄來分別管理,用來裁剪實現(xiàn)不同設(shè)備上Android目標(biāo)系統(tǒng)。 |
Android 編譯后的out目錄分析
Android編譯完成后,將在根目錄中生成一個out文件夾,所有生成的內(nèi)容均放置在這個文件夾中。
主要的兩個目錄是host和target, 前者表示在主機(x86)生成的工具,host目錄是一些在主機上用的工具,有一些是二進制程序,有一些是JAVA的程序。后者表示目標(biāo)機(模認為ARMv5)運行的內(nèi)容。target中中common目錄表示通用的內(nèi)容,product中則是針對產(chǎn)品的內(nèi)容。