當前位置: 首頁 > 安卓培訓 > Android開發 > Android系統源碼學習:Android內核編譯教程
          Android系統源碼學習:Android內核編譯教程 時間:2018-08-16     來源:未知

          之前分享過一些關于Android源代碼學習方法的文章,初次接觸Android源代碼的朋友建議去看一下。今天我們主要分享具體Android系統源碼學習中的Android內核編譯的相關知識。

          Android系統源碼學習:Android內核編譯教程
          Android內核編譯教程

          1、編譯Android源碼

          關于android系統的編譯,Android的官方網站上也給出了詳細的說明。

          http://source.android.com/source/building.html

          Ø 初始化編譯環境:

          切換到Android源碼目錄:

          $ cd android_source

          執行下面命令,加載編譯過程中用到的命令、環境變量:

          $ source build/envsetup.sh

          Ø 選擇編譯選項:

          執行下面的命令,從列表中選擇一個編譯項:

          $ lunch

          You're building on Linux

          Lunch menu... pick a combo:

          1. full-eng

          2.full_x86-eng

          3.vbox_x86-eng

          4.full_maguro-userdebug

          5.full_tuna-userdebug

          6.full_panda-eng

          我們選擇1,也就是說,編譯full-eng的目標,當然我們也可以直接指定編譯項,如下:$ lunch full-eng。

          其中,lunch命令是指打印或設置出當前系統中設置的編譯項,full-eng這個編譯項由兩部分組成,其中前半部分full表示目標設備為Android的模擬器,官方解釋為:fully configured with all languages,apps, input methods,全部的應用程序及語言,輸入法等。后半部分eng表示帶有調試功能的工程機。lunch命令打印全部的信息,如下表所示:

          lunch命令打印全部的信息

          Ø 編譯前的準備:

          由于我們使用ubuntu12.04對Android進行編譯,Android對Ubuntu12.04的編譯平臺的支持不是很推薦,有些庫的兼容方面會有一些問題,在編譯過程中會產生一些錯誤,我們要進行一些修正。

          具體錯誤會在編譯過程中表現出來,可以根據錯誤信息,然后搜索解決方案。

          Ø 編譯源碼:

          輸入下面命令開始編譯:

          $ make -jn

          其中,-jn表示,n個線程同時編譯,一般n的值為CPU核的2倍,但是,也要和你的Ubuntu的內存有關系,每個線程在編譯時少需要1G內存,如果你沒有很多內存,還是直接使用make命令吧,否則,編譯到后面會出錯。

          這個過程,如果是虛擬機的話,至少要4個多小時,如果是實體機的話,要看配置,一般在1個小時以上。

          編譯成功結果如下圖所示:

          Android內核源碼編譯成功界面

          2、編譯goldfish內核源碼:

          編譯Linux源碼必然要先指定gcc交叉編譯器,我們直接使用Android自帶的arm-eabi-4.4.3編譯器,它在android_source/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin路徑下。

          $ ls android_source/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin

          編譯goldfish內核源碼

          我們編輯下面一個編譯腳本make_kernel.sh,讓這個腳本去編譯goldfish的內核:

          #!/bin/bash

          export PATH=/home/android/android_source/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH

          export ARCH=arm #指定目標體系的架構

          export SUBARCH=arm #指定目標體系的子架構

          export CROSS_COMPILE=arm-eabi- #配置交叉編譯器

          make goldfish_armv7_defconfig

          make

          為了確保環境參數正確,接下來執行下面兩條指令,否則有可能不能正常啟動模擬器。(注:以下兩條指令是在Android源碼根目錄下執行)

          $ source build/envsetup.sh #缺少這條指令,可能會導致無法編譯通過

          $ lunch full-eng

          //缺少這條指令,可能會導致無法啟動模塊器,系統報無法找到AVD,并要求你創建AVD。

          注:用$make goldfish_defconfig這樣配置也可以編譯通過,模擬器也可以啟動,但是Android的開機畫機就顯示不了,$adb shell也死活連不上,原因就是這個goldfish_defconfig這個配置文件問題。

          給make_kernel.sh添加可執行權限,然后執行該編譯腳本:

          $ chmod a+x make_kernel.sh

          $ ./ make_kernel.sh

          當我們看到下面的結果時,表示goldfish的內核編譯出來了:

          goldfish的內核編譯成功界面

          $ ls arch/arm/boot/

          可以看到zImage文件。

          zImage文件

          在模擬器中啟動編譯好的內核:

          $ emulator -kernel /home/android/android_source/kernel/goldfish/arch/arm/boot/zImage

          模擬器啟動界面:

          模擬器啟動界面

          進入模擬器從設置里看版本信息:

          進入模擬器從設置里看版本信息

          從上圖可以看出當前Android版本是4.0.1,內核版本是2.6.29,說明成功了。

          同樣也可以通過adb shell來查看內核版本信息,如下圖:

          $adb shell

          #cd proc

          #cat version

          通過adb shell來查看內核版本信息

          備注:可以在源碼的根目錄下運行emulator –help查看模擬器的幫助信息。其中,可以通過-kernel指定你自己編譯出的kernel;-partition-size系統分區的大小;-memory指定內存RAM的大小;-skin指定模擬器的皮膚;-avd指定模擬器的名字等。

          3、 Android編譯過程分析:

          按照google給出的編譯步驟如下:

          Ø source build/envsetup.sh:加載命令;

          Ø lunch:選擇目標平臺編譯選項;

          Ø make:執行編譯;

          我們按照編譯步驟來分析編譯過程的細節,終添加自己的平臺產品的編譯選項。

          3.1、source build/envsetup.sh:

          該命令是用來將envsetup.sh里的所有用到的命令加載到環境變量里去。主要幾個命令如下:

          function help() #顯示幫助信息

          function check_product() #檢查product

          function check_variant() # 檢查變量

          function printconfig() #打印配置

          function add_lunch_combo() # 添加lunch項目

          function print_lunch_menu() # 打印lunch列表

          function lunch() #配置lunch

          function m() #make from top

          function mm() #make from current directory

          function mmm() #make the supplied directories

          build/envsetup.sh其主要作用如下:

          加載了編譯時使用到的函數命令,如:help,lunch,m,mm,mmm等;

          添加了兩個編譯選項:generic-eng和simulator,這兩個選項是系統默認選項

          查找vendor/*/*/vendorsetup.sh和device/*/*/vendorsetup.sh,也就是說從vendor/<廠商目錄>/<平臺設備目錄>/目錄和device/<廠商目錄>/<平臺設備目錄>/目錄下,查找vendorsetup.sh,如果找到的話,加載執行它,添加廠商自定義產品的編譯選項。

          如果想要添加自己的目標設備編譯選項,我們就要在device或vendor目錄下創建設備廠商,然后在設備廠商目錄下,創建一個vendorsetup.sh文件,在里面添加上自己的編譯項。

          $mkdir -p device/farsight/fsdevice

          $touch device/farsight/fsdevice/vendorsetup.sh

          $echo "add_lunch_combo fs100-eng" > device/farsight/fsdevice/vendorsetup.sh

          注:

          farsight:廠商名

          fsdevice:平臺設備名

          fs100-eng:自定義的目標產品名為fs100,eng為編譯目標類型

          所有的編譯項的格式都是:設備名-編譯目標類型,編譯目標類型為:eng,user,userdebug,三種類型之一(詳細見3.1節)。

          下面驗證一下我們的結果,當在Android目錄下,再次執行source build/envsetup.sh時,我們可以看到我們新添加的編譯項:

          查看新添加的編譯項

          3.2、執行lunch full-eng:

          我們當然也可以直接執行lunch命令,然后在彈出菜單里面來選擇我們的編譯項,如下圖所示:

          執行lunch full-eng

          注:我們添加的編譯項這時已經存在了,但是如果你選擇了它,在編譯時會出錯,因為我們還沒有對應編譯項的配置文件。

          lunch命令可以帶參數和不帶參數,終導出一些重要的環境變量,從而影響編譯系統的編譯結果。導出的變量如下(以lunch full-eng為例):

          TARGET_PRODUCT=full

          TARGET_BUILD_VARIANT=eng

          TARGET_BUILD_TYPE=release

          3.3、執行make命令:

          當我們輸入make命令后,就開始android系統的編譯了,所有的Makefile都通過build/core/main.mk這個文件組織在一起,它定義了一個默認goals:droid,當我們在TOP目錄下,敲make實際上就等同于我們執行make droid。

          當make include所有的文件,完成對所有make文件的解析以后就會尋找生成droid的規則,依次生成它的依賴,直到所有滿足的模塊被編譯好,然后使用相應的工具打包成相應img。其中,config.mk,envsetup.mk,product_config.mk文件是編譯用戶指定平臺系統的關鍵文件。Android的編譯系統比較復雜,詳細的說明請參照前面給出博文內容。

          下面列出在編譯過程中經常使用的一些命令:

          1、source build/envsetup.sh:加載編譯命令,產生編譯選項;

          2、lunch或lunch xxx-yyy:打印編譯選項菜單或指定編譯選項,xxx表示產品,yyy表示編譯類型;

          3、make:根據lunch選項,編譯Android系統,后產出為:system.img,ramdisk.img,userdata.img;

          4、m:和make命令一樣;

          5、mm:從當前目錄下開始向下編譯目標;

          6、mmm:指定一個目錄,僅編譯指定目錄下的目標;

          7、make snod:只將out/target/product/XXX/system/目錄下的內容打包生成system.img,不會檢查依賴關系;

          8、make bootimage:只將out/target/product/XXX/root/目錄下的內容打包生成ramdisk.img。

          前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2018 北京華清遠見科技發展有限公司

          Android培訓

          版權所有 ,京ICP備16055225號,京公海網安備11010802025203號
          内蒙古十一选五软件