如何編譯AOSP內核Kernel並整合進AOSP (Android P/Pixel 2)
本文指引Android平台開發者如何取得Android官方 (AOSP)釋出的Kernel進行編譯(Build)並且刷入實機驗證。
接下來我們要完成以下項目:
最新的Android官方內核編譯已不需要先把AOSP編譯完成(甚至不用刷機)就可以編譯內核並且由新編譯的內核利用fastboot boot的命令直接用來開機。
目前(2019/4/15)Android官方內核Kernel的原始碼釋出方式有了重大改變,看起來是為了支持更多的內核組態。Kernel的原始碼釋出不再只是使用一個Git Project做管理,而是以一個Android Repo來進行多個Project管理。所以取得AOSP Kernel有點類似取得整個AOSP的流程。
Android官網的說明:https://source.android.com/setup/build/building-kernels#id-version
從官網可以看出,我們要拿的內核Repo branch版本為android-msm-wahoo-4.4-pie-qpr2
首先取得AOSP Kernel for Pixel 2
取得原始碼後,在此原始碼根目錄下可以列出以下目錄及一個連結檔:
所以以前的AOSP內核編譯需要先把AOSP環境架設好,然後內核的編譯才能「依附」其下。現在的內核編譯採用了「自給自足」模式。
再來進行編譯AOSP內核 (build AOSP Kernel),取得後在原始碼目錄下,直接執行以下命令
最後會將Kernel編譯完成,編譯過程中輸出的編譯訊息文字:
最後一行Files copied to ~,就是輸出核心映像(Kernel Image)的位置,到該目錄下,列出檔案:
Android提供「不刷機測試核心」的功能,好處就是如果改壞Kernel了,重開機後(一般是長按Power Key 15秒),就能回復原有的Kernel核心,這也降低了把手機刷壞的機率(理論上目前的手機要刷壞到無法重刷那也不容易)。不刷機直接從新編譯的核心開機命令如下,先將目錄轉換至核心輸出目錄,out/android-msm-wahoo-4.4/dist,執行:
之後手機就直接由新編譯的核心開機,為了確認這件事,開機後用adb檢視開機的核心Log:
可以從以上Log的時間 (Apr 15 11:55:46 CST 2019) 看出,內核是由新編譯出來。
如果你要將內核及AOSP分別管理,在編譯完成內核後,從內核輸出目錄,將以下檔案複製到AOSP原始碼Codebase下(編譯AOSP的完整引導可以參考:完整指引如何編譯AOSP (Android P),整合GMS及刷機),再進行AOSP編譯即可。
例如你的內核編譯完成,輸出在/aosp-kernel/out/android-msm-wahoo-4.4/dist,而AOSP目錄在/aosp下,則執行複製命令:
再進入AOSP的目錄下,執行envsetup.sh及lunch後,再make,就能完整編譯出可刷機的自製AOSP + Kernel版本。
如果要管理自身內核的更動,包含原始碼審視(Code Review),就必須將內核專案納入Gerrit Server/AOSP。若你已經建立一個Gerrit Server可以管理AOSP代碼庫,則你可以將內核也一併整合進該代碼庫。(若是還沒有自有的AOSP Gerrit Server,請參考 架設AOSP Gerrit Server)
以下是快速命令來建立Kernel內核專案納入本地的Gerrit Server進行管理。以下命令假設你的環境為:
步驟一:取得內核Git鏡射 (git mirror)
步驟二:將內核代碼庫推入(push)Gerrit Server
Android官方內核代碼庫包含了七個專案,我們只需其中兩個:kernel/build及kernel/msm。
因為其他五個不是必要,有些和AOSP代碼庫的專案是重複的,所以排除。
步驟三:把內核專案加入AOSP代碼庫
目前只是把內核代碼庫加入Gerrit Server,所以還必須在AOSP代碼庫中加入內核專案。
首先在AOSP的.repo/manifests/default.xml加入內核專案。
然後在.repo/manifests目錄下,更新default.xml推上Gerrit Server。
步驟四:修改內核編譯環境
配合整個AOSP編譯環境,我們把內核原始碼放在kernel/private/msm,把內核編譯命令放在kernel/build。
接下來改變以下kernel/build/private/msm/build.config來符合AOSP的編譯環境:
第8,9行的改變是改變分枝名稱。第10行加入DIST_DIR把原本AOSP的預載內核覆蓋成自行編譯的內核。第17,18行是指向內核原始碼,第20~31行是把編譯工具指向AOSP的編譯工具(GCC及Clang等等)。
步驟五:編譯內核及編譯完整AOSP
最後重新進行編譯,我們分為兩部份,所編譯內核,再編譯AOSP
進入kernel目錄,編譯內核
完成後,新的內核映像檔及其他內核模組會自動產生在device/google/wahoo-kernel下, 再回到AOSP根目錄,重新編譯AOSP,完成後利用fastboot flashall刷機。
完成後就可以把內核的原始碼也納入Gerrit Server管理,並且和AOSP整成一包完整的代碼庫,包含AOSP,GMS及Kernel。
kernel/private/msm/arch/arm64/configs/wahoo_defconfig
找到後編輯加入一個SYSVPIC設定
儲存後重新編輯內核會發生錯誤,這是AOSP內核編輯系統的設定,主要是不讓你因變更預設的內核組態而造成Android系統的問題。AOSP官方有規定必須加入的CONFIG及不可加入的CONFIG。這些可以從kernel/config/README.md仔細去看,這裏我們先省略檢查相容性的部份,可以將kernel/private/msm/build.config中的POST_DEFCONFIG_CMDS='check_defconfig'改為空字串
如此即可跳過相容性檢查,再重新執行一次Kernel Build就能成功編譯。但使用到不相容的CONFIG是有風險的,以SYSVIPC來說其風險在以下官方連結有詳細說明。
https://android.googlesource.com/platform/ndk/+/4e159d95ebf23b5f72bb707b0cb1518ef96b3d03/docs/system/libc/SYSV-IPC.TXT
接下來我們要完成以下項目:
- 取得Android官方釋出的Pixel 2 (Walleye) Kernel。(Android 9.0/Pie)
- 編譯核心Linux Kernel
- 刷入Pixel 2實機 (以下步驟對於其他Google Pixel系列手機也適用。)
- 整合AOSP及內核代碼庫
編譯AOSP
編譯AOSP的完整引導可以參考:完整指引如何編譯AOSP (Android P),整合GMS及刷機最新的Android官方內核編譯已不需要先把AOSP編譯完成(甚至不用刷機)就可以編譯內核並且由新編譯的內核利用fastboot boot的命令直接用來開機。
取得AOSP Kernel
目前(2019/4/15)Android官方內核Kernel的原始碼釋出方式有了重大改變,看起來是為了支持更多的內核組態。Kernel的原始碼釋出不再只是使用一個Git Project做管理,而是以一個Android Repo來進行多個Project管理。所以取得AOSP Kernel有點類似取得整個AOSP的流程。
Android官網的說明:https://source.android.com/setup/build/building-kernels#id-version
![]() |
在Android官網中,說明Pixel2的對映版本為android-msm-wahoo-4.4-pie-qpr2 |
首先取得AOSP Kernel for Pixel 2
取得原始碼後,在此原始碼根目錄下可以列出以下目錄及一個連結檔:
- build => 編譯命令及環境設定腳本
- build.config => 編譯設定組態檔
- kernel => 內核測試工具
- prebuilts => 內核編譯工具 (Cross Compiler/GCC)
- prebuilts-master => 內核編譯工具 (Clang)
- private => 內核原始碼
- .repo => repo管理目錄
所以以前的AOSP內核編譯需要先把AOSP環境架設好,然後內核的編譯才能「依附」其下。現在的內核編譯採用了「自給自足」模式。
編譯AOSP內核
再來進行編譯AOSP內核 (build AOSP Kernel),取得後在原始碼目錄下,直接執行以下命令
最後會將Kernel編譯完成,編譯過程中輸出的編譯訊息文字:
最後一行Files copied to ~,就是輸出核心映像(Kernel Image)的位置,到該目錄下,列出檔案:
![]() |
AOSP Kernel核心編譯完成的輸出檔案 |
測試AOSP Kernel內核
Android提供「不刷機測試核心」的功能,好處就是如果改壞Kernel了,重開機後(一般是長按Power Key 15秒),就能回復原有的Kernel核心,這也降低了把手機刷壞的機率(理論上目前的手機要刷壞到無法重刷那也不容易)。不刷機直接從新編譯的核心開機命令如下,先將目錄轉換至核心輸出目錄,out/android-msm-wahoo-4.4/dist,執行:
之後手機就直接由新編譯的核心開機,為了確認這件事,開機後用adb檢視開機的核心Log:
可以從以上Log的時間 (Apr 15 11:55:46 CST 2019) 看出,內核是由新編譯出來。
整合進AOSP
整合的意思即是將內核編譯後,納入AOSP編譯,編譯AOSP完成後,其內核映像檔(boot.img)即是自行編譯的內核。選擇1:簡易整合
如果你要將內核及AOSP分別管理,在編譯完成內核後,從內核輸出目錄,將以下檔案複製到AOSP原始碼Codebase下(編譯AOSP的完整引導可以參考:完整指引如何編譯AOSP (Android P),整合GMS及刷機),再進行AOSP編譯即可。
例如你的內核編譯完成,輸出在/aosp-kernel/out/android-msm-wahoo-4.4/dist,而AOSP目錄在/aosp下,則執行複製命令:
再進入AOSP的目錄下,執行envsetup.sh及lunch後,再make,就能完整編譯出可刷機的自製AOSP + Kernel版本。
選擇2:完整原始碼Codebase整合
如果要管理自身內核的更動,包含原始碼審視(Code Review),就必須將內核專案納入Gerrit Server/AOSP。若你已經建立一個Gerrit Server可以管理AOSP代碼庫,則你可以將內核也一併整合進該代碼庫。(若是還沒有自有的AOSP Gerrit Server,請參考 架設AOSP Gerrit Server)
以下是快速命令來建立Kernel內核專案納入本地的Gerrit Server進行管理。以下命令假設你的環境為:
- Gerrit Server IP: 10.50.100.56,
- 使用者:jeremychen,
- 管理者群組:android-admin
- 父專案:AOSP,
- 自有AOSP Branch分枝為:my_android-9
步驟一:取得內核Git鏡射 (git mirror)
步驟二:將內核代碼庫推入(push)Gerrit Server
Android官方內核代碼庫包含了七個專案,我們只需其中兩個:kernel/build及kernel/msm。
因為其他五個不是必要,有些和AOSP代碼庫的專案是重複的,所以排除。
步驟三:把內核專案加入AOSP代碼庫
目前只是把內核代碼庫加入Gerrit Server,所以還必須在AOSP代碼庫中加入內核專案。
首先在AOSP的.repo/manifests/default.xml加入內核專案。
然後在.repo/manifests目錄下,更新default.xml推上Gerrit Server。
步驟四:修改內核編譯環境
配合整個AOSP編譯環境,我們把內核原始碼放在kernel/private/msm,把內核編譯命令放在kernel/build。
接下來改變以下kernel/build/private/msm/build.config來符合AOSP的編譯環境:
第8,9行的改變是改變分枝名稱。第10行加入DIST_DIR把原本AOSP的預載內核覆蓋成自行編譯的內核。第17,18行是指向內核原始碼,第20~31行是把編譯工具指向AOSP的編譯工具(GCC及Clang等等)。
步驟五:編譯內核及編譯完整AOSP
最後重新進行編譯,我們分為兩部份,所編譯內核,再編譯AOSP
進入kernel目錄,編譯內核
完成後,新的內核映像檔及其他內核模組會自動產生在device/google/wahoo-kernel下, 再回到AOSP根目錄,重新編譯AOSP,完成後利用fastboot flashall刷機。
完成後就可以把內核的原始碼也納入Gerrit Server管理,並且和AOSP整成一包完整的代碼庫,包含AOSP,GMS及Kernel。
修改Kernel Config(內核組態)
修改Kernel Config要先找到內核的Config檔案位置。在kernel/build/private/msm/build.config中,定義了變數DEFCONFIG=wahoo_defconfig,這就是Kernel Config的檔案名稱。而實際的位置目錄根據Linux Kernel的規則是放在Kernel根目錄下的arch/<ARCH>/configs。Kernel根目錄我們放在kernel/private/msm而Pixel2的架構為ARM64,所以其組態位置在kernel/private/msm/arch/arm64/configs/wahoo_defconfig
找到後編輯加入一個SYSVPIC設定
儲存後重新編輯內核會發生錯誤,這是AOSP內核編輯系統的設定,主要是不讓你因變更預設的內核組態而造成Android系統的問題。AOSP官方有規定必須加入的CONFIG及不可加入的CONFIG。這些可以從kernel/config/README.md仔細去看,這裏我們先省略檢查相容性的部份,可以將kernel/private/msm/build.config中的POST_DEFCONFIG_CMDS='check_defconfig'改為空字串
如此即可跳過相容性檢查,再重新執行一次Kernel Build就能成功編譯。但使用到不相容的CONFIG是有風險的,以SYSVIPC來說其風險在以下官方連結有詳細說明。
https://android.googlesource.com/platform/ndk/+/4e159d95ebf23b5f72bb707b0cb1518ef96b3d03/docs/system/libc/SYSV-IPC.TXT
謝謝分享整個程序。不過我有兩個問題請教,第一是下載完後編譯,你會先下"sh build/envsetup.sh",然而程式會顯示此方法已經不再使用,只需要進行"build/build.sh" 即可。第二個問題是我在驗證 android-msm-marlin-3.18-pie-qpr2,編譯無法成功,卡在 build_config 裡的一個命令:python build/buildinfo/buildinfo.py,因為檔案 buildinfo/buildinfo.py 並不存在,所以就編譯失敗,因為 Google 上找不到類似的問題與解決方式,想請教你這邊是否有經驗。Thanks.
回覆刪除你好,我按照文章内步驟編譯並成功flash了内核,發現觸屏功能失效。。。不知道什麽原因導致的
回覆刪除我也碰到触屏失效的问题,请问你解决了吗?
刪除作者已經移除這則留言。
刪除我也遇到相同的問題解決了。可以用滑鼠點進去系統看,是因為核心版本跟原本不一致所導致的。重抓核心版本一致的用就行了!
刪除