1. 程式人生 > >[Android編譯(二)] 從谷歌官網下載android 6.0原始碼、編譯並刷入nexus 6p手機

[Android編譯(二)] 從谷歌官網下載android 6.0原始碼、編譯並刷入nexus 6p手機

1 前言

經過一週的奮戰,終於從谷歌官網上下載最新的android 6.0.1_r62原始碼,編譯成功,併成功的刷入nexus6p,接著root完畢,現寫下這篇部落格記錄一下實踐過程。

2 簡介

自己下載android系統原始碼,修改定製,然後編譯刷入安卓手機,想想還有點小激動呢。簡單點說一句話——定製我們自己的MIUI,這就是android的魅力,這篇部落格博主就來教大家實現自己的定製系統。
首先,要明白下面的基礎知識:

(1) 什麼是aosp?
aosp就是android open source project(安卓開源專案),也就是android原始碼的簡稱,使用git管理,我們要下載的就是aosp原始碼,它託管在谷歌的伺服器上,直接編譯aosp後得到的android系統就叫原生android。

(2) 如何下載aosp?
aosp需要專門的下載工具repo下載,當然必須科學上網。

(3) 如何編譯aosp?
aosp必須在Linux系統上編譯,官方推薦的是Ubuntu系統。目前官網上只有Ubuntu 14.04的編譯教程,但博主用的是Ubuntu 16.04,並且編譯成功了。

(3) 什麼手機可以刷入aosp?
並不是所有安卓手機都可以刷入安卓原始碼,雖然aosp是開源的,但是aosp本身介面很簡陋,也不帶有驅動,所以廠商拿到aosp後都會進行定製,這些定製系統就是MIUI們,它們並不開源,所以你無法拿到MIUI的原始碼,自然也無法編譯它了。現在大部分手機廠商為了自家定製系統的市場佔有率,都給手機的bios(bootloader)加了鎖,所以魅族的手機你是無法刷入小米的系統的。所以能夠刷入原生android的機型很少,博主只知道谷歌的nexus系列和一加手機可以。這裡推薦谷歌nexus系列手機,也就是人稱的太子,android的標杆機,當然,nexus手機不在大陸發售,你需要在萬能的淘寶上購買。

(4) android開放但不開源
android並不是真正的開源作業系統,因為android的驅動是不開源的,所以它從Linux中除名了,linux才是真正的開源系統,你可以拿到所有原始碼,包括驅動,但是安卓不行,所以安卓是開放的系統。android把驅動放在了HAL層,這個是抽象層,具體實現交給了各個廠商,而且為了規避GPL協議的傳染性,android巧妙的將HAL層放在了使用者態,並且把關鍵的核心庫全部重寫了,從而保證從android的framework層開始不必開源了,不得不說谷歌在開源和商業化之間做了巧妙的結合,這也是安卓能夠迅速發展的原因之一。所以,我們編譯的系統要刷入手機中去最難的地方就是沒有驅動,那麼有沒有手機廠商放出了驅動呢?有的,這就是谷歌的nexus系列手機,最新的是nexus 5x和nexus 6p,作為android開發者必備手機。

(5) 什麼是CM?
前面提到了,將AOSP刷入手機最困難的地方是沒有驅動,因為驅動是商業機密,是閉源的,那麼有沒有人專門處理不同手機的驅動問題呢,遮蔽掉驅動的差異呢?答案是有的,這就是大名鼎鼎的Cyanogenmod,簡稱CM,目前全球最有名的第三方編譯團隊。換句話說,如果你的手機不是nexus系列手機,又想編譯原始碼刷入手機中,那麼你可以下載你手機型號對應的CM的原始碼。當然,CM是怎麼解決驅動問題的呢,據說是從官方ROM中提取的二進位制程式碼。

3 環境

  • Ubuntu 16.04
  • nexus 6p
  • 科學上網
  • Git
  • Gmail 郵箱
  • Twrp recovery
  • Open Gapps
  • SuperSU

4 準備工作

(1) 安裝ubuntu 16.04
首先要安裝Ubuntu 16.04,博主直接安裝在實體機器上,你也可以在vmware虛擬機器中安裝,但是強烈建議在實體機器上直接安裝Ubuntu,因為執行流暢、編譯速度快,節約時間。Ubuntu和windows的相容做的很好,博主安裝的就是win7和Ubuntu雙系統。
至於如何安裝Ubuntu百度一下一大堆,這裡博主就帶過來了,只是順便提醒一點,如果在實體機上安裝Ubuntu,一定要給Ubuntu的/home分割槽至少250G空間,因為原始碼解壓、編譯後真的很大,如果你想把原始碼壓縮儲存起來,那麼至少300G空間,博主就在壓縮的過程中遇到了空間不足的情況,只好切換到win7用分割槽助手壓縮分出空閒分割槽,然後再用Gparted在Linux下面把空閒分割槽分給/home,整整浪費一天時間,其中涉及到windows和linux重新分割槽,Gparted用法,linux啟動修復等高階技術,所以提醒大家多分點空間給Linux.

(2) 科學上網
要下載Google上的Android原始碼必須學會科學上網,博主使用的是搬瓦工vps+shadowsocks的方式科學上網,為了下載Android原始碼,博主專門寫了一篇如何科學上網的部落格,具體請看這裡:

科學上網一般都是要花錢的,免費的不穩定。

(3) Gmail郵箱
在下載原始碼的過程中,谷歌為了防止匿名連線過多,對同一個ip的訪問次數進行了限制,這就導致我們下載過程中很可能會失敗,因此我們需要用一個谷歌賬號(也就是Gmail郵箱)來進行驗證。博主在下載過程中就遇到了匿名下載失敗這個問題,後來加了驗證之後才下載成功。有了Gmail郵箱就可以使用Google的所有服務了,可以體驗優秀的Google App了,如果你還沒有Gmail賬號,那就趕緊去申請吧,當然,前提是能科學上網。

(4) nexus 6p手機
作為Android標杆機,nexus系列是Android開發者必備,你可以自己修改原始碼,編譯後push到手機中看看效果,這樣學習過程就不會枯燥了,想想是不是還有點小激動呢。如果nexus手機上某個app有問題,那麼一定是app寫的不好,而不是手機的問題,這就是標杆機。目前最新的nexus系列是華為代工的nexus 6p,顏值高,大螢幕,雙喇叭,瞬間指紋解鎖,高階大氣,上一張nexus 6p的圖片:

這裡寫圖片描述

當然原生的AOSP不帶谷歌全家桶(GApps),用nexus不用谷歌全家桶就好比喝拿鐵不加糖一樣—苦不堪言。所以,刷機完畢,博主會教大家如何刷入Google Apps。
最後補充一點,nexus不翻&牆也是可以用的,但是,逼格呢?

5 下載原始碼

(1) 安裝Git
Git安裝命令如下:

sudo apt-get install git 

安裝完畢,配置Git賬號,這裡使用者名稱可以隨便寫,但是郵箱請務必使用你的Gmail郵箱,因為涉及到下面的訪問驗證,命令如下:

git config --global user.name "Your Name"   
git config --global user.email "Your [email protected]"

(2) Google賬號驗證
對於匿名訪問,為了防止連線過多,谷歌對同一個ip的訪問次數進行了限制,所以我們需要新增一個下載驗證,開啟下面的連結:

登入谷歌賬號,會看到下面的介面:

這裡寫圖片描述

翻譯一下就是:通過複製下面的指令碼程式碼到shell中,為Git配置cookie,用於訪問谷歌服務。
如果你是在windows下用Git for windows來下載原始碼,那麼複製上面框框裡面程式碼到cmd命令列中去執行,一行一行的執行。
由於我們使用的是Ubuntu,所以我們開啟shell視窗,將下面框框的程式碼一行一行的複製到shell中執行,複製一行執行一行就可以了。

(3) 安裝repo
android原始碼包括很多模組,每個模組都是一個個工程,不同版本依賴不同模組,總不能一個一個去下載這些工程吧,所以為了管理這些工程,谷歌開發了一個管理Git倉庫的工具叫repo,官網的安裝教程是這樣的:
首先建立bin資料夾:

$ mkdir ~/bin
$ PATH=~/bin:$PATH

下載repo工具:

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

(4) 選擇合適的原始碼版本
android原始碼除了大版本外還有很多小版本,例如:android-6.0.1_r62,6.0.1就是大版本號,r62就是小版本號,因此我們需要先確定好需要下載的版本號,具體有哪些版本請看下面的連結:

第一列是編譯的代號,第二列是版本號,第三列是版本名稱,最後一列是該版本支援的手機型號,請下載與你手機對應的版本,由於博主用的是nexus 6p,所以我下載的是最新的android-6.0.1_r62:

這裡寫圖片描述

(5) 開始下載
確定了版本號之後,首先建立資料夾,這裡以版本號命名:

$ mkdir android-6.0.1_r62
$ cd android-6.0.1_r62

初始化repo,注意把 -b 後面改為你要下載的版本號:

$ repo init -u https://android.googlesource.com/platform/manifest -b android-6.0.1_r62

使用下面的命令就可以開始下載了:

$ repo sync 

但是,請先不要著急下載,由於下載過程中還會遇到各種各樣的問題,所以我們需要建立一個自動下載指令碼,確保出錯了之後會自動執行repo sync,在android-6.0.1_r62下建立一個指令碼down.sh,程式碼如下:

#!/bin/bash
repo sync  -j16
while [ $? = 1 ]; do  
        echo “======sync failed, re-sync again======”  
        sleep 3  
        repo sync  -j16
done 

在shell中執行下面命令:

chmod a+x down.sh
./down.sh

好了,開始下載原始碼了,整個原始碼大概有40G,建議在晚上下載。在沒有下載完畢之前,原始碼的資料夾中只有一個.repo資料夾,這是正常的,等到所有原始碼下載完畢,其餘資料夾就會出現,不要著急。下載完畢後如下圖:

這裡寫圖片描述

全部下載完後android-6.0.1_r62中檔案如下:

這裡寫圖片描述

(6) 備份原始碼
原始碼下載完畢後,先不要著急著編譯,我們先備份一下原始碼,萬一玩壞了還可以推倒重來,否則又要辛辛苦苦下載一遍。博主一上來就直接壓縮打包android-6.0.1_r62這個原始碼資料夾,結果發現有50多G,直接把磁碟爆掉了,於是又重新從windows下面分出空閒分割槽,然後調整Linux的分割槽,折騰了整整一天,後來解壓的時候解壓了半個小時還沒有解壓完,又把硬碟給爆掉了。仔細一想,不對啊,別人上傳到網盤的原始碼只有7G左右啊,我的原始碼怎麼這麼大呢,後來發現都是.repo這個資料夾太大了,百度一下,發現這個資料夾只是與程式碼同步有關,並不影響編譯,於是果斷刪掉之後,壓縮打包原始碼,這次只有7G左右,而且刪掉之後編譯成功。下面我們來備份原始碼。
首先刪掉 .repo 資料夾,然後使用下面的命令:

cd ~
tar -zcvf android-6.0.1_r62.tar.gz android-6.0.1_r62/

壓縮完畢後android-6.0.1_r62.tar.gz只有不到7G,如果你已經編譯完了才備份程式碼,那麼備份前請使用make clean來清除掉編譯出來的檔案,以便減小壓縮後的體積。

下載完原始碼請務必刪掉 .repo 資料夾,以便備份原始碼,同時防止編譯時磁碟空間不夠用

6 編譯

關於android 6.0 的編譯,請看我之前寫的一篇部落格,非常詳細,這裡不再贅述,部落格地址如下,只補充兩點:

(1) 下面三個庫如果你安裝失敗了,不用管他,照樣可以編譯成功:

libncurses5-dev:i386
libreadline6-dev:i386
lib32ncurses5-dev

(2) 在lunch的時候選擇17,如下圖所示:

這裡寫圖片描述

aosp_angler-userdebug ,解釋一下,angler是nexus 6p的代號(code name),每個裝置對應的代號如下:

這裡寫圖片描述

userdebug 是編譯型別,含義如下:

這裡寫圖片描述

user 用於正式產品
userdebug 和user類似,但是有root許可權,並且可以除錯,主要用於除錯
eng 開發用的選項,配有額外的除錯工具。

如果編譯後只在模擬器上執行,則lunch時選擇:1
這裡我們的目標是要編譯後刷入nexus 6p,所以 lunch 時選擇:17

如果你不知道lunch該選哪一個,請參考下面的連結,根據第三列選擇編譯選項:

上一張編譯成功後的圖:

這裡寫圖片描述

7 驅動概述

如果只在模擬器中執行,到這裡就結束了,但我們要把編譯好的映象刷入nexus 6p,首先得去官網下載工廠映象(factory image)。

(1) 為何還要下載工廠映象呢?
前面我們提到了,只有nexus系列手機放出了驅動,所以我們需要去谷歌官網獲取驅動。

(2) 驅動又是以什麼形式放出的呢?
在nexus 6p(5x)之前,例如nexus 5,驅動的二進位制程式碼(當然不可能有原始碼啦)是壓縮包的形式,下載後在aosp原始碼根目錄下面解壓,然後執行裡面的sh指令碼檔案,接著編譯全部原始碼就能編譯出驅動映象,谷歌一下都是這種方法,然而關於nexus 6p編譯AOSP後刷機時驅動問題的資料就很少了,博主在這裡卡了很長時間才搞清楚了nexus 6p刷入AOSP時如何刷入驅動的方法。

(3) 如何獲取nexus 6p的驅動?
從nexus 6p(5x)起,驅動都放在了專門的vender分割槽中,谷歌官網上只有工廠映象,沒有二進位制檔案的壓縮包了。我們需要下載工廠映象,然後提取出裡面的vender.img映象,刷入nexus 6p中就可以了。當然,經過實踐發現,驅動問題可沒這麼簡單就解決了哦。

8 刷機

(1) 首先到谷歌官網下載工廠映象,下載地址如下:

根據前面下載原始碼時候的編譯代號(Build)來選擇工廠映象:

這裡寫圖片描述

根據原始碼下載那一節,我們選擇的android-6.0.1_r62版本對應的build是MTC20F,所以我們下載MTC20F的工廠映象,博主將下載的檔案儲存在~/nexus6p目錄中。解壓後如下圖所示:

這裡寫圖片描述

(2) 配置adb命令
刷機需要使用adb和fastboot兩個命令,先下載Android SDK,下載地址如下:

開啟~/.bashrc檔案,在末尾追加下面的程式碼,注意替換成你的sdk路徑:

export PATH=$PATH:/home/fuchao/Android/Sdk/tools
export PATH=$PATH:/home/fuchao/Android/Sdk/platform-tools

重新開啟shell,輸入adb命令,看看配置是否生效。

(3) 解鎖bootloader
bootloader可以簡單理解為手機的bios,解鎖bootloader之後才可以用fastboot命令刷機(線刷),相當於U盤重灌系統,雖然不解鎖也可以通過進入recovery模式的方法刷機(卡刷),相當於PE重灌系統,但是強烈建議你解鎖,因為解鎖之後就不怕變磚了,萬一玩壞了,最後還可以通過fastboot救回來,當然,解鎖後就不能保修了,魚和熊掌不可兼得嘛。刷機是個long long story,相關知識請看後面章節,我們先來操作。
谷歌在nexus 6p的bootloader前面加了一個oem鎖,所以先得解oem鎖,才能再解bootloader鎖。
解oem鎖很簡單,開機進入設定、關於手機、連續點版本號6次,進入開發者模式,將OEM解鎖選項開啟,如下圖所示:

這裡寫圖片描述

建議一直開啟OEM解鎖,這樣你就可以隨時進入bootloader了,能夠進入bootloader就不怕變磚了。
接著解bootloader鎖,在shell中輸入下面命令進入bootloader:

adb reboot bootloader

bootloader介面如圖所示:

這裡寫圖片描述

接著輸入下面的程式碼解鎖bootloader:

fastboot flashing unlock

然後會看到下面的介面:

這裡寫圖片描述

用音量+選擇yes,電源鍵確認,解鎖完成。
解鎖完畢後,開機會顯示一個警告,請無視之,如圖:

這裡寫圖片描述

至此解鎖完畢。

(4) 備份資料
只需要備份聯絡人和簡訊就可以了,應用不需要備份,因為還原的時候太慢了,博主用的是360手機助手備份的。值得一提的是,如果你想備份Google App然後刷完機再還原,這是不行的,這不是谷歌全家桶的正確安裝姿勢。

(5) 刷機ing
萬事俱備,終於進入到了激動人心的刷機階段了,首先進入解壓後的工廠映象資料夾中,博主的是~/nexus6p/angler-mtc20f:

cd ~/nexus6p/angler-mtc20f

重啟進入bootloader,接著執行flash-base.sh指令碼:

adb reboot bootloader
./flash-base.sh

接著刷入驅動,解壓 image-angler-mtc20f.zip 檔案後進入image-angler-mtc20f資料夾:

unzip image-angler-mtc20f.zip
cd image-angler-mtc20f

刷入vernder.img:

fastboot flash vendor vendor.img

驅動刷入完畢,接著就要刷入我們編譯的其他映象了,進入原始碼編譯後生成的映象目錄android-6.0.1_r62/out/target/product/angler:

cd android-6.0.1_r62/out/target/product/angler

依次執行下面的命令,分別刷入映象:

fastboot flash boot boot.img
fastboot flash recovery recovery.img
fastboot flash system system.img
fastboot flash userdata userdata.img
fastboot flash cache cache.img

好了,刷完之後重啟就可以了:

fastboot reboot

到這裡就成功的刷入了我們編譯的aosp啦,不過別高興的太早,問題還在後頭呢。

(6) 一次批量刷入
到這裡你應該明白了,其實刷機就是將我們編譯出來的系統映象和工廠映象裡面的vernder.img用fastboot命令寫入手機中,那麼我們可以將imge-angler-mtc20f中的映象除vender.img以外全部替換成我們自己的,然後打包,用flash-all.sh指令碼一次性刷入,省時省力,下面來操作。
將imge-angler-mtc20f下的檔案除vender.img外全部替換成我們的,如下圖所示:

這裡寫圖片描述

在imge-angler-mtc20f下將所有檔案壓縮打成包imge-angler-mtc20f.zip:

cd ~/nexus6p/angler-mtc20f/image-angler-mtc20f
zip image-angler-mtc20f ./*

這個時候在 imge-angler-mtc20f 檔案下會產生一個 imge-angler-mtc20f .zip的檔案,接著替換掉上級資料夾angler-mtc20f中的同名檔案,如果你想保留官方映象檔案,只需要重新命名一下官方zip包就可以了。接著執行flash-all.sh指令碼:

cd ~/nexus6p/angler-mtc20f
./flash-all.sh

上一張一次刷入的圖片:

這裡寫圖片描述

(7) 原生AOSP
刷機完畢,開機,原生android就呈現在你面前,是不是有點小激動外稍微又有點小失望呢,沒有Google全家桶的AOSP醜的不是一點點啊,尤其是那個首頁的Google搜尋欄還停留在android 2.3的樣式,相機和相簿也是分分鐘不想用啊,預設的聲音簡直是滿大街山寨機即視感。作為谷歌粉的博主當然不能忍啦,但是別急,後面我們再來刷入Gapps,首先我們得解決一些”小”問題,你有沒有發現原生aosp刷入nexus 6p後不能識別sim卡和藍芽呢?也就是說,電話都打不了,每次開機都報個錯誤,說系統遇到一個問題,請聯絡裝置製造商。下面我們就來解決這兩個問題。

9 解決sim卡不識別問題

博主刷完aosp後遇到這個問題,sim卡怎麼都識別不了,驅動明明已經刷好了呀,於是順手百度了一下,結果差點嚇尿,看到機鋒論壇有人說是因為刷機前沒有備份,把基帶搞丟了,要返廠修理,於是趕緊看了下關於手機裡面,基帶一欄果然是空白的,嚇的午覺都沒睡好,這才剛買的手機呢不會就玩壞了吧?不管了,先喝口82年的雪碧冷靜一下,然後開始谷歌大法,經過一天奮鬥,終於解決了這個問題,擦,百度這個坑貨。
博主在這裡找到了解決方法:

出現這個問題的原因是,先看英文:

if vendor.img is not generated when system.img is prepared for build, a few bits are broken that also require manual fixing (various symbolic links between two partitions, bytecode product packages, vendor shared libs dependencies, etc.).

解釋一下,vender.img的生成需要以system.img為前提,其中涉及到一些符號、變數、分割槽、vernder依賴的包等都需要system.img中的資訊。也就是說,谷歌的工廠映象中的system.img和我們自己編的當然不同啦,所以直接刷入工廠映象的vender.img就會出現問題,需要我們自己生成vender.img。搞清楚了原因,下面我們就來解決它。
首先下載這個工程:

git clone [email protected].com:anestisb/android-prepare-vendor.git

接著進入這個工程,執行下面的命令:

./execute-all.sh -d angler -b MTC20F -o $(pwd) -i ~/nexus6p/angler-mtc20f-factory-4355fe06.zip -k

解釋一下引數:

-d 後面是裝置代號,nexus6p是angler
-b build id,分支編譯時的代號
-o 輸出目錄
-i 下載好的谷歌工廠映象路徑
-k (不懂,好像是保持所有工廠映象,優化資料)

耐心等待程式執行完畢,如圖所示,中間的那塊是API,自己看英文:

這裡寫圖片描述

執行完畢,會在我們的裝置代號檔案下,生成一個vender資料夾,例如博主的nexus6p生成的路徑就是 angler/mtc20f/vender,接著我們要將這個vender資料夾複製到我們的android原始碼目錄下面,注意:不要用GUI來操作,必須用命令,因為其中有些檔案你沒有許可權

//複製所有檔案到android原始碼下面
sudo cp ~/android-prepare-vendor/angler/mtc20f/vendor ~/android-6.0.1_r62/
//進入android原始碼目錄
cd ~/android-6.0.1_r62
//改變vernder所有者為自己,防止編譯的時候沒有許可權
sudo chown -R fuchao:fuchao ./vender

接著開始編譯嘍:

source build/envsetup.sh 
lunch           
make clean      
make -j8    

編譯完畢,在android-6.0.1_r62/out/target/product/angler 下面就可以看到我們自己遍出來的vender.img啦,趕緊刷入試試吧。上一張博主編譯好的圖:

這裡寫圖片描述

10 解決開機報錯的問題

刷完AOSP每次開機都會報個錯:

There’s an internal problem with your device. Contact your manufacturer for details

中文則是:

您的裝置內部出現了問題,請聯絡您的裝置製造商瞭解詳情。

如下圖所示:

這裡寫圖片描述

報這個錯的原因是,同樣先看英文:

The problem occurs because of a check that google implemented in Android 5.1 which compares /system/build.prop with the values found in /vendor/build.prop. If they differ you get that error message. All one has to do to get rid of the error is to change the 3 values in /vendor/build.prop according to the values in /system/build.prop.

翻譯一下:從android 5.1開始谷歌有個檢查,這個檢查會比較/system/build.prop和/vendor/build.prop這兩個檔案中的3個變數值,如果不一致則導致這個錯誤,解決方法是手動修改,讓兩個檔案中的這幾個變數保持一致。

聽起來很複雜,其實解決方法很簡單啦,將下面的壓縮包放在sd卡上,然後進recovery安裝就可以了:

博主是通過刷入twrp recovery後來安裝這個壓縮包的,如果你還不懂recovery是怎麼回事沒關係,看完後面的刷入Gapps章節後你就懂了。
問題解決。

最後附上博主搜到的解決問題的xda上的帖子:

作者說手動修改這些引數是很煩人的,於是他製作了這個壓縮包,看他原話:

Doing this manually after every flash is cumbersome so I created an update-zip that corrects the values in /vendor/build.prop in a generic way (it should work no matter what rom you use). It mounts /system and /vendor, extracts the relevant information from /system/build.prop and creates a new /vendor/build.prop. I successfully tested it on my nexus 9 so I decided to release it to all of you.

當然每次刷入新的rom都要重複上面的操作:

Just install it via your recovery and you are done! This has to be done every time you flash a new rom

xda,你值得擁有。

11 刷入Gapps

好了,解決了前面兩個問題,下面我們就來刷入谷歌全家桶嘍。先科普一下,谷歌全家桶,指的是Google開發的一系列App和Google服務,包括: Google Play,Google Now,Google Service,Google Play,Google Driver等。由於終所周知的原因,Google Service不能像普通app那樣安裝,反正博主是沒有安裝成功,沒有Google Service其餘的Google App即使安裝了也無法執行,所以必須使用Recovery的形式刷進去,所謂Recovery,你可以簡單的理解為windows pe系統,這裡博主推薦twrp recovery。去哪兒找哪些Google app呢?放心,早有第三方把谷歌一套收集打包好了,只等你刷進去了,這些包,行話叫Gapps,這裡博主推薦OpenGapps。下面我們來刷入OpenGapps。

首先,到這裡選擇你的裝置對應的twrp recovery版本去下載:

博主使用nexus6p下載地址:

注意:一定要下載你的裝置對應的twrp版本
接著刷入twrp,先用adb reboot bootloader命令進入bootloader,接著用下面的命令刷入twrp:

fastboot flash recovery twrp-3.0.2-2-angler.img

刷入twrp成功之後,接著我們去下載OpenGapps。OpenGapps的官網如下:

平臺選擇Arm64。OpenGapps有很多版本,各版本介紹如下:

  • stock :最為貼近 Nexus 機型體驗的 GApps 版本,包含了 Nexus 機型所預裝的所有 Google 服務和 Google 應用。需要注意的是,這個版本會用 Chrome 、 Google Now Launcher 、 Google Keybord 等 Google 應用替換掉 CM 系 ROM 中那些基於 AOSP 程式碼的相關應用。
  • full :與 stock 版所包含的內容相同,但不會替換 AOSP 應用。
  • mini :包含了完整的 Google 服務框架和主流 Google 應用,去掉了 Google Docs 等文件處理應用
  • micro :包含了完整的 Google 服務框架和少數 Google 應用,如 Gmail 、 Google Calender 、 Google Now Launcher 。
  • nano :包含完整的 Google 服務框架但不包含多餘的 Google 應用。
  • pico:包含了最基礎的 Google 服務框架,體積最小,一些依賴完整 Google 框架的應用(如 Google Camera )將無法執行。

這裡我們選擇stock就行了,保持和官方預裝的App一致。如下圖:

這裡寫圖片描述

然而,博主下載了很多次始終下載失敗,這個OpenGapps實在很難下載成功,於是博主從下面的帖子中的百度網盤下載了一個:

博主下載的檔案是open_gapps-arm64-6.0-stock-20160701.zip,接著將這個檔案放進手機的sdcard上,然後進入bootloader,按兩下音量減鍵,看到recovery,電源鍵確認進入,此時螢幕下方會有一個滑動條,向右拉即可:

這裡寫圖片描述

點選安裝,選擇我們放在sdcard上的Gapps,然後把滑動條拉到右邊即可開始安裝,

這裡寫圖片描述

安裝完畢,重啟系統就可以了,第一次開機可能比較慢。如果開機後不停的彈框報錯,請把選單拉下來,然後點選設定進入應用,給Google Service開啟所有許可權就行了。

特別注意:刷完aosp後必須馬上刷入Gapps,中途不能開機,否則會卡在開機Logo

12 root

root的原理就是把所有者為root的su檔案放入系統檔案/system/bin、/sbin等目錄下,放入之後就擁有了root許可權,但是這個放入過程需要root許可權,所以這就是矛盾的地方,怎麼想辦法放進去呢?一般思路是利用系統的漏洞,例如具有root許可權的程序對棧溢位,或者adbd提權漏洞等。但是漏洞越來越難找了,所以就有了下面recovery的方式,nexus6p的root方法很簡單,用twrp將下面的SuperSu刷入就可以了,前面我們已經用twrp刷入了OpenGapps,這裡OpenGapps換成SuperSu刷入就可以了,不再多說。
SuperSu的下載地址如下:

13 正確的刷機順序

好了,到這裡主要步驟就講完了,但是在實踐中,博主發現,刷入我們自己編譯的AOSP後,接著進入recovery刷入OpenGapps、刷入SuperSU完成root、刷入vendor-build-prop-fix-signed.zip 解決開機報錯的問題,可是這樣雖然成功的打開了系統,但是總是有很多APP報錯,也就是說很多APP用不了,例如:百度外賣、貓眼電影、餓了麼等點開就停止執行。這就很頭疼,總不能拿著個磚頭來裝X吧,說好的各大廠商都要適配AOSP的呢?博主在刷了大概10次以後,終於找到了解決辦法:進Recovery刷完後,要清除掉所有資料,包括虛擬機器的快取cache/Dalvik,博主估計是之前安裝App後的位元組碼還在Dalvik的快取中,與新的app衝突。所以正確的步驟如下:

  1. 拔掉SIM卡
  2. 刷入AOSP後接著刷入trwp-recovery,進入recovery後選擇wipe,清除掉所有資料,包括cache/Dalvik。這一步是為了清除資料,同時為放入OpenGapps做準備。
  3. 開機進入AOSP,將OpenGapps、vendor-build-prop-fix-signed.zip兩個檔案放入Sdcard中,SuperSu以後再刷。
  4. 再次刷入AOSP和trwp-recovery,進入recovery刷入OpenGapps、vendor-build-prop-fix-signed.zip
  5. 刷完兩個檔案之後再清除掉所有資料,包括cache/Dalvik
  6. 開機進入系統,按照谷歌的安裝嚮導來設定,並給谷歌服務所有許可權。
  7. 插入SIM卡,這個時候應該可以識別sim卡了
  8. 再次進入recovery,刷SuperSU,root掉

到這裡,基本上大部分APP都能運行了,像百度外賣、貓眼電影都可以運行了,然鵝,餓了麼這貨還是停止執行,博主打算留到以後再來研究,如果你解決了這個問題,或者找到了原因,歡迎給我留言。

14 實踐記錄

下面記錄博主在實踐過程中遇到的問題,以及怎麼解決這些問題的心路歷程。博主的體會就是:能用谷歌堅決不用百度這個渣渣。每當爆出一個error,如果全是英文的,博主就很happy,因為Google一下一定能搜到,如果是china特色的問題就很頭大,例如:QQ,以及GFW。

(1) 原始碼下載失敗問題
博主在下載原始碼工程中遇到一個錯誤:

A TLS packet with unexpected length was received

如圖:

這裡寫圖片描述

導致這個錯誤的原因是,谷歌對同一個IP的匿名訪問次數有限制,解決方法是在下載原始碼前,配置谷歌的訪問驗證,也就是設定Git的cookie,具體參見上文。

(2) fastboot 卡在 waiting for device
在使用fastboot命令刷入映象的時候總是卡在waiting for devices

$ fastboot flash boot boot.img
   < waiting for device >

看看devices:

$ fastboot devices
   no permissions  fastboot

原來是fastboot沒有許可權,那就給fastboot增加許可權:

$ whereis fastboot             //先看fastboot在哪兒
$ sudo chown root:root /bin/fastboot       //改為root使用者所有
$ sudo chmod +s /bin/fastboot          //執行的時候就會自動擁有root許可權
$ fastboot devices
   7D89BCD6        fastboot

注意替換你的fastboot位置。

(3) nexus 6p的驅動問題
編譯完AOSP後,怎麼處理驅動問題,博主在這裡卡了很長時間,最開始,在谷歌的官網上看到了放出nexus二進位制驅動的地方:

但是,始終沒有找到nexus 6p的二進位制驅動,於是又看了很多編譯Android 6.0的原始碼的部落格,要麼就是編譯完了之後啟動模擬器就結束了,要麼就是刷入nexus 5的教程,直接在官網下載一個驅動包,解壓後執行一個shell指令碼,再編譯就出現驅動了。
後來,在這裡看到一篇部落格,知道了nexus 6p的驅動是在工廠映象中:

不過作者說的太簡單了,又沒有操作步驟。然後自己摸索,將vernder.img刷入nexus 6p,結果開機發現sim卡無法識別,百度一下,發現基帶沒了,尼瑪,嚇了一跳。趕緊谷歌,後來在這裡發現了別人在谷歌論壇上提的問題:

慢慢看,居然有人解決了,臥槽,趕緊試試,看中間那個叫 Jared Tsai 的說:

The script will download a Google factory image, extract necessary files, and create a vendor folder for aosp.
Move the created vendor folder to aosp root and build the images again, the vendor.img will be in the out folder.
Just flash all the images into device, the radio works as normal.

然後博主開啟那個github後,就一臉懵逼了,尼瑪,全是英文,不知所云,怎麼用的也不寫清楚,還好下面有個example,博主clone之後,執行了一下指令碼,擦,各種引數說明都出來了,再對比一下example之後,嗯,so easy。
然後再看上面 Jared Tsai 說的,把生成的vender資料夾複製到原始碼資料夾下,開編。擦,過一會兒報個錯,說那個vender檔案找不到target,無法編譯,根據博主多年經驗,這很明顯是makefile檔案無法識別嘛,於是又谷歌,在谷歌論壇上發現別人也有同樣的問題,原因是複製的時候vender資料夾的檔案丟失了,沒有複製全,於是博主又在命令列下面用sudo來複制,然後修改所有檔案的所有者為自己,這樣再編譯就ok了,終於編出來了,費了好大勁才解決驅動問題。

(4) 繼續解決fuseext2的問題
後來博主在家裡面按照上面步驟操作的時候,在用anestisb/android-prepare-vendor這個工程來生成vender目錄的時候,執行execute-all.sh這個指令碼的時候遇到了下面這個問題:

這裡寫圖片描述

仔細看報錯:

fuse-ext2: command not found

擦,在公司電腦上好好的,在家裡的電腦就不行了,再看報錯,掛載system.img的時候失敗,懷疑是沒有許可權導致掛載失敗,於是sudo來執行指令碼,然鵝還是不行,遂谷歌一下,發現linux下面要讀取android的映象檔案,必須藉助fuse-ext2這個程式,接著找到fuse-ext2的github地址,然後clone下來,配置一下.bashrc,結果還是報同樣的錯,然後仔細看anestisb/android-prepare-vendor的github:

Required steps summary
…………………………
All scripts can be executed from OS X, Linux & other Unix-based systems as long as fuse-ext2 and other utilized command line tools are installed. Scripts will abort if any of the required tools is missing from the host

翻譯一下,就是執行這個指令碼前,系統必須安裝好fuse-ext2和其他一些工具。好了,明白了,是因為fuse-ext2這個工具沒有安裝,接著谷歌後找到了按照命令:

sudo apt-get install fuseext2

安裝完畢,再接著執行指令碼,解決問題。

(5) Open Gapps下載、刷入的問題
博主開始安裝Google Service時,打算用360手機助手,直接把刷機前備份的Google App還原到手機中,結果發現太慢了,幾十分鐘才還原了兩個,總共有28個,遂無法忍受放棄了,然後又在360市場下載專門安裝谷歌服務的App,結果這些谷歌服務安裝器無一例外,全部安裝失敗,其結果就是不停的彈框報錯,谷歌服務已停止執行。後來在下面這個地方知道了OpenGapps,這才瞭解了正確的安裝姿勢:

雖然OpenGapps可以直接開啟,但是下載OpenGapps卻要翻&牆,博主下了4、5次,下著下著就沒有速度了,有一次下載到99%就卡住了,實在不行放棄了,到OpenGapps的貼吧去下了一個別人上傳到網盤的版本,解決問題。

接著刷入,然而,並不是一開始就成功了,刷完AOSP,解決完sim卡的問題,再來刷入OpenGapps,結果一開機就報錯,說無法啟動配置嚮導,然後不停的彈窗,無法忍受,接著百度,在機鋒論壇看到別人的帖子,才知道刷完ROM,也就是我們編的AOSP後要馬上刷入OpenGapps,不能開機,否則就會不停的彈窗報錯。然而刷完之後,還是不停彈窗報谷歌服務已停止,再百度一下,給谷歌服務開啟所有許可權,世界就平靜了,終於成功了。

(6) 刷機的問題
刷機的水真是深啊,各種知識,各種概念,各種術語,什麼卡刷,線刷,解鎖,救磚,oem鎖,bootloader鎖,進recovery,雙清,OTA升級,xposed,綠色守護等,博主補了一個上午,看貼吧、論壇才把這些概念搞懂了。非得要自己動手操作,才能體會這些東西。

15 總結

紙上得來終覺淺,絕知此事要躬行。終於把AOSP從谷歌官網下載、編譯、刷入nexus 6p了,接下來就可以開始定製系統了。
部落格中所有內容都是經過博主親手實踐得來的,轉載請註明出處,謝謝。如果你在實踐中遇到什麼問題,歡迎給我留言。
歡迎關注我的部落格——-梧桐那時雨。

Tips:
如果覺得這篇部落格對你有幫助或者喜歡博主的寫作風格,就關注一下博主或者給博主留個言唄,鼓勵博主創作出更多優質部落格,Thank you.