1. 程式人生 > >【android原始碼】編譯android M原始碼、刷機,開啟原始碼學習的First Step

【android原始碼】編譯android M原始碼、刷機,開啟原始碼學習的First Step

一、概述

編譯android原始碼強烈建議在Linux作業系統下,最好在物理機器上安裝Linux作業系統,筆者使用發行版ubuntu 16.04作為PC系統,不建議在win上安裝虛擬機器vmvare解決,因為穩定性大打折扣,筆者曾經不知所以虛擬機器上的作業系統就掛掉了,如果打算研究原始碼,物理機器上安裝雙系統或者僅僅安裝Linux,作為開發者建議使用Linux,不要問我為什麼。

有了Linux作業系統還是不夠的,這隻表明你可以下載編譯android原始碼了,如果想了解原始碼,那麼一部nexus手機就是必備的,當然現在google已經不再發布nexus系列了,可以購買最新版的Pixel系列手機,總之,android開發者儘量使用太子是好事,如果你的app相容太子,那麼其他第三方ROM手機支援不好,那一定是他們把原始碼改亂了,很大程度和我們關係不大,有時需要做專門的適配工作,但首先應該適配的永遠是太子系列。紙上得來終覺淺,絕知此事要躬行。只有自己編譯原始碼,打入Log檢視執行流程,才能理清楚原始碼工作的一些細枝末節,這部手機基本是必備的。

良好的網路環境,最好科學上網。我這裡介紹的是使用國內映象下載對應分支的原始碼。筆者使用安裝ubuntu 16.04 PC一臺,Nexus 5手機一臺,高品質資料線一根,使用清華的原始碼映象。

二、ubuntu作業系統安裝

作為使用廣泛的linux發行版之一,ubuntu廣受歡迎,目前的最新穩定版本為16.04,可以到http://cn.ubuntu.com/download/烏班圖官網下載。網路上製作U盤系統的工具很多按照步驟製作即可,安裝的時候用u盤啟動,一直提示:vesamenu.c32:not a COM32R image無法進行下一步,則直接輸入live回車即可。

三、下載原始碼工具準備

在Linux平臺下進行Android系統專案開發時,需要git和repo管理。

Git和Repo的區別:

  1. Git:Git是一個開源的分散式版本控制系統,用以有效、高速的處理從很小到非常大的專案版本管理。

  2. Repo: Repo是谷歌用Python指令碼寫的呼叫git的一個指令碼。主要是用來下載、管理Android專案的軟體倉庫(也就是說Repo是用來管理給Git管理的一個個倉庫的)

1.Git安裝

已安裝忽略這一步驟

apt-get install git

2.Repo下載與使用

下載 repo 工具:

mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo

無法下載的話,先用git clone一份

git clone https://mirrors.tuna.tsinghua.edu.cn/git/git-repo

拷貝其中的repo指令碼到你的PATH裡即可,設定方式可以參照上面。

四、下載android原始碼

1.建立工作目錄

mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY

例如筆者在使用者目錄下新建android-6.0.1_r72資料夾,進入這個資料夾。

mkdir android-6.0.1_r72
cd android-6.0.1_r72

2.下載相應版本的原始碼

Build Branch Version Supported devices
NDE63X android-7.1.0_r7 Nougat Pixel XL, Pixel
M4B30X android-6.0.1_r72 Marshmallow Nexus 5
MOB30Y android-6.0.1_r60 Marshmallow Nexus 5
MMB29K android-6.0.0_r1 Marshmallow Nexus 5

原始碼下載,具體下載那個版本只需修改後面的分支名稱。

repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.1_r72

init成功後,開始漫長的同步原始碼樹(以後只需執行這條命令來同步)。

repo sync

這還不夠,因為很有可能出錯跳出來了,我們需要一個指令碼,在出問題的情況下再次執行repo sync,在當前需要下載原始碼的目錄下新建down.sh檔案,直接使用vi命令即可。

vi down.sh

接下來,在vi編輯器內輸入下面這段指令碼程式碼,儲存退出。

#!/bin/sh
repo sync
while [ $? -ne 0 ]
do
repo sync
done

用這段指令碼執行,替換repo sync這條命令。

./down.sh

N個小時過去後,終於下載好了。小水管的筆者下了15個多小時才完成。開始著手搭建原始碼編譯環境。

五、原始碼編譯

對應分支的原始碼下載好以後,接下來就開始激動人心的編譯工作,但編譯之前還需要先配置環境。

1.搭建編譯環境

筆者環境
- Ubuntu 16.04 LTS
- Android android-6.0.1_r72分支原始碼
- Open JDK 7

上面的兩者已經具備了,那麼還需要安裝Open JDK 7,注意是Open JDK,並非甲骨文的Oracle JDK。

這部分內容引自csdn博主梧桐那時雨。

(1) 更換軟體源

為了更快的安裝軟體,我們需要更換軟體源為國內的軟體源,這裡推薦使用Ubuntu官方指定的國內軟體源阿里雲,具體方法是:

sudo gedit /etc/apt/sources.list 

在檔案最前面加入下面程式碼:

deb http://mirrors.aliyun.com/ubuntu/ quantal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ quantal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ quantal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ quantal-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ quantal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ quantal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ quantal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ quantal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ quantal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ quantal-backports main restricted universe multiverse

(2) 安裝依賴

sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386 
sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib 
sudo apt-get install tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386 
sudo apt-get install dpkg-dev libsdl1.2-dev libesd0-dev
sudo apt-get install git-core gnupg flex bison gperf build-essential  
sudo apt-get install zip curl zlib1g-dev gcc-multilib g++-multilib 
sudo apt-get install libc6-dev-i386 
sudo apt-get install lib32ncurses5-dev x11proto-core-dev libx11-dev 
sudo apt-get install lib32z-dev ccache
sudo apt-get install libgl1-mesa-dev libxml2-utils xsltproc unzip m4

Ubuntu 16.04請務必使用上面的依賴,Ubuntu 16.04需要的依賴和Ubuntu 14.04所需要的依賴是不同的。

(3) 安裝open JDK7

由於Ubuntu 16.04沒有OpenJDK7的源,因此在16.04上安裝OpenJDK7需要執行下面的命令:

sudo add-apt-repository ppa:openjdk-r/ppa 
sudo apt-get update
sudo apt-get install openjdk-7-jdk 

配置OpenJDK.開啟/etc/profile檔案:

sudo gedit /etc/profile

在末尾追加下面程式碼:

export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
export JRE_HOME=${JAVA_HOME}/jre 
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib 
export PATH=${JAVA_HOME}/bin:$PATH

修改了/etc/profile檔案需要重啟才能生效,但使用下面命令可以在不重啟的情況下在當前bash環境生效:

source /etc/profile

檢查OpenJDK配置是否正確:

java -version

配置正確如下圖:

image

2.修改原始碼待編譯

修改android-6.0.1_r72/art/build/Android.common_build.mk 檔案,定位到75行,將下面的程式碼改為false:

ifneq ($(WITHOUT_HOST_CLANG),true) 改為 ifeq ($(WITHOUT_HOST_CLANG),false)

3.下載驅動

image
image

我這裡下載對應的M4B30X,下載成功後得到三個壓縮包broadcom-hammerhead-m4b30x-7c7b231f.tgz、lge-hammerhead-m4b30x-74fa3aa5.tgz、qcom-hammerhead-m4b30x-158606cf.tgz,解壓這三個壓縮包,解壓出來是三個sh檔案,放到Android原始碼目錄下面即android-6.0.1_r72下,然後執行。會將相關驅動放到vender目錄下面。

拷貝三個sh到原始碼目錄:

cp /media/lhw/LHW/extract-broadcom-hammerhead.sh /home/lhw/aosp/android-6.0.1_r72/
cp /media/lhw/LHW/extract-lge-hammerhead.sh /home/lhw/aosp/android-6.0.1_r72/
cp /media/lhw/LHW/extract-qcom-hammerhead.sh /home/lhw/aosp/android-6.0.1_r72/

拷貝成功後,賦予執行許可權

chmod a+x extract-broadcom-hammerhead.sh
chmod a+x extract-lge-hammerhead.sh
chmod a+x extract-qcom-hammerhead.sh

執行每個sh,輸入I ACCEPT,最終將驅動放到vender目錄待使用。

4.開始編譯

(1) 在 .bashrc檔案末尾新增:export USE_CCACHE = 1

echo export USE_CCACHE=1 >> ~/.bashrc

(2) 為了提高編譯效率,設定編譯器快取記憶體:

prebuilts/misc/linux-x86/ccache/ccache -M 50G

(3) 接著匯入編譯Android原始碼所需的環境變數和其它引數:

source build/envsetup.sh
including device/asus/deb/vendorsetup.sh
including device/asus/flo/vendorsetup.sh
including device/asus/fugu/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/htc/flounder/vendorsetup.sh
including device/huawei/angler/vendorsetup.sh
including device/lge/bullhead/vendorsetup.sh
including device/lge/hammerhead/vendorsetup.sh
including device/moto/shamu/vendorsetup.sh
including sdk/bash_completion/adb.bash

(4) 執行lunch命令選擇編譯目標:

lunch
Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_mips-eng
     4. aosp_mips64-eng
     5. aosp_x86-eng
     6. aosp_x86_64-eng
     7. aosp_deb-userdebug
     8. aosp_flo-userdebug
     9. full_fugu-userdebug
     10. aosp_fugu-userdebug
     11. mini_emulator_arm64-userdebug
     12. m_e_arm-userdebug
     13. mini_emulator_mips-userdebug
     14. mini_emulator_x86_64-userdebug
     15. mini_emulator_x86-userdebug
     16. aosp_flounder-userdebug
     17. aosp_angler-userdebug
     18. aosp_bullhead-userdebug
     19. aosp_hammerhead-userdebug
     20. aosp_hammerhead_fp-userdebug
     21. aosp_shamu-userdebug

選擇19:

Which would you like? [aosp_arm-eng] 19

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=6.0.1
TARGET_PRODUCT=aosp_hammerhead
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=krait
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.4.0-47-generic-x86_64-with-Ubuntu-16.04-xenial
HOST_BUILD_TYPE=release
BUILD_ID=M4B30X
OUT_DIR=out
============================================

(5) 開始編譯,執行make -j6, 6為同時編譯的執行緒數,一般google推薦這個數字為2倍的cpu個數再加上2,比如4核,就是10。

make -j6

檢視cpu核心個數命令:

cat  /proc/cpuinfo

編譯結束,大功告成!首次編譯花費了6個多小時,out目錄會有對應的輸出檔案。

五、刷機

1.adb、fastboot命令生效

關於這一步大家應該不陌生,android platform-tools裡有adb、fastboot。具體可以到http://www.androiddevtools.cn/下載,配置環境變數,確保fastboot命令正常工作。

2.進入recovery模式

Nexus 5關機狀態下,長按音量下鍵和power鍵,即可進入recovery模式
image

3.開始刷機

原始碼根目錄下輸入:

fastboot -w flashall

執行命令後輸出如下:

target reported max download size of 1073741824 bytes
Creating filesystem with parameters:
    Size: 29236371456
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8192
    Inode size: 256
    Journal blocks: 32768
    Label: 
    Blocks: 7137786
    Block groups: 218
    Reserved block group size: 1024
Created filesystem with 11/1785856 inodes and 156120/7137786 blocks
Creating filesystem with parameters:
    Size: 734003200
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 7472
    Inode size: 256
    Journal blocks: 2800
    Label: 
    Blocks: 179200
    Block groups: 6
    Reserved block group size: 47
Created filesystem with 11/44832 inodes and 5813/179200 blocks
--------------------------------------------
Bootloader Version...: HHZ20f
Baseband Version.....: M8974A-2.0.50.2.29
Serial Number........: 0313b757307b7e19
--------------------------------------------
checking product...
OKAY [  0.100s]
sending 'boot' (9160 KB)...
OKAY [  0.630s]
writing 'boot'...
OKAY [  0.799s]
sending 'recovery' (10018 KB)...
OKAY [  0.701s]
writing 'recovery'...
OKAY [  0.842s]
erasing 'system'...
OKAY [  1.048s]
sending 'system' (406390 KB)...
OKAY [ 17.923s]
writing 'system'...
OKAY [ 29.100s]
erasing 'userdata'...
OKAY [ 16.383s]
sending 'userdata' (139109 KB)...
OKAY [  5.941s]
writing 'userdata'...
OKAY [  9.321s]
erasing 'cache'...
OKAY [  0.602s]
sending 'cache' (13348 KB)...
OKAY [  0.760s]
writing 'cache'...
OKAY [  1.064s]
rebooting...

finished. total time: 86.021s

總記86.021s,通過fastboot命令將boot.img、recovery.img、system.img等映象檔案寫入了手機,手機自動重啟,這時候比平時要慢一些。

首次開機:
image

沒有谷歌全家桶的桌面:
image

再來看看設定,Build number 中可以看到M4B30X,這是google支援nexus 5最新的程式碼了,官方不再更新。
image

由於編譯的是userdebug版本,系統已經自帶root許可權,我們來看一下。

adb root

輸出adbd is already running as root,一切正常,以後可以通過只燒寫部分模組檢視修改了,畢竟全編太耗時了。

以上就是從PC烏班圖系統安裝到安卓原始碼下載,再到編譯和刷機的所有內容,萬里長征的第一步,以後就可以隨心所欲的原始碼探索之旅了。

參考資料