戰(zhàn):從環(huán)境搭建到鏡像燒錄)
1. 項(xiàng)目概述為什么高通8155平臺的開源代碼如此重要最近有不少做車機(jī)系統(tǒng)開發(fā)的朋友在后臺問我有沒有高通8155平臺最新的開源代碼和編譯方法。這確實(shí)是個好問題也是當(dāng)前智能座艙開發(fā)領(lǐng)域的一個核心痛點(diǎn)。高通驍龍8155芯片作為第三代驍龍汽車數(shù)字座艙平臺的主力幾乎成了中高端智能汽車的“標(biāo)配”大腦。從理想、小鵬到蔚來再到傳統(tǒng)車企的新能源車型你都能看到它的身影。對于開發(fā)者而言拿到這塊芯片對應(yīng)的開源代碼意味著你能真正深入底層去定制啟動引導(dǎo)程序、內(nèi)核驅(qū)動甚至是系統(tǒng)服務(wù)。這不僅僅是技術(shù)探索更是實(shí)現(xiàn)差異化功能、優(yōu)化性能、解決特定硬件兼容性問題的關(guān)鍵。比如你想為自家車型的8155平臺增加一個獨(dú)特的開機(jī)動畫或者優(yōu)化某個外設(shè)如特定型號的攝像頭或麥克風(fēng)的驅(qū)動性能沒有底層代碼的支持幾乎是寸步難行。然而高通平臺的代碼獲取和編譯環(huán)境搭建歷來以“門檻高、資料散、坑點(diǎn)多”著稱。官方文檔往往面向大型OEM客戶對獨(dú)立開發(fā)者或小團(tuán)隊(duì)不夠友好。網(wǎng)上的資料又新舊混雜用著老版本的代碼去配新版本的工具鏈編譯報錯能讓人排查到懷疑人生。今天我就結(jié)合自己最近一次成功拉取和編譯8155平臺AOSPAndroid Open Source Project底層代碼的實(shí)際經(jīng)歷把整個流程、關(guān)鍵配置和踩過的那些“坑”系統(tǒng)地梳理出來。目標(biāo)就一個讓你能對照著這份指南在Linux環(huán)境下把代碼下下來、環(huán)境配起來、鏡像編出來。2. 環(huán)境準(zhǔn)備與關(guān)鍵概念澄清在動手之前我們必須把幾個關(guān)鍵概念和準(zhǔn)備工作理清楚這能避免后續(xù)90%的困惑。2.1 理解“開源代碼”的范疇BSP與AOSP當(dāng)我們說“高通8155平臺開源代碼”時通常指的是兩個部分的組合高通提供的BSPBoard Support Package這是芯片原廠提供的、與具體硬件平臺強(qiáng)相關(guān)的代碼包。它包括Bootloader如U-Boot或高通專用的ABL負(fù)責(zé)硬件初始化、加載內(nèi)核。內(nèi)核Kernel經(jīng)過高通深度定制和優(yōu)化的Linux內(nèi)核包含了8155芯片所有外設(shè)GPU、DSP、ISP、音頻編解碼器、各種總線接口等的驅(qū)動。廠商閉源組件Proprietary Blobs一些涉及核心IP或協(xié)議的二進(jìn)制庫文件比如圖形庫、DSP固件、基帶相關(guān)模塊等。這部分不開源但編譯時需要。谷歌的AOSPAndroid Open Source Project這是Android系統(tǒng)的開源主體包含了系統(tǒng)框架、原生應(yīng)用、系統(tǒng)服務(wù)等。對于8155這樣的車規(guī)級平臺高通通常會提供一個基于特定Android版本的BSP參考代碼。我們的工作就是將高通的BSP代碼與對應(yīng)版本的AOSP代碼進(jìn)行整合與編譯。注意高通代碼的獲取通常需要與高通簽訂協(xié)議并獲得訪問權(quán)限訪問CodeAurora Forum 現(xiàn)已遷移至 高通開發(fā)者網(wǎng)絡(luò) 的特定區(qū)域。本文假設(shè)你已具備合法的獲取途徑重點(diǎn)講解獲取后的編譯方法。公開渠道無法直接下載完整的專有BSP。2.2 編譯主機(jī)環(huán)境搭建一個純凈、高效的Linux編譯環(huán)境是成功的第一步。我強(qiáng)烈推薦使用Ubuntu 20.04 LTS這是Android官方長期兼容的版本社區(qū)資源也最豐富。基礎(chǔ)系統(tǒng)配置# 更新系統(tǒng)并安裝基礎(chǔ)編譯工具 sudo apt update sudo apt upgrade -y sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig python3 # 安裝Repo工具谷歌用于管理AOSP倉庫的工具 mkdir -p ~/.bin curl https://storage.googleapis.com/git-repo-downloads/repo ~/.bin/repo chmod arx ~/.bin/repo # 將 ~/.bin 加入PATH環(huán)境變量如果尚未加入 echo export PATH$HOME/.bin:$PATH ~/.bashrc source ~/.bashrc磁盤空間要求這是新手最容易低估的一點(diǎn)。完整下載8155平臺的AOSPBSP代碼并完成一次完整編譯你需要準(zhǔn)備至少300GB的可用磁盤空間。我建議直接分配500GB以上。代碼倉庫本身大約80-100GB編譯輸出目錄out/在首次編譯時可能會達(dá)到150-200GB。內(nèi)存與CPU編譯過程極其消耗資源。建議主機(jī)擁有至少32GB物理內(nèi)存和8核以上CPU。16GB內(nèi)存可以編譯但可能會頻繁使用Swap導(dǎo)致速度極慢。使用SSD硬盤能顯著提升編譯速度。3. 代碼下載與倉庫同步實(shí)戰(zhàn)環(huán)境就緒后我們進(jìn)入最核心的步驟獲取代碼。這里以高通通常提供的基于Android 12S的8155 BSP為例。3.1 初始化AOSP主干代碼首先我們需要拉取對應(yīng)版本的AOSP主干代碼。高通BSP通常會指定一個具體的AOSP版本和分支。# 1. 創(chuàng)建一個工作目錄并進(jìn)入 mkdir -p ~/aosp_sa8155_android12 cd ~/aosp_sa8155_android12 # 2. 初始化Repo倉庫指定分支。這里以 android-12.1.0_r27一個常見的Tag為例。 # -b 指定分支--depth1 只拉取最新提交節(jié)省時間和空間。 repo init -u https://android.googlesource.com/platform/manifest -b android-12.1.0_r27 --depth1 # 3. 同步代碼庫。這是一個漫長的過程取決于你的網(wǎng)絡(luò)速度可能需要數(shù)小時。 # -j4 表示使用4個線程同步可以根據(jù)你的網(wǎng)絡(luò)和CPU調(diào)整如 -j8。 repo sync -c --no-tags --no-clone-bundle -j4實(shí)操心得repo sync過程極易因網(wǎng)絡(luò)問題中斷。建議使用穩(wěn)定的網(wǎng)絡(luò)并可以編寫一個簡單的重試腳本。如果中斷重新執(zhí)行repo sync即可Repo工具支持?jǐn)帱c(diǎn)續(xù)傳。3.2 集成高通BSP代碼包AOSP主干代碼拉取完成后你的目錄里還缺少高通硬件相關(guān)的代碼。這時你需要將高通提供的BSP代碼包集成進(jìn)來。高通通常會提供一個manifest XML文件和一個vendor補(bǔ)丁包。假設(shè)你獲得的BSP包解壓后有一個qcom-manifest.xml和一個vendor_qcom的目錄。# 1. 將高通的manifest文件復(fù)制到 .repo/local_manifests/ 目錄下 # 如果沒有這個目錄就創(chuàng)建它。 mkdir -p .repo/local_manifests cp /path/to/your/bsp/qcom-manifest.xml .repo/local_manifests/ # 2. 再次執(zhí)行 repo sync這次會拉取高通特定的硬件倉庫如 kernel/msm, vendor/qcom 等。 repo sync -c --no-tags --no-clone-bundle -j4 # 3. 應(yīng)用高通提供的vendor補(bǔ)丁如果有的話。 # 通常BSP包里會有一個腳本比如 apply_patches.sh運(yùn)行它即可。 cd /path/to/your/bsp ./apply_patches.sh ~/aosp_sa8155_android12關(guān)鍵點(diǎn)解析.repo/local_manifests/目錄下的XML文件擁有最高優(yōu)先級它會覆蓋或補(bǔ)充主manifest中的項(xiàng)目定義。通過這種方式高通將其私有的硬件代碼倉庫“注入”到了你的AOSP代碼樹中。3.3 驗(yàn)證代碼樹結(jié)構(gòu)同步完成后你的代碼樹應(yīng)該包含以下關(guān)鍵目錄device/qcom/高通平臺設(shè)備相關(guān)的配置特別是device/qcom/sa8155/或類似目錄這里存放著8155特定設(shè)備的編譯配置、啟動腳本、分區(qū)表等。kernel/msm-5.4/或kernel/msm-5.10/高通定制化的Linux內(nèi)核源代碼。vendor/qcom/包含大量的閉源二進(jìn)制庫和頭文件。hardware/qcom/高通硬件抽象層HAL的實(shí)現(xiàn)。使用ls -la檢查這些目錄是否存在是驗(yàn)證代碼下載是否成功的第一步。4. 編譯配置與構(gòu)建過程詳解代碼到位接下來就是配置和編譯。這是最考驗(yàn)?zāi)托暮图?xì)心的環(huán)節(jié)。4.1 構(gòu)建環(huán)境初始化AOSP使用source和lunch命令來初始化編譯環(huán)境。# 1. 進(jìn)入代碼根目錄 cd ~/aosp_sa8155_android12 # 2. 導(dǎo)入編譯環(huán)境變量和命令 source build/envsetup.sh # 3. 選擇編譯目標(biāo)。這是最關(guān)鍵的一步 lunch執(zhí)行l(wèi)unch后會列出一個菜單。對于8155平臺目標(biāo)通常包含sa8155字樣。例如qssi_sa8155-userdebug這是最常見的用于開發(fā)的版本帶有root調(diào)試權(quán)限。qssi_sa8155-user用戶版本無調(diào)試權(quán)限。sa8155_auto-userdebug可能針對車載IVI車載信息娛樂系統(tǒng)的特定變體。我們選擇qssi_sa8155-userdebug輸入對應(yīng)的編號或全名。4.2 理解QSSIQualcomm Single System Image這里出現(xiàn)了一個重要概念QSSI。這是高通在Android 10之后引入的架構(gòu)旨在將系統(tǒng)鏡像System Image和供應(yīng)商鏡像Vendor Image分離編譯。qssi目標(biāo)編譯出的system.img是通用的可以與不同硬件平臺的vendor.img組合。這提升了系統(tǒng)通用性和OTA效率。對于開發(fā)者我們通常需要同時編譯qssi目標(biāo)和具體的設(shè)備目標(biāo)。4.3 開始編譯配置完成后使用mmake的封裝命令開始編譯。首次編譯耗時極長在32核64GB內(nèi)存的機(jī)器上可能也需要2-4小時。# 使用 -j 參數(shù)指定并行編譯任務(wù)數(shù)通常設(shè)置為CPU核心數(shù)的1-1.5倍。 # 例如對于16核CPU m -j24 # 或者使用全速編譯 m編譯過程會輸出大量日志。你可以重點(diǎn)關(guān)注是否有[ERROR]出現(xiàn)。更常見的是一些[WARNING]通常可以忽略。踩坑實(shí)錄編譯失敗最常見的原因內(nèi)存不足OOM編譯內(nèi)核或某些大型模塊時可能因內(nèi)存不足被系統(tǒng)殺死進(jìn)程。癥狀是編譯突然停止并伴有Killed信息。解決方案是增加Swap空間或增加物理內(nèi)存。# 創(chuàng)建一個32GB的Swap文件如果已有Swap可跳過 sudo fallocate -l 32G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # 永久生效需寫入 /etc/fstabJava版本不匹配Android 12需要OpenJDK 11。確保你的默認(rèn)Java版本正確。sudo apt install openjdk-11-jdk sudo update-alternatives --config java # 選擇Java 11文件系統(tǒng)大小寫敏感在Windows WSL或某些Mac分區(qū)上編譯可能會因?yàn)槲募到y(tǒng)大小寫不敏感導(dǎo)致奇怪錯誤。務(wù)必在Linux原生EXT4分區(qū)上進(jìn)行編譯。BSP與AOSP版本不匹配這是最致命的問題。務(wù)必確認(rèn)你下載的高通BSP manifest文件指定的AOSP分支與你repo init時使用的分支完全一致。4.4 編譯輸出與鏡像文件編譯成功后所有生成的鏡像文件位于out/target/product/sa8155/具體路徑可能因lunch目標(biāo)略有不同。你需要關(guān)注的核心鏡像有boot.img包含內(nèi)核和初始RAM磁盤。system.img系統(tǒng)分區(qū)鏡像。vendor.img供應(yīng)商分區(qū)鏡像。userdata.img用戶數(shù)據(jù)分區(qū)鏡像。super.imgAndroid 10動態(tài)分區(qū)鏡像可能包含了system、vendor、product等的組合。vbmeta.imgAVBAndroid Verified Boot元數(shù)據(jù)鏡像。此外目錄下還會有flashall.batWindows或flashall.shLinux腳本用于一鍵刷機(jī)。但刷機(jī)有風(fēng)險務(wù)必確認(rèn)鏡像與你的開發(fā)板完全匹配。5. 內(nèi)核的單獨(dú)編譯與調(diào)試有時我們只需要修改內(nèi)核驅(qū)動或配置不需要編譯整個Android。高通平臺的內(nèi)核可以單獨(dú)編譯。5.1 配置與編譯獨(dú)立內(nèi)核# 1. 進(jìn)入內(nèi)核源碼目錄 cd ~/aosp_sa8155_android12/kernel/msm-5.4 # 請根據(jù)實(shí)際目錄調(diào)整 # 2. 設(shè)置交叉編譯工具鏈和環(huán)境變量 # AOSP已經(jīng)自帶了工具鏈通常路徑如下 export ARCHarm64 export SUBARCHarm64 export CROSS_COMPILE/path/to/your/aosp/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- # 3. 使用高通提供的默認(rèn)配置 make sa8155-perf_defconfig # 具體defconfig名稱需參考BSP文檔常見的有 sa8155-perf, sa8155_auto 等 # 4. 編譯內(nèi)核 make -j24編譯完成后會在arch/arm64/boot/下生成Image.gz-dtb文件這就是壓縮的內(nèi)核鏡像。5.2 將新內(nèi)核集成到Boot鏡像僅有內(nèi)核文件還不夠需要將其打包成Android可用的boot.img。# 回到AOSP根目錄 cd ~/aosp_sa8155_android12 # 重新初始化環(huán)境如果已初始化可跳過 source build/envsetup.sh lunch qssi_sa8155-userdebug # 使用AOSP的mkbootimg工具重新打包boot.img # 首先將新編譯的內(nèi)核復(fù)制到設(shè)備樹目錄假設(shè)位置 cp kernel/msm-5.4/arch/arm64/boot/Image.gz-dtb device/qcom/sa8155-kernel/ # 然后重新編譯bootimage。這會使用新的內(nèi)核文件。 m bootimage新的boot.img將生成在out/target/product/sa8155/目錄下你可以單獨(dú)刷寫這個鏡像來測試內(nèi)核改動。6. 常見問題排查與解決技巧在實(shí)際操作中你幾乎一定會遇到各種問題。這里我整理了一個速查表涵蓋了最常見的一些錯誤和解決方法。問題現(xiàn)象可能原因排查步驟與解決方案repo sync失敗報錯fatal: unable to access...網(wǎng)絡(luò)問題無法訪問googlesource.com。1. 檢查網(wǎng)絡(luò)連接和代理設(shè)置。2. 嘗試更換國內(nèi)鏡像源如清華源修改repo init的-u參數(shù)為鏡像地址。3. 使用repo sync --no-clone-bundle。lunch菜單中沒有sa8155相關(guān)選項(xiàng)。1. BSP代碼未成功集成。2. 環(huán)境未正確初始化。1. 檢查.repo/local_manifests/下是否有高通的manifest文件。2. 重新執(zhí)行source build/envsetup.sh。3. 檢查device/qcom/目錄下是否存在sa8155子目錄。編譯中途報錯ninja: build stopped: subcommand failed.這是編譯失敗的通用提示需要向上查看具體錯誤。1. 查看錯誤日志的最后幾十行尋找第一個[ERROR]。2. 常見原因依賴缺失、文件沖突、Python/Java版本不對、權(quán)限問題。編譯報錯關(guān)于dex2oat或soong。通常是資源內(nèi)存/磁盤不足。1. 使用free -h和df -h檢查內(nèi)存和磁盤空間。2. 增加Swap空間。3. 嘗試用m -jN減少并行任務(wù)數(shù)N小一些。刷機(jī)后設(shè)備無法啟動卡在開機(jī)Logo。1. 鏡像不匹配如userdebug刷成了user。2. 內(nèi)核或設(shè)備樹不兼容。3.vbmeta.img驗(yàn)證失敗。1.最安全使用高通提供的原廠鏡像恢復(fù)。2. 嘗試只刷寫boot.img和system.img保留原vendor.img。3. 刷機(jī)時使用fastboot flash vbmeta vbmeta.img --disable-verification禁用AVB驗(yàn)證僅用于開發(fā)測試。修改了device/或vendor/下的文件但編譯后未生效。編譯系統(tǒng)可能沒有檢測到更改。1. 執(zhí)行m installclean清理之前編譯的對應(yīng)模塊產(chǎn)物再重新編譯。2. 或者更徹底地刪除out/target/product/sa8155/目錄下相關(guān)文件再m。編譯時提示找不到某個命令或工具。編譯環(huán)境依賴未安裝完整。根據(jù)錯誤提示使用apt search查找并安裝對應(yīng)的包。例如缺少libssl-dev、python3-xxx等。獨(dú)家技巧高效調(diào)試編譯錯誤單模塊編譯如果你只修改了某個App或服務(wù)比如packages/apps/Car/Media可以直接在根目錄執(zhí)行mma來編譯當(dāng)前目錄及其依賴。這比全量編譯快得多。查看詳細(xì)日志編譯失敗時在輸出中會有一個路徑指向一個verbose.log.gz文件。解壓并查看這個文件里面有最詳細(xì)的編譯命令和錯誤信息。使用CCache如果你需要頻繁清理并重新編譯設(shè)置CCache可以極大加速后續(xù)編譯。在~/.bashrc中添加export USE_CCACHE1 export CCACHE_EXEC/usr/bin/ccache ccache -M 50G # 設(shè)置緩存大小為50GB之后source ~/.bashrc并重啟終端。7. 進(jìn)階定制化開發(fā)與燒錄指南成功編譯出原生鏡像只是第一步。真正的開發(fā)工作始于定制化。7.1 添加一個系統(tǒng)級應(yīng)用假設(shè)你要為車機(jī)添加一個名為MyVehicleApp的系統(tǒng)應(yīng)用。創(chuàng)建應(yīng)用目錄在packages/apps/下創(chuàng)建MyVehicleApp/。編寫Android.mk或Android.bp這是AOSP的構(gòu)建腳本。現(xiàn)在推薦使用Soong構(gòu)建系統(tǒng)Android.bp。// packages/apps/MyVehicleApp/Android.bp android_app { name: MyVehicleApp, srcs: [src/**/*.java], resource_dirs: [res], certificate: platform, // 使用平臺簽名成為系統(tǒng)應(yīng)用 privileged: true, // 如果需要特權(quán)權(quán)限 optimize: { enabled: false, // 開發(fā)時可關(guān)閉優(yōu)化便于調(diào)試 }, }將應(yīng)用加入產(chǎn)品配置編輯你的設(shè)備配置文件例如device/qcom/sa8155/device.mk或device/qcom/sa8155/sa8155.mk添加PRODUCT_PACKAGES \ MyVehicleApp重新編譯系統(tǒng)鏡像執(zhí)行m或m systemimage。你的應(yīng)用就會被集成到system.img中。7.2 修改系統(tǒng)屬性與默認(rèn)配置系統(tǒng)屬性定義在system.prop或default.prop中。你可以在設(shè)備樹的rootdir目錄下找到或創(chuàng)建它們。例如在device/qcom/sa8155/rootdir/vendor/etc/init/hw/init.qcom.rc中可以設(shè)置屬性并觸發(fā)服務(wù)。7.3 燒錄鏡像到開發(fā)板警告此操作會擦除開發(fā)板上所有數(shù)據(jù)請務(wù)必先備份重要數(shù)據(jù)并確認(rèn)鏡像與硬件完全匹配。通常使用高通提供的fastboot工具進(jìn)行燒錄。將開發(fā)板進(jìn)入fastboot模式通常通過按住特定按鍵上電。通過USB將開發(fā)板連接至主機(jī)。在主機(jī)終端進(jìn)入鏡像所在目錄cd out/target/product/sa8155/執(zhí)行刷機(jī)腳本Linux./flashall.sh或者更穩(wěn)妥地分步刷入fastboot flash boot boot.img fastboot flash system system.img fastboot flash vendor vendor.img fastboot flash userdata userdata.img fastboot flash vbmeta vbmeta.img --disable-verification # 開發(fā)階段禁用驗(yàn)證 fastboot reboot刷機(jī)完成后設(shè)備會自動重啟。第一次啟動首次刷機(jī)或清理數(shù)據(jù)后會較慢因?yàn)橄到y(tǒng)需要進(jìn)行初始化。整個過程走下來從環(huán)境搭建到鏡像燒錄雖然步驟繁多但每一步都有其明確的邏輯。關(guān)鍵在于保持耐心仔細(xì)閱讀每一步的輸出信息遇到錯誤時善用搜索引擎和官方文檔盡管高通的公開文檔有時不盡如人意。最好的學(xué)習(xí)方式就是在成功編譯出基礎(chǔ)鏡像后嘗試做一些小的定制修改比如替換一個開機(jī)動畫、預(yù)裝一個自己的應(yīng)用在實(shí)踐中去理解整個AOSP高通BSP的構(gòu)建體系是如何運(yùn)作的。這遠(yuǎn)比只看文檔要來得深刻。