引用原文出处:https://zhuanlan.zhihu.com/p/371262225
原作者:name1e5s

前几天拆了个鸿蒙的 OTA 升级包,解包后发现那目录结构我太熟悉了,再随便看几个文件就明白了其实这鸿蒙就是安卓套壳。不过啊,我还是想知道除去 UI 上的修改,鸿蒙是否在 AOSP 的基础上改了部分内容,如果有,改了多少。今天晚上正好无事可做,就稍微看看解包的文件,找了找华为改了哪些内容。

结论

0. 鸿蒙手机版内核就是 Linux,没有什么乱七八糟的微内核

  1. 鸿蒙改了安卓的启动流程,多设置了个环境变量 MAPLE_RUNTIME,同时预先加载了一些自己的 Java 类
  2. 鸿蒙自己的 ohos 包大多通过方舟编译器被塞到了 .so 文件里,看不到实现,但是确实自己加了一些东西出来
  • 根据去年年末别人对 DevEco 的拆包,其实是能看到最核心的 ohos.aafwk.ability.Ability 里面就是把安卓的 Activity 包了一层

3. 方舟编译器真的可以用

过程

我们都知道,Android 的启动流程是这样的:

  1. bootloader 初始化一些最基本的状态,之后载入并运行 Linux 内核
  2. 内核启动,加载驱动,初始化外设等等等等,最后开启第一个用户态进程 init
  3. init 读 init.rc,创建 /dev 等目录,初始化 SELinux,创建 ServiceManager,运行 Zygote 转到 Java 世界等等等等
  4. Zygote 创建 SystemServer,开 Launcher

在这个启动流程中,init.rc 是比较重要的,这里面记录了 init 进程要做的一些工作。我们先来看鸿蒙的 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
import /init.mygote64.rc
...

下面都是一些常规的项目,就不列出了,在这个文件的开头除去初始化硬件的 /vendor/etc/init/hw/init.${ro.hardware}.rc,还有一个 init.mygote64.rc 看起来就不是安卓自带的文件,打开看看内容:

service mygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --nice-name=zygote64 --socket-name=mygote
    class main
    disabled
    priority -20
    user root
    group root readproc reserved_disk
    socket mygote stream 660 root system
    socket usap_mygote_pool_primary stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart zygote
    onrestart restart zygote_secondary
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks /dev/blkio/foreground/tasks
    setenv MAPLE_RUNTIME libandroidmpl-rt.so
    critical

相比常规的 Zygote 启动语句,这里除去 socket 的名字不一样外,还多了个设置环境变量的语句:

setenv MAPLE_RUNTIME libandroidmpl-rt.so

这个梅普露 Runtime 以前稍微看过一点方舟编译器的都会有印象,它们的 IR 就叫做 MAPLE IR,想必与这个环境变量相关的文件就是鸿蒙自己修改/加的文件了罢。搜一下看看:

➜  system grep -r MAPLE_RUNTIME ./ 2>&1 | grep matches
Binary file .//apex/com.android.runtime.release.apex matches
Binary file .//lib64/libandroid_runtime.so matches
Binary file .//lib64/libmapleframework.so matches
Binary file .//lib64/libmaplecore-all.so matches
Binary file .//lib64/libmaplehwPartBasicplatform.so matches
Binary file .//lib64/libmaplehwframework.so matches
Binary file .//lib64/libmaplezframework.z.so matches
Binary file .//bin/bootstrap/linker64 matches
Binary file .//bin/bootstrap/linker matches
Binary file .//bin/bootstrap/linker_asan64 matches
Binary file .//bin/bootstrap/linker_asan matches
Binary file .//bin/crash_dump64 matches
Binary file .//bin/crash_dump32 matches
Binary file .//bin/decouple_cache matches
Binary file .//framework/maple/boot-zframework.z_classes2.cdex matches
Binary file .//framework/maple/boot-zframework.z_classes.cdex matches
Binary file .//framework/boot-zframework.z.vdex matches
Binary file .//framework/hwPartBasicplatform.jar matches
Binary file .//framework/hwframework.jar matches
Binary file .//framework/framework.jar matches
Binary file .//framework/arm/boot-core-libart.art matches
Binary file .//framework/arm64/boot-core-libart.art matches
Binary file .//priv-app/InProcessNetworkStack/InProcessNetworkStack.apk matches
Binary file .//lib/libandroid_runtime.so matches

还真不少,简单的看一下都是什么:

  • /lib64/libmaple*.so 推测是鸿蒙的运行时,开发鸿蒙引用的 ohos.aafwk 包估计都会在里面,看文件名可能还用到了方舟编译器编译?
  • /framework/arm*/boot-core-libart.art 安卓的 ART 虚拟机启动时预加载的一些包的映像
  • /bin/bootstrap/* 一些处理初始化的程序
  • /framework/*framework.jar,系统的框架文件
  • /lib/libandroid_runtime.so 安卓的运行时,Zygote 启动就会调里面的一些函数

最近要早睡,我时间有限,简单的看一下其中的两个重量级文件。

/framework/*framework.jar

这里只看 com.android.internal.os.ZygoteInit,就是 Zygote 初始化后运行的第一个 Java 类。会做一些类的预加载啦,环境的初始化等事情。通过反编译,可以注意到,在 preloadClasses 里面,除了常规的加载 /system/etc/preloaded-classes 列出来的类之外,还加载了 /system/etc/preloaded-harmony-classes 里面的文件,打开看看这个文件列了什么:

➜  framework cat ../etc/preloaded-harmony-classes | head -10
ohos.app.AbilityContext
ohos.app.AbilityManager
ohos.app.Application
ohos.app.Context
ohos.app.ContextDeal
ohos.app.dispatcher.task.TaskPriority
ohos.app.dispatcher.threading.WorkerPoolConfig
ohos.app.dispatcher.TaskDispatcherContext
ohos.app.dispatcher.TaskExecutor
ohos.app.ProcessInfo

是鸿蒙自己定义的一些类呢,预加载这些类可以加速鸿蒙程序的执行,可以理解。除此之外,在 preloadResources 函数引用的 C++ 程序中,除了常规的加载 /system/framework/framework-res.apk 之外,还额外加载了 /system/framework/framework-res-hwext.apk,想必是鸿蒙用的一些资源文件。

libmaplezframework.z.so

先看看这个文件的头:

➜  lib64 readelf -a libmaplezframework.z.so
...
节头:
  [号] 名称              类型             地址              偏移量
       大小              全体大小          旗标   链接   信息   对齐
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
...
  [23] .maple.gcrootsmap PROGBITS         00000000020ad768  0209d768
       0000000000024aa8  0000000000000000  WA       0     0     8
  [24] .reg_jni_tab      PROGBITS         00000000020d2210  020c2210
       000000000000d3a0  0000000000000000   A       0     0     8
  [25] .reg_jni_func_tab PROGBITS         00000000020df5b0  020cf5b0
       00000000000069d0  0000000000000000  WA       0     0     8
  [26] .muid_tab         PROGBITS         00000000020e5f80  020d5f80
       00000000001ed240  0000000000000000  WA       0     0     8
  [27] .mpl_version      PROGBITS         00000000022d31c0  022c31c0
       000000000000000c  0000000000000000   A       0     0     8
  [28] .classmetadata    PROGBITS         00000000022d31d0  022c31d0
       00000000000e9d28  0000000000000000  WA       0     0     8
  [29] .classmetada[...] PROGBITS         00000000023bcef8  023acef8
       0000000000008fe4  0000000000000000  WA       0     0     8
  [30] .refl_strtab      PROGBITS         00000000023c5ee0  023b5ee0
       000000000036a45a  0000000000000000   A       0     0     8
  [31] .refl_strtab.hot  PROGBITS         0000000002730340  02720340
       000000000002e1a0  0000000000000000   A       0     0     8
  [32] .bss              NOBITS           000000000275f000  0274e4e0
       000000000000b828  0000000000000000  WA       0     0     8
  [33] .maple_java_[...] PROGBITS         0000000000000000  0274e4e0
       0000000000000030  0000000000000000           0     0     1
  [34] .maple_java_[...] PROGBITS         0000000000000000  0274e510
       0000000000000020  0000000000000000           0     0     1
  [35] .maple_java_[...] PROGBITS         0000000000000000  0274e530
       000000000000000c  0000000000000000           0     0     1
  [36] .maple_java_[...] PROGBITS         0000000000000000  0274e53c
       00000000000fa7f6  0000000000000000           0     0     1
  [37] .shstrtab         STRTAB           0000000000000000  02848d32
       00000000000001d9  0000000000000000           0     0     1
... 

这种 Section 的排布还真没见过,上网搜一搜,最后发现 .refl_strtab 这些只在方舟编译器的源码中出现过,推测这文件是方舟编译器生成的产物。对照方舟编译器源码,了解到 .refl_strtab 是一些编译出来的类的符号字符串。看看都有啥:

➜  lib64 objdump -s -j .refl_strtab libmaplezframework.z.so | head -15

libmaplezframework.z.so:	file format elf64-littleaarch64

Contents of section .refl_strtab:
 23c5ee0 00676574 4861704d 6f64756c 65496e66  .getHapModuleInf
 23c5ef0 6f7c2829 4c6f686f 732f6275 6e646c65  o|()Lohos/bundle
 23c5f00 2f486170 4d6f6475 6c65496e 666f3b00  /HapModuleInfo;.
 23c5f10 6765744d 69737369 6f6e4964 7c282949  getMissionId|()I
 23c5f20 00766973 69744443 4d504c7c 284c6f68  .visitDCMPL|(Loh
 23c5f30 6f732f63 6f6d2f73 756e2f6f 72672f61  os/com/sun/org/a
 23c5f40 70616368 652f6263 656c2f69 6e746572  pache/bcel/inter
 23c5f50 6e616c2f 67656e65 7269632f 44434d50  nal/generic/DCMP
 23c5f60 4c3b2956 00766973 69744249 50555348  L;)V.visitBIPUSH
 23c5f70 7c284c6f 686f732f 636f6d2f 73756e2f  |(Lohos/com/sun/
 23c5f80 6f72672f 61706163 68652f62 63656c2f  org/apache/bcel/ 

看起来 ohos 相关的包的实现都被编译到了这个 so 里面,在外面搜了下也确实没搜到相关的文件,这至少证明了方舟编译器确实是存在的。

著作权归原作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐