引用原文出处:https://zhuanlan.zhihu.com/p/371262225
原作者:name1e5s
前几天拆了个鸿蒙的 OTA 升级包,解包后发现那目录结构我太熟悉了,再随便看几个文件就明白了其实这鸿蒙就是安卓套壳。不过啊,我还是想知道除去 UI 上的修改,鸿蒙是否在 AOSP 的基础上改了部分内容,如果有,改了多少。今天晚上正好无事可做,就稍微看看解包的文件,找了找华为改了哪些内容。
结论
0. 鸿蒙手机版内核就是 Linux,没有什么乱七八糟的微内核
- 鸿蒙改了安卓的启动流程,多设置了个环境变量
MAPLE_RUNTIME
,同时预先加载了一些自己的 Java 类 - 鸿蒙自己的
ohos
包大多通过方舟编译器被塞到了.so
文件里,看不到实现,但是确实自己加了一些东西出来
- 根据去年年末别人对 DevEco 的拆包,其实是能看到最核心的
ohos.aafwk.ability.Ability
里面就是把安卓的 Activity 包了一层
3. 方舟编译器真的可以用
过程
我们都知道,Android 的启动流程是这样的:
- bootloader 初始化一些最基本的状态,之后载入并运行 Linux 内核
- 内核启动,加载驱动,初始化外设等等等等,最后开启第一个用户态进程 init
- init 读
init.rc
,创建/dev
等目录,初始化 SELinux,创建 ServiceManager,运行 Zygote 转到 Java 世界等等等等 - 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 里面,在外面搜了下也确实没搜到相关的文件,这至少证明了方舟编译器确实是存在的。
著作权归原作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。