Android 64和32位so是如何相容的
不知道大家在設定abi的時候,有沒有考慮過這個問題。不同的abi之間有什麼區別。32位so又是如何執行在64位機器上的。這個是如何相容的呢?
從Zygote說起
相信有了解過系統原始碼的同學都知道這是啥玩意。首先我們看下init程序在啟動zygote程序是如何做的。以6.0原始碼為例。
import /init.environ.rc import /init.usb.rc import /init.${ro.hardware}.rc import /init.${ro.zygote}.rc import /init.trace.rc 複製程式碼
在init.rc檔案中,會根據ro.zygote的值去啟動響應支援相應位數的程序。那麼,ro.zygote有幾種取值呢?

如圖所示
- zygote32 僅支援32位
- zygote64 僅支援64位
- zygote32_64 相容32和64,32位優先
- zygote64_32 相容模式,64位優先
以小米6為例。屬性值如下。

現在看一下init_zygote64_32.rm檔案
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary class main socket zygote_secondary stream 660 root system onrestart restart zygote 複製程式碼
可以很清楚的看到,系統在啟動的時候,會啟動兩個Zygote,一個64位一個32位。
Android系統是如何確定應該是fork 64位還是32位的呢
有了解過程序啟動的同學應該看到過如下程式碼。
synchronized(mLock) { return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } 複製程式碼
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held"); if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try { primaryZygoteState = ZygoteState.connect(mSocket); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe); } maybeSetApiBlacklistExemptions(primaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState); } if (primaryZygoteState.matches(abi)) { return primaryZygoteState; } // The primary zygote didn't match. Try the secondary. if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { try { secondaryZygoteState = ZygoteState.connect(mSecondarySocket); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe); } maybeSetApiBlacklistExemptions(secondaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState); } if (secondaryZygoteState.matches(abi)) { return secondaryZygoteState; } throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi); } 複製程式碼
- 會根據abi的值,先去primaryZygoteState匹配然後,再去匹配備選secondaryZygoteState。
那個,ZygoteState中所儲存的abi分類是怎麼來的呢?具體細節不說。這裡的值是通過讀取ro.product.cpu.abilist64,ro.product.cpu.abilist32這兩個屬性得來的。
#if defined(__LP64__) static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64"; static const char ZYGOTE_NICE_NAME[] = "zygote64"; #else static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32"; static const char ZYGOTE_NICE_NAME[] = "zygote"; #endif if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) { LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.", ABI_LIST_PROPERTY); return 11; } String8 abiFlag("--abi-list="); abiFlag.append(prop); 複製程式碼
將這些值寫入引數中,然後跟著ZygoteInit#main方法傳入到java層。具體通過socket查詢這個值的過程這裡就不說了。
現在,看下小米6手機這幾個值是多少。

因此,啟動的是64位還是32位,重點在於啟動程序時的引數abi.