快轉到主要內容

獨立編譯Android kernel(核心),以小米手機為例

分類   智慧型手機 Root與刷機
標籤   Android Linux Kernel
🗓️ 民國111年 壬寅年
✍ 切換正體/簡體字
目錄

本文簡述如何自行修改Android kernel,開啟特定的功能,再重新編譯檔案,將其刷入手機。

不同廠牌手機的作法不一樣,本文以小米當例子,從原始碼樹外(out of source tree)編譯kernel。

先從簡單的開始: 刷入自己修改過的kernel後,會在手機設定→關於→核心版本顯示自己的名字。

如果成功了,那麼就能更進一步去調kernel的功能,例如把docker要求的功能全部打開,就能 在Android手機跑docker

1. 硬體需求
#

要刷kernel,手機必定已經解鎖bootloader。刷kernel不會重置手機資料,所以刷之前只要備份boot分區,避免卡開機。

本文使用的手機是紅米Note 5 (whyred),系統為LineageOS 18。

編譯kernel需要一台x86-64位元的Linux電腦。我的電腦規格: Intel Core 2 Q9550 + 4GB DDR2 RAM。作業系統為Lubuntu 20.04。

2. 步驟概述
#

編譯kernel包含除錯可能會花至少一天的時間,修改程式需要對C語言有深入了解。由於每支手機kernel的編譯器和需要的patch不盡相同,在此只講最基礎的方法。

首先下載kernel原始碼 → 設定交叉編譯器(在x86上編譯ARM) → 簡單加上名字後第一次編譯 → 刷入手機看功能正不正常 → 修改kernel功能 → 再次編譯 → 刷入到手機

我們會在Linux電腦桌面建立一個叫做customkernel的目錄當作工作目錄。在第5步開始編譯前裡面大概長這樣:

接著安裝以下套件

sudo apt update
sudo apt install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev \
gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev \
x11proto-core-dev libx11-dev lib32z-dev libgl1-mesa-dev \
libxml2-utils xsltproc unzip bc

3. 取得kernel原始碼
#

原廠的kernel或第三方kernel都可以,通常會把原始碼放在Github。

這裡我以有很多額外功能的”RAD Kernel”專案做示範,這個專案程式碼問題比較少。

到他們的Github,clone原始碼。

git clone https://github.com/radcolor/android_kernel_xiaomi_whyred.git

為了方便識別,將clone下來的目錄重新命名為”src”。

4. 設定交叉編譯器
#

再次提醒:不同廠牌手機kernel使用的編譯器不見得相同,有些甚至要用舊版GCC才編譯的過。

在Google改用Clang後,XDA仍有開發者持續提供最新版的GCC編譯器,也就是本文使用的"EVA GCC"。

XDA下載ARM與ARM64的版本(點選direct download下載)

將下載的arm版本解壓縮,命名為"tc32"。再將aarch64版本解壓縮,命名為"tc"。

將這二個目錄移動到"customkernel",到目前為止目錄長這樣,src是kerenl原始碼的目錄,tc和tc32則是剛剛下載的交叉編譯器。

5. 第一次測試編譯
#

  1. 進入src目錄,在這裡開啟終端機。先export環境變數,指向編譯器的所在位置:
#以下分別對應tc和tc32所在的目錄,以及檔案名稱前綴
export CROSS_COMPILE=/home/ivon/Desktop/customkernel/tc/bin/aarch64-elf-
export CROSS_COMPILE_ARM32=/home/ivon/Desktop/customkernel/tc32/bin/arm-eabi-
export ARCH=arm64
  1. 清理kernel原始碼目錄
make clean
make mrproper
  1. 按照機型_config檔案產生kernel設定檔,該檔案通常在arch/arm64/configs
make whyred_defconfig
#輸出: configuration written to .config
  1. 開啟src目錄的MakeFile,在EXTRAVERSION後面加入自己名字的字串:

  2. 接著開始編譯kernel。-j後面加的數字通常是CPU核心數的二倍。

make -j8
  1. 4核心的Intel Q9550編譯至少要20分鐘,若遇到error編譯器就會停下來,要去改程式碼、上網找patch,再重新make,編譯器會從上個中止的地方繼續。

  2. 編譯好的檔案位於arch/arm64/boot/,應該會有一個Image.gz-dtb的檔案。

  3. 接著要重新打包boot.img,把原廠的boot.img解開之後把我們做的kernel塞進去。先到 XDA下載Linux版Android Image Kitchen (點選文中的AIK-Linux-v3.8-ALL.tar.gz附件),解壓縮。

  4. 手機進入TWRP → Advanced → Terminal,使用dd指令從手機提取原廠的boot.img。

dd if=/dev/block/bootdevice/by-name/boot of=/sdcard/stockboot.img
  1. 把這個原廠的stockboot.img檔案傳輸到電腦,放到AIK的工作目錄,並將剛剛編譯的Image.gz-dtb也放到這個目錄。

  2. 在AIK目錄開啟終端機,使用指令解開stockboot.img(需要sudo)

./unpackimg.sh stockboot.img
  1. 進入目錄split_img,把stockboot.img-kernel檔案替換成我們編譯好的Image.gz-dtb,檔名也改成stockboot.img-kernel

  2. 回到AIK目錄,重新打包:

./repackimg.sh
  1. 應該會得到一個image-new.img的檔案。

6. 刷入到手機
#

將新的image-new.img傳輸到手機,用TWRP點選Install Image,刷入到boot分區。

接著就是看看能不能開機了…若卡開機,還原TWRP的boot分區備份,繼續在電腦上debug吧…

7. menuconfig開關kernel功能
#

如果前六個步驟成功完成,那就來真正修改kernel吧。

  1. 在src目錄開啟終端機,輸入指令開啟kconfig選單,用於開關kernel的功能。
make menuconfig
  1. 使用鍵盤上下和Enter進入子選項。找到要開啟的項目按下y,然後用鍵盤左右鍵移動到Save儲存設定值。

  2. 改好後切換到Exit退出,寫入變更,再次開始編譯kernel:

make -j8
  1. 接著重複第5步的步驟,編譯成功後把kernel打包,刷到手機測試。

8. 參考資料
#

感謝fossfrog的影片清楚地解釋如何製作kernel: Build Your Own Android Custom Kernel | fossfrog

這篇文章有講解LineageOS編譯kernel的注意事項: Building LineageOS kernel trees from source

相關文章

[Root] Termux:以原生效能在Android手機上跑Docker (紅米Note 5)
分類   智慧型手機 Root與刷機
標籤   Termux Android Linux Kernel Docker Xiaomi
[Root] Linux Deploy chroot環境安装Box86 Wine + Box64 Wine64
分類   智慧型手機 Root與刷機
標籤   Linux Deploy Box86 Box64 Wine
免Root將Android手機去Google化
分類   智慧型手機 Root與刷機
標籤   Degoogle MicroG

留言板

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要Github帳號才能留言。支援markdown語法,若要上傳圖片請貼Imgur連結。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus強制投放的廣告。有時留言可能會被系統判定需審核,導致延遲顯示,請見諒。