從零開(kāi)始的內(nèi)核編譯
本教程將基于小米 10S 的內(nèi)核源碼進(jìn)行實(shí)例,其他型號(hào)的手機(jī)請(qǐng)自行尋找內(nèi)核源碼。具體內(nèi)容可以參考我的內(nèi)核編譯項(xiàng)目。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-447194.html
手機(jī)型號(hào)查詢
1. 獲取設(shè)備(手機(jī))代號(hào)
在安卓設(shè)備終端(adb shell
)上執(zhí)行:
getprop | grep device
并尋找?guī)в?ro.xx.device
這一行,里面的內(nèi)容即為你的手機(jī)代號(hào),例如:
# 手機(jī)代號(hào)為 thyme
[ro.product.device]: [thyme]
2. 獲取設(shè)備架構(gòu)
在安卓設(shè)備終端(adb shell
)上執(zhí)行:
uname -m
我的設(shè)備顯示為 aarch64
, 即可判斷我的設(shè)備架構(gòu)為 aarch64
。
3. 獲取設(shè)備內(nèi)核版本
在安卓設(shè)備終端(adb shell
)上執(zhí)行:
uname -r
輸出內(nèi)容的格式為:
- [版本].[補(bǔ)丁版本].[子版本號(hào)]-[內(nèi)核標(biāo)識(shí)]-[提交記錄](méi)
例如我的設(shè)備顯示為 4.19.157-Margatroid-gb1b98c3d4fd0
內(nèi)核源碼獲取
內(nèi)核源碼的一般格式為 [android_]kernel_設(shè)備廠商_cpu/代號(hào)
,例如,小米 10S(thyme)的代號(hào)為 thyme
, CPU 型號(hào)為 sm8250
,生產(chǎn)廠商為 xiaomi
,則搜索格式應(yīng)為下面幾種:
kernel_xiaomi_thyme
kernel_xiaomi_sm8250
android_kernel_xiaomi_thyme
android_kernel_xiaomi_sm8250
以下是我收集的一些小米 10S(thyme)的源碼倉(cāng)庫(kù):
- Lynnrin-Studio/android_kernel_xiaomi_thyme: 這是我目前編譯內(nèi)核所使用的內(nèi)核源碼。
-
UtsavBalar1231/kernel_xiaomi_sm8250: CLO 內(nèi)核升級(jí)為 CAF 標(biāo)簽
LA.UM.9.12.r1-14700-SMxx50
,AOSP 源碼同步上游android-4.19-stable
。 -
WeeAris/RK-KSU-mi-kernel-SM8250: 支持
KernelSU
的 Rohail33/RealKing-kernel-SM8250 分支。 -
Rohail33/RealKing-kernel-SM8250: 基于
LA.UM.9.12.r1-08000-SMxx50.0
標(biāo)簽的內(nèi)核。
當(dāng)然除此之外還有很多源碼,但這些源碼對(duì)于我來(lái)說(shuō)是我前期學(xué)習(xí)的一個(gè)途徑,因此在這里列出給大家。
途徑 | 具體介紹 |
---|---|
各廠商開(kāi)源 |
小米內(nèi)核開(kāi)源 華為開(kāi)源代碼 |
去手機(jī)社區(qū)找源碼 | XDA 論壇 |
獲取編譯工具鏈
強(qiáng)烈推薦您學(xué)習(xí)[內(nèi)核向] 交叉編譯器的選擇以及[白話文版] ClangBuiltLinux Clang 的使用來(lái)學(xué)習(xí)工具鏈的配置。
同時(shí)可以配合 Neutron-Clang 的說(shuō)明文檔來(lái)進(jìn)行編譯參數(shù)配置。
目前比較推薦的幾個(gè)預(yù)編譯工具鏈如下:
工具名稱 | 簡(jiǎn)介 |
---|---|
Neutron-Clang | 這是為內(nèi)核開(kāi)發(fā)構(gòu)建的 LLVM 和 Clang 編譯器工具鏈。構(gòu)建始終是從最新的 LLVM 源代碼而不是穩(wěn)定版本構(gòu)建的, |
阿菌?未霜 Clang/LLVM Toolchain with Binutils | 這是一個(gè)預(yù)構(gòu)建的工具鏈,構(gòu)建始終來(lái)自最新的 LLVM 和 Binutils 源而不是穩(wěn)定版本,因此無(wú)法保證完全的穩(wěn)定性。它是用 Full LTO、PGO 和 BOLT 構(gòu)建的,以盡可能減少編譯時(shí)間。 |
ClangBuiltLinux/tc-build | 類似前兩個(gè)工具,但是這個(gè)工具需要自己在本地從 LLVM 的源碼進(jìn)行構(gòu)建,但編譯時(shí)間較長(zhǎng)。 |
除此之外,一個(gè)比較保險(xiǎn)的方法是從預(yù)編譯內(nèi)核機(jī)器的 /proc/config.gz
提取`,需要對(duì)應(yīng)版本的交叉編譯器以及 Clang,自行選擇合適版本下載即可,通過(guò)這種方式編譯出來(lái)的內(nèi)核一般是不會(huì)存在錯(cuò)誤的。
1. Neutron-Clang 使用介紹
這是為內(nèi)核開(kāi)發(fā)構(gòu)建的 LLVM 和 Clang 編譯器工具鏈。構(gòu)建始終是從最新的 LLVM 源代碼而不是穩(wěn)定版本構(gòu)建的,因此不能保證完全的穩(wěn)定性。目前該編譯鏈工具使用 AntMan
來(lái)同步工具,具體使用方法如下:
mkdir -p "$HOME/toolchains/neutron-clang"
cd "$HOME/toolchains/neutron-clang"
bash <(curl -s "https://raw.githubusercontent.com/Neutron-Toolchains/antman/main/antman") -S
一些更多的 AntMan
命令:
功能 | 對(duì)應(yīng)命令 |
---|---|
同步最新的工具鏈構(gòu)建 |
./antman -S 或 ./antman -S=latest
|
同步特定的工具鏈版本 | ./antman -S=<release tag> |
檢查更新 | ./antman -U |
檢查更新和同步更新 | ./antman -Uy |
同步特定更新 | ./antman -S=<release tag> |
刪除同步構(gòu)建 | ./antman -D |
顯示有關(guān)同步構(gòu)建的信息 | ./antman -I |
同步特定的工具鏈版本 | ./antman -S=<release tag> |
如果需要更多細(xì)節(jié)介紹,請(qǐng)運(yùn)行
./antman --help
獲取。
2. ClangBuiltLinux
如果您想要使用這個(gè)工具鏈的話,那么其中的編譯工具則需要你自行編譯,對(duì)應(yīng)的編譯腳本為 ClangBuiltLinux/tc-build。
誠(chéng)然,自行編譯確實(shí)是一件造輪子且費(fèi)時(shí)費(fèi)力的方法,但是通過(guò)這種方式編譯出來(lái)的工具是最適合您的系統(tǒng)的,不會(huì)發(fā)生其他的編譯中的關(guān)于 glibc
等方面的錯(cuò)誤。
3. 阿菌?未霜 Clang/LLVM Toolchain with Binutils
這是一個(gè)預(yù)構(gòu)建的工具鏈,構(gòu)建始終來(lái)自最新的 LLVM 和 Binutils 源而不是穩(wěn)定版本,因此無(wú)法保證完全的穩(wěn)定性。它是用 Full LTO、PGO 和 BOLT 構(gòu)建的,以盡可能減少編譯時(shí)間。
其編譯鏈工具存儲(chǔ)在:
- GitHub:僅用于發(fā)布預(yù)構(gòu)建的壓縮文件(*.7z)
- Gitea:僅用于存儲(chǔ)預(yù)構(gòu)建的二進(jìn)制文件(Current AR Archive、ELF 64-bit LSB shared object 存儲(chǔ)在 LFS)
編譯腳本編寫
內(nèi)核編譯流程其實(shí)只有兩步:
- 生成對(duì)應(yīng)設(shè)備的配置文件
make <theDefConfig>
- 開(kāi)始編譯內(nèi)核
make
您可以直接執(zhí)行這些指令進(jìn)行編譯(參數(shù)設(shè)置一定要正確),或參考我下面的編譯流程:
1. 設(shè)置編譯鏈環(huán)境
最簡(jiǎn)單的設(shè)置環(huán)境辦法就是將編譯鏈工具的路徑添加到系統(tǒng)路徑中,例如:
export PATH="<absolute/path/to/ur/toolchains>/bin:$PATH"
# 例如,您正在使用 neutron-clang
# export PATH="home/user/toolchains/neutron-clang/bin:$PATH"
# 其中的路徑必須為絕對(duì)路徑
如果您在使用
gcc
,可能還需要將gcc
工具鏈的路徑加入到環(huán)境變量中。
2. 簡(jiǎn)易配置腳本
首先給出一個(gè)最基礎(chǔ)的配置腳本:
#!/bin/bash
args="-j$(nproc --all) \
O=out \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
CC=clang \
CROSS_COMPILE_COMPAT=arm-linux-gnueabi- "
make ${args} <config name>
make ${args}
該腳本是在使用上一節(jié)的三個(gè)工具時(shí)才可以正常使用的,如果您使用其他工具可以需要進(jìn)行其他配置。
下面是一些參數(shù)對(duì)應(yīng)的說(shuō)明:
參數(shù) | 說(shuō)明 | 一般參數(shù) |
---|---|---|
CC |
指定使用的編譯器,因?yàn)?make 默認(rèn)使用 gcc ,因此實(shí)際上只有你在使用 clang 進(jìn)行編譯的時(shí)候才會(huì)使用該參數(shù) |
clang |
CROSS_COMPILE |
您的主要交叉編譯鏈工具,如果你在使用谷歌的 gcc 4.9,請(qǐng)指定參數(shù)為 aarch64-linux-android- ,32 位同理 |
aarch64-linux-gnu- |
CLANG_TRIPLE |
只在使用 clang 進(jìn)行編譯的時(shí)候才需要使用,用于指定當(dāng) clang 不生效時(shí)候使用的工具鏈,但在使用上一節(jié)我們提到的工具中基本不用設(shè)置該參數(shù) |
aarch64-linux-gnu- |
CROSS_COMPILE_ARM32 |
只在編譯 32 位內(nèi)核或者帶 vdso 補(bǔ)丁的內(nèi)核時(shí)需要指定該參數(shù) | arm-linux-gnueabi- |
CROSS_COMPILE_COMPAT |
類似于參數(shù) CROSS_COMPILE_ARM32 ,但內(nèi)核版本為 4.19 及更新版本應(yīng)使用本參數(shù)而非 CROSS_COMPILE_ARM32
|
arm-linux-gnueabi- |
更多參數(shù)介紹可以參考一下 Neutron-Clang 的編譯說(shuō)明,里面對(duì)于一些參數(shù)的說(shuō)明比較詳細(xì)。
正常情況下,clang 是無(wú)法獨(dú)立完成內(nèi)核編譯的,需要 gcc 的輔助。但使用上一節(jié)介紹的幾種工具并不需要并不需要單獨(dú)指定
gcc
來(lái)輔助編譯。
3. 部分參考腳本
- DogDayAndroid/KSU_Thyme_BuildBot:我自己編譯的內(nèi)核使用的本地編譯腳本。
- UtsavBalar1231/Drone-scripts:一個(gè)很多人使用的編譯腳本,我的部分代碼也是參考自這里。
- EndCredits/kernel_xiaomi_sm7250:同樣的一個(gè)編譯腳本,但并未提供編譯鏈,但是其中的腳本流程我也有參考。
-
xiaoleGun/KernelSU_Action:
KernelSU
的編譯腳本,同樣有參考。
制作刷機(jī)包鏡像
內(nèi)核編譯完成后的打包請(qǐng)參考文章[內(nèi)核向] 論如何優(yōu)雅的刷入內(nèi)核,目前最流行的方法是使用 osm0sis/AnyKernel3 來(lái)完成整個(gè)內(nèi)核的打包刷入工作。
如果您更喜歡自己動(dòng)手,那么請(qǐng)參考文章內(nèi)的其他方法。
值得注意的是,不同版本的內(nèi)核編譯出來(lái)的內(nèi)容并不相同,因此需要區(qū)分他們之間的打包,詳情請(qǐng)參考文章:關(guān)于 Image.xx-dtb 和 Image.xx + dtb 的區(qū)別。
來(lái)自文章的評(píng)論區(qū):_對(duì)應(yīng)芯片組的。比如 865 只需要 kona-v2.1.dtb。如果弄不清楚,可以使用 cat 命令將多個(gè) dtb 連接在一起,bootloader 會(huì)自動(dòng)識(shí)別。
編譯常見(jiàn)問(wèn)題
本教程將基于小米 10S 的內(nèi)核源碼進(jìn)行實(shí)例,其他型號(hào)的手機(jī)請(qǐng)自行尋找內(nèi)核源碼。具體內(nèi)容可以參考我的內(nèi)核編譯項(xiàng)目。
1. -Werror=implicit-int
/arch/arm64/kernel/smp.c:834:8: error: type defaults to ‘int’ in declaration of ‘in_long_press’ [-Werror=implicit-int]
您可以修改 extern in_long_press
為 extern int in_long_press
;或者去除MakeFile 中對(duì)應(yīng)錯(cuò)誤限制。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-447194.html
參考
- 自己編譯定制一個(gè)牛逼的安卓?jī)?nèi)核
- 讓 Android 手機(jī)更省電流暢,你可以試試「刷內(nèi)核」
- [內(nèi)核向] 交叉編譯器的選擇
- [白話文版] ClangBuiltLinux Clang 的使用
- Neutron-clang 的編譯說(shuō)明
- [內(nèi)核向] 論如何優(yōu)雅的刷入內(nèi)核
到了這里,關(guān)于[Android]從零開(kāi)始的內(nèi)核編譯的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!