人生最大的改變就是去做自己害怕的事情。
今年的Google I/O大會上Google提出了Android GO,其目的是儘可能的讓Android系統能運行在低配的手機設備。其中就提到了爲了節省存儲空間,Android GO是32位系統。
本篇博文沿着這個思路,介紹將Android改爲32系統的方法。修改的地方較少,只用修改兩個地方。
修改64位Android系統成32位
- 定義TARGET_ARCH跟TARGET_ARCH_VARIANT爲32位,TARGET_2ND_ARCH跟TARGET_2ND_ARCH_VARIANT賦空值.
- 配置zygote爲32位,在項目對應的make文件中添加
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32
到此修改完畢了,可以收工了。當然如果你還想知道這背後的細節知識,請繼續往下看。
TARGET_ARCH是什麼
TARGET_ARCH代表的是編譯Android的目標CPU架構的名稱,比如:arm,x86。利用uname -m可以查看當前手機的的CPU架構,我自己手機運行結果如下:
$ adb shell uname -m
armv7l
TARGET_ARCH_VARIANT是什麼
VARIANT英文譯爲”不同的”,TARGET_ARCH_VARIANT之前被稱爲TARGET_ARCH_VERSION,其作用是區分相同CPU架構的不同版本,比如arm架構它有很多個版本,我們依靠TARGET_ARCH_VARIANT來進行選取。
TARGET_ARCH_VARIANT在源碼中有多個值,比如armv7-a-neon/x86_64/mips64r6。這些分別代表什麼含義呢?
arm系列
以armv7-a-neon來舉例說明,arm打頭代表CPU架構是arm的,v7表示版本,v7以及v7以下的版本均是32位的,從v8開始就是64位了。而v7版本的arm又細分爲三種:
- a:專爲Application設計,a代表Applications
- r:專爲實時系統設計,r代表Real-time
- m:精簡版本,m代表Microcontroller
這其中a跟r非常類似。更詳細的說明請查考arm官方文檔:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c/index.html
我們平時見的多是armv7-a系列。
提下neon, 它是arm公司專爲移動消費類設備設計的。它提供了更卓越的視頻編碼解碼,3D圖形渲染,語音處理,流媒體處理等功能。
還有vfp,vfp是Vector Floating-Point的縮寫,它在處理矢量浮點運算方面表現更好。
明白了這些在看下面這些配置值心裏就明白意思了。
armv7-a-neon
armv5te-vfp
armv8-a
mips系列
mips是區別與arm的另一種CPU架構。由MIPS公司開發並授權,它跟arm一樣都基於精簡指令集處理器架構的思想,常見的有
mips64r6
mips32r2-fp
mips32-fp
x86系列
x86_64中x86表示cpu架構是由因特爾公司開發,而64表示是64位系統。
TARGET_2ND_ARCH和TARGET_2ND_ARCH_VARIANT分別什麼含義
TARGET_2ND_ARCH
從Android5.0之後出現了64位系統,Android系統就需要考慮兼容之前大量的32位程序了,如果打算在64位系統上,也具有編譯32程序的能力,就該TARGET_2ND_ARCH出場了,它的出現正是Android系統爲了兼容64/32的程序而引入的。
這裏的目標程序多數情況下指的是庫文件,默認系統只會編譯出運行在TARGET_ARCH架構下的庫文件.
看看下面的例子:
TARGET_ARCH=arm64
TARGET_2ND_ARCH=arm
TARGET_ARCH說明芯片架構是面向64位系統的,並且在這個基礎上又定義了TARGET_2ND_ARCH,它表明芯片也是兼容32位程序的。當確定需要編譯32位庫文件時,需要在庫文件模塊的Android.mk文件中加入:
LOCAL_MULTILIB := 32 # 只編譯32位
LOCAL_MULTILIB := both # 64/32位都編譯
TARGET_2ND_ARCH_VARIANT
解釋完TARGET_2ND_ARCH,TARGET_2ND_ARCH_VARIANT的含義也就明朗了。它表示兼容cpu架構的版本。
zygote32是什麼
zygote32顧名思義,它服務的是32位系統。因爲從Android5.0之後蹦出了64位,因此zygote也需要跟着適配,分成32/64的版本。
開篇提到的
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32
改動是什麼道理呢?
system/core/rootdir/init.rc
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc
我們將ro.zygote賦值爲zygote32,所以最終就有import /init.zygote32.rc
init.zygote32.rc所在位置如下圖:
這裏也可以看到zygote有四個版本,不應該是兩個嗎?(一個32另一個64),查看內容就知道區別了。
system/core/rootdir/init.zygote32_64.rc
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
class main
priority -20
user root
group root readproc
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
它們的區別如下表:
配置文件名稱 | 含義 |
---|---|
init.zygote32.rc | 只啓動一個面向32位的app_process32進程 |
init.zygote64.rc | 只啓動一個面向64位的app_process64進程 |
init.zygote32_64.rc | 啓動兩個app_process進程,其中app_process32爲主,app_process64爲輔 |
init.zygote64_32.rc | 啓動兩個app_process進程,其中app_process64爲主,app_process32爲輔 |