ABI与Instruction Set

例子

在Android手机执行getprop | grep cpu,会得到类似下面的信息:

[ro.product.cpu.abi]: [arm64-v8a]
[ro.product.cpu.abilist]: [arm64-v8a,armeabi-v7a,armeabi]
[ro.product.cpu.abilist32]: [armeabi-v7a,armeabi]
[ro.product.cpu.abilist64]: [arm64-v8a]

每个CPU支持不同的指令集(Instruction Set),一个CPU和指令集的组合定义了一个ABI (Application Binary Interface),ABI定义了:
- 机器代码应当使用的CPU指令集
- 内存访问时大小端配置
- 可执行二进制文件的格式
- Convention:如对齐,寄存器使用限制

Primary ABI vs. Secondary ABI

Primary ABI是在编译整个系统镜像时已知的ABI,系统镜像中的机器代码使用Primary ABI;而可选的Secondary ABI是系统也可以支持的ABI。

获取平台ABI列表

在应用中,可以通过访问android.os.Build类来获得当前平台的ABI信息。设备支持的ABI信息列表是Build类中有序的String数组: SUPPORTED_ABIS, SUPPORTED_32_BIT_ABIS, SUPPORTED_64_BIT_ABIS,系统preferred ABI存储在Build.SUPPORTED_ABIS[0]中,比如前面例子中显示的设备preferred ABI是arm64-v8a

ABI和Instruction set

目前Android支持7种ABI (arm64-v8a,armeabi-v7a,armeabi,mips,mips64,x86,x86_64),如以上例子中的ro.product.cpu.abilist列出的几个。不同的ABI可能映射到同样的runtime instruction set(libcore/libart/src/main/java/dalvik/system/VMRuntime.java getInstructionSet(String abi)),Android M中ABI到instruction set的映射定义在VMRuntime类中如下:

   ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
   ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
   ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
   ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64");
   ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
   ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64");
   ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64");

可以看到不同的ABI (armeabi,armeabi-v7a)映射到了相同的instruction set arm. 在应用安装过程中,Android L开始会做AOT编译,编译时的target instruction set就是通过应用本身和平台ABI信息来计算出的。计算过程可以参见framework中InstructionSets.java中的代码。首先会根据解析出的Application包AppInfo中的primaryCpuAbi和secondaryCpuAbi来计算,如果AppInfo中的primaryCpuAbi不存在,则根据系统preferred ABI来计算target instruction set.

Reference:

[1] https://developer.android.com/ndk/guides/abis.html
[2] http://developer.android.com/reference/android/os/Build.html

你可能感兴趣的:(Managed,Runtime,Technology,系统,平台,可移植性,Android)