Android abi和CPU位數

前言

不知道你們在設置abi的時候,有沒有考慮過這個問題。不一樣的abi之間有什麼區別。32位so又是如何運行在64位機器上的。這個是如何兼容的呢?java

從Zygote提及

相信有了解過系統源碼的同窗都知道這是啥玩意。首先咱們看下init進程在啓動zygote進程是如何作的。以6.0源碼爲例。android

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有幾種取值呢?bash

如圖所示app

  • zygote32 僅支持32位
  • zygote64 僅支持64位
  • zygote32_64 兼容32和64,32位優先
  • zygote64_32 兼容模式,64位優先

以小米6爲例。屬性值以下。socket

如今看一下init_zygote64_32.rm文件ui

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位。spa

Android系統是如何肯定應該是fork 64位仍是32位的呢

有了解過進程啓動的同窗應該看到過以下代碼。rest

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這兩個屬性得來的。code

#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查詢這個值的過程這裏就不說了。cdn

如今,看下小米6手機這幾個值是多少。

所以,啓動的是64位仍是32位,重點在於啓動進程時的參數abi.

這個ABI是哪裏來的

仔細想想,這個ABI是怎麼來的呢?首先,一個經過Launcher啓動的應用進程,確定是不知道應用的ABI的,那麼,只能是PMS了,PMS會在開機或者是安裝apk的過程當中,分析app的abi,而後就能夠在啓動的時候,fork相應位數的進程。

在PMS#installPackageLI方法中,調用了derivePackageAbi去分析abi.

這個方法的具體邏輯就很少說了,感興趣的能夠去了解下。

相關文章
相關標籤/搜索