Android 64位變32位

人生最大的改變就是去做自己害怕的事情。

今年的Google I/O大會上Google提出了Android GO,其目的是儘可能的讓Android系統能運行在低配的手機設備。其中就提到了爲了節省存儲空間,Android GO是32位系統。

本篇博文沿着這個思路,介紹將Android改爲32系統的方法。修改的地方較少,只用修改兩個地方。

修改64位Android系統成32位

  1. 定義TARGET_ARCH跟TARGET_ARCH_VARIANT爲32位,TARGET_2ND_ARCH跟TARGET_2ND_ARCH_VARIANT賦空值.
  2. 配置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爲輔
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章