Android x86的arm兼容库移植--初步分析及尝试手动移植houdini/ndk_translation
適用于x86架構的安卓5.0以上需要root,或者離線改文件,但并非全部適用;本文僅為個人經驗,未涵蓋的地方需要自行探索。
手動移植Android x86的arm兼容庫(houdini/ndk_translation):簡略思路與移植演示_嗶哩嗶哩_bilibili
簡略版以及移植演示,請參考上邊視頻。需要了解一些東西的初步概念以理解本文再謹慎動手實踐,若不了解,請先在模擬環境測試環境下嘗試,備份資料。
Houdini兼容庫(Intel)與NDK_Translation兼容庫(Google)是目前x86處理器運行安卓時兼容arm應用的兩種方案。本篇文章參考安卓x86各處的源碼,Android-x86項目與Bliss-x86項目的一些文件,還有bliss os開發人員寫的兼容庫配置腳本(https://github.com/casualsnek/waydroid_script/blob/main/waydroid_extras.py)以嘗試實現手動移植這些兼容庫。(若要在編譯x86安卓時包含兼容庫,請移步其他教程)
網上已經存在Android-x86項目的arm兼容啟用教程,特別對于在sfs格式的只讀system系統目錄情況,本篇文章將不適用,請移步網上教程。
其中有些網上的教程還會配置L3級別的widevine,這里不講。
簡述waydroid的腳本的配置過程(install_houdini()與install_ndk()部分):
-
掛載系統鏡像,下載壓縮包驗證解壓,擴容鏡像(waydroid部分不詳述)
-
設置兼容庫文件權限為可執行
-
復制文件到系統鏡像?①
-
添加內容到build.prop?③
-
添加內容到init.rc?②
-
卸載鏡像
針對以上三個序號①②③分別展開
①兼容庫文件構成
(不同安卓版本的文件可能稍不同,不同的來源也可能目錄結構均有不同,因此可有多種,但目錄結構是由相關配置或者是動態庫的預設位置關聯的,因此應盡量與移植來源一致)
兼容庫文件權限設置
其中lib和etc目錄下,相關的文件夾權限均為drwxr-xr-x (755),相關的文件權限為-rw-r--r-- (644),bin目錄下的相關可執行文件權限為-rwxr-xr-x (755)
預先說明:部分目錄結構含有以下文件不會列出,會在后邊詳細說明
以下為兼容庫文件如何構成的一些例子,移植時可以盡量參考。同時,部分兼容庫可能會存放于vendor中,甚至是各種軟鏈接,需要弄清楚它們關聯
圖例顏色說明:
一、Houdini(經典目錄結構):
二、Houdini(waydroid目錄結構,linker在bin的arm文件夾中)
三、Houdini (remix os 5.1版本目錄結構,houdini可執行文件以及libhoudini.so動態庫在/lib/arm/下;類似的,許多安卓模擬器的houdini均在此文件夾,但libhoudini.so在原位置)
Ndk_Translation,9.0及以上,9.0目前有32位版本,9.0與11.0以上有所不同
四、Ndk_Translation(waydroid目錄結構,與11.0類似)
五、Ndk_Translation(9.0版本32位目錄結構)
②binfmt_misc注冊arm二進制執行文件
關于這個模塊,可以閱讀https://blog.csdn.net/whatday/article/details/88299482/ 以了解更多。
上邊已提前說明部分目錄結構包含binfmt_misc,在不同的設備/系統上,這部分的支持可以在超級多的地方,但主要是一個工作:在系統初始化時,將binfmt_misc目錄下的那些內容拷貝到/proc/sys/fs/binfmt_misc/register 下進行注冊。以下舉多種例子:
一、Waydroid配置腳本的內容過程解釋:
先找到init.rc(在舊版本中init.rc位于根目錄/ramdisk,在新版本中init.rc位于/system/etc/init/hw/),然后將以下內容拷貝進去:
②binfmt_misc注冊arm二進制執行文件
關于這個模塊,可以閱讀https://blog.csdn.net/whatday/article/details/88299482/ 以了解更多。
上邊已提前說明部分目錄結構包含binfmt_misc,在不同的設備/系統上,這部分的支持可以在超級多的地方,但主要是一個工作:在系統初始化時,將binfmt_misc目錄下的那些內容拷貝到/proc/sys/fs/binfmt_misc/register 下進行注冊。以下舉多種例子:
一、Waydroid配置腳本的內容過程解釋:
先找到init.rc(在舊版本中init.rc位于根目錄/ramdisk,在新版本中init.rc位于/system/etc/init/hw/),然后將以下內容拷貝進去:
解釋以上配置文本:在初始化早期,掛載binfmt_misc;檢測具有“啟用兼容庫的執行=√”這個屬性時,注冊內容
二、谷歌AS模擬器,安卓9 x86的32位:
system\etc\init\ndk_translation.rc的內容:(與waydroid有些類似)
三、chrome os (部分機型,此內容查看于guybrush機型)
安卓容器根目錄中的init.bertha.rc 部分內容:
四、Android-x86項目和Bliss OS等系統,部分安卓模擬器:
?
可以看到Android-x86項目在系統初始化時將腳本文件enable_nativebridge設置成了一個服務,引入了一個屬性persist.sys.nativebridge來控制服務的運行與終止。同時enable_nativebridge中也是關于binfmt_misc的配置。一些模擬器則會改動很多,注冊的內容可能還會在其他地方
參考其中一種arm_dyn和arm_exe及其文本內容,
:arm_dyn:M::\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x28::/system/bin/houdini:P
:arm_exe:M::\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28::/system/bin/houdini:P
?由名字可猜測分別對應動態庫和可執行程序,而里邊的注冊內容尾部也標定了arm代碼由哪個文件執行。對于houdini,則指定houdini文件的存放位置;對于ndk翻譯庫,則指定ndk_translation_program_runner_binfmt_misc文件的存放位置。其余部分詳解網上有,移植時基本上照搬即可。在移植翻譯庫時除了復制這些文件,也應考慮如何適配這個binfmt_misc的注冊。
③build.prop, default.prop等系統屬性內容配置
1. 參考waydroid配置腳本內容:
2.參考Android-x86配置內容:
3.參考谷歌AS模擬器9.0 x86 32位:
4.參考chrome os,安卓11子系統,ndk翻譯器:
總結以上例子:這些屬性中,部分屬性是可選的,而部分屬性是必選,但其位置很可能在各種地方,如default.prop或vendor下的build.prop,以下為這些屬性總結:
1.abi列表:根據需要,增加或刪除abi,以及調整abi順序
ro.product.cpu.abilist=x86_64,x86,armeabi-v7a,armeabi,arm64-v8a
ro.product.cpu.abilist32=x86,armeabi-v7a,armeabi
ro.product.cpu.abilist64=x86_64,arm64-v8a
上邊中,第一行包含全部abi及優先級(arm64優先級最低),第二第三行分別對應32位abi和64位abi。這幾行abi屬性影響應用安裝與運行,大多數情況,應用安裝包根據此處判斷是否支持的abi以及優先使用的abi。
2. ro.dalvik.vm.isa.arm64=x86_64和ro.dalvik.vm.isa.arm=x86
這兩個,如果含有64位或32位arm翻譯庫,則prop應包含對應的那行屬性,具體作用網上有介紹
3. ro.enable.native.bridge.exec=1
這一行屬性是安卓系統啟用兼容庫的標志,也可能與binfmt_misc在rc文件的的注冊代碼有關;部分包含64位翻譯庫的系統包含ro.enable.native.bridge.exec64=1,這應該由系統配置,或者init.rc相關的內容決定其作用,依情況添加
4. ro.dalvik.vm.native.bridge
這一個屬性很重要,其后參數代表使用的翻譯庫名稱,指向system的lib或lib64目錄下的對應文件。同時這一行屬性一般可能在根目錄的default.prop,部分系統則在build.prop
其后在目前有三種可能:
????①libhoudini.so,使用houdini兼容庫
????②libndk_translation.so,使用ndk_translation兼容庫
????③libnb.so,使用Android-x86項目特有的中間層,其動態庫位置由源代碼指定(詳細后講)
5. persist.sys.nativebridge
Android-x86項目特有的屬性,控制enable_nativebridge服務的運行與終止,以及決定libnb是否起作用。在系統設置中有其對應的開關。
6. dalvik.vm.isa.{abi}.variant;dalvik.vm.isa.{abi}.features
一般原系統已定義,不同設備(比如atom處理器的平板)可能會有不同的特殊的參數,模擬器和Android-x86一般都是默認;其中AS模擬器額外添加了arm的屬性
7.其他可選
一些尚未知曉其作用的屬性,如ro.ndk_translation.version,參考兼容庫的移植來源。
額外說明?
1.?houdini 兼容庫存在x,y,z這三種版本,同時具有基本對應的安卓版本,可執行的houdini和libhoudini.so中均可獲取版本號。版本號形式舉個例子:
Houdini 9.0.5c_y.51331
9.0.5c為大版本號,9對應安卓9;51331為小版本號,可作為區分更細版本。中間的y即代表y版本。含義——
????????x:32位系統內核的arm32翻譯庫(x86→arm),
????????y:64位系統內核的arm32翻譯庫(x86_64→arm),
????????z:64位系統內核的arm64翻譯庫(x86_64→arm64)。
NDK翻譯庫應該也是這么區分兩種32位模式,但是難以辨別,要從移植來源確認是32位還是64位linux內核。
最前邊的數字存在特例,安卓7的x版本使用的是houdini 6.1.2d_x,但部分模擬器用的libhoudini.so是7.1.1b_x(安卓9.0也能用houdini8)。此外安卓5存在houdini5.0.*和houdni5.2.*,部分使用houdini5.0.*的英特爾cpu的安卓5設備不能使用houdini5.2.*,原因是那些設備的安卓系統缺少部分源代碼,以致不兼容新的houdini5.2.*。改動內容可以參考https://github.com/iConsole/Console-OS_art/commits/consoleos-lollipop
2.?部分包含houdini兼容庫的Android-x86系統存在/system/vendor/etc/misc/目錄,包含三個文件:
?????? .OEMBlackList
?????? .OEMWhiteList
?????? .ThirdPartySO
其作用在Android-x86源碼可查(https://osdn.net/projects/android-x86/scm/git/frameworks-base/commits/280957b03c2c36535975d43ef5c0b0a1b8ad2c87?)需要系統代碼支持,
功能簡述:含有這些文件的系統,開啟了“國產app兼容性檢查”。這個檢查會將那些有x86庫但缺斤少兩,或者用arm庫以次充好的那些app,均安裝arm的版本而不是x86版本。
?????? .OEMWhiteList:對這個名單的app關閉這個檢查功能,有x86庫就裝x86
?????? .OEMBlackList:對這個名單的app強制安裝arm版本
?????? .ThirdPartySO:包含第三方庫的列表,以供檢查
另外,adb調試可以用 adb install --abi {abi名稱} {apk路徑} 命令以指定abi來安裝應用;而Android系統在shell可以用 pm install --abi {abi名稱} {apk路徑} 命令以指定abi安裝應用(pm需要root權限,且低版本安卓的pm沒有指定abi的功能)
3.?libnb.so庫:這是屬于Android-x86特有的一個中間層,可以找到其源碼。其內容標定了libhoudini.so的存放位置(因此remix os等可以將這個庫挪到其他地方);同時源碼中含有讀取persist.sys.nativebridge屬性,以決定是否啟用兼容;源碼中還含有其他調用兼容庫的中間層函數,但目前僅針對houdini優化,因此,若移植ndk_translation則不應使用libnb。
Remix OS的libnb源碼:https://github.com/JideTechnology/remixos-device-generic-common/blob/jide_x86_lollipop/nativebridge/src/libnb.cpp
4. 翻譯庫移植來源:鑒于目前可用的翻譯庫均是閉源產品,使用應該低調些,在以下地方等等可以提取
Houdini:
①Android-x86項目的下載鏈接,比如若要下載houdini5_z,則從這個網址以5_z為版本下載
http://dl.android-x86/houdini.php?v=5_z
http://dl.android-x86.org/houdini/5_z/houdini.sfs
②各種市面的安卓模擬器(夜神、雷電、逍遙等等)
③Win11的安卓子系統
④一些Android x86系統,如bliss os,prime os,以前的remix os,鳳凰os等等
⑤Intel處理器的chrome os刷機包內的安卓子系統可能含有
⑥寨板、zenfone2手機等intel處理器的安卓設備(Android IA)的刷機包含有
注:houdini自8.0開始就沒有發布x版本,8.0僅發布了y版本,10.0則完全沒有發布
NDK_Translation:
①谷歌Android Studio模擬器,含有google api的鏡像,其中安卓9的x86,安卓11的x86和x86_64,安卓12 x86_64會含有
②部分AMD處理器的chrome os設備的刷機包的安卓子系統會含有
③部分bliss os鏡像,waydroid的GitHub資源等等也含有移植過來的翻譯庫
移植過程大致總結:
1. 獲取/提取兼容庫,參考兼容庫目錄文件構成,將文件復制過去,需要注意兼容庫版本,目標系統空間剩余
2. 對復制后的兼容庫文件/文件夾進行權限設置
3. 配置binfmt_misc,參考上邊的過程類似;
?????? 常見的有:
?????? ①根目錄下的init.rc或init.{機型相關}.rc中包含部分注冊內容,這些內容將/system/etc/binfmt_misc/下的配置進行注冊;
?????? ②/system/etc/init/,或/vendor/etc/等附近與init有關的rc文件,也與①類似;
?????? ③Android-x86項目已通過init.rc相關的地方將腳本文件/system/bin/enable_nativebridge設置為服務,注冊/配置內容均在此腳本文件中實現。(不同的模擬器改動較大,自行探索)
4. 配置屬性(default.prop或build.prop等),參考上邊內容
總結
以上是生活随笔為你收集整理的Android x86的arm兼容库移植--初步分析及尝试手动移植houdini/ndk_translation的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中文网页中的字体选型及开发指南
- 下一篇: iphone照片无故消失一大半是怎么回事