鸿蒙OS开源代码精要解读之——init

作者介绍:

中科创达OpenHarmony研究组

阐明:

中科创达OpenHarmony研究组第一工夫对https://codechina.csdn.net/op...。为此,咱们打算编写一系列篇幅中等,内容精炼的源码剖析文章来引领大家更进一步的走进鸿蒙OS。随着对代码的理解,宽广开发者想亲自动手参加的志愿和信念也会随之加强——这也是鸿蒙OS开源的意义所在。

本篇内容摘要:

本篇以OpenHarmony中ipcamera_hi3518ev300为编译指标,介绍init过程的相干代码。

写在后面的话

咱们对OpenHarmony的代码进行了一个简略粗略的统计。除去所有的third_party代码(即OpenHarmony应用的第三方开源库),其余残余的代码中,以.c、.h文件为统计入口,总无效代码行数(不含正文、空行等,统计工具为tSourceCounter)为325627行。其中,归属kernel目录下的总无效代码行数为74150行。整个OpenHarmony中,kernel局部占比为22.8%左右,代码量上占大头的还在于kernel之上的、咱们称之为Framework的局部。依据咱们在Android零碎上多年的摸索和教训,Framework恰好是Android OS的精华。所以,以OpenHarmony目前才20多万行的Framework代码量来看,感兴趣的开发者在这块参加共建、献策献力的机会十分大。

1. OpenHarmony源码的下载和编译

先介绍代码的下载和编译。咱们研究组用得是ubuntu 19.10的主机环境。

1.1 源码下载

依照codechina.csdn官网的源码下载指南:https://codechina.csdn.net/op...

咱们应用的是第四种形式“获取形式4:从代码仓库获取”。执行这一节中的几个命令,即可失去整个源码仓库。

1.2 编译源码

咱们抉择的编译指标是“Hi3518解决方案”,其编译后的输入目录名为ipcamera_hi3518ev300。ipcamera_hi3518ev300是一个基于海思的ip摄像头设施。相干的介绍文档入口在https://codechina.csdn.net/op...。

留神,编译不同的解决方案须要建设对应的编译环境。对hi3518来说,开发者须要依照上述链接里的“搭建环境”来下载和配置。

所有就绪后,在源码根目录下执行 python build.py。如果不带参数的话,它会揭示你指定编译指标,截图如下:

这次,咱们通过python build.py ipcamera_hi3518ev300即可编译“Hi3518解决方案”。编译耗时10几分钟。

留神,编译过程中可能呈现找不到<valgrind/valgrind.h>的谬误。这是因为目前咱们下载的代码中没有蕴含valgrind的头文件。开发者能够手动将/usr/include/valgrind目录拷贝到prebuilts/lite/sysroot/usr/include下即可(仅限Ubuntu平台,需提前装置好valgrind工具)。

1.3 OpenHarmony编译相干小常识介绍

OpenHarmony源码编译系统应用了google开发的gn工具以及ninjia。这二者联合起来比传统的makefile编译系要高效,尤其适宜大零碎的并行编译。对开发者而言,如果要参加OpenHarmony的开发,须要对gn的语法有些理解。本文仅做一些最根本的介绍:

  1. 应用gn工具的话,开发者将编译规定写在名为BUILD.gn文件中。和Makefile一样,gn文件有本人的语法规定,属于畛域语言(Domain Specific Language,DSL)。gn语法不难,但编译规定自身有很多内容,所以一下子要把握全部内容也不容易。
  2. gn反对自定义模板函数,可放在名为.gni的文件中。OpenHarmony中最常见到的gn模板文件为./build/lite/config/component/lite_component.gni。.gn文件中通过import可导入gni模板文件。OpenHarmony定义了lite_component、lite_library等模板函数。
  3. gn中,可执行文件的编译函数入口为exectuable("文件名"),共享库的编译规定函数为shared_library("文件名")。所以,如果要搜寻某个文件对应的编译规定,能够先搜寻所有的BUILD.gn文件,而后grep executable。以下是咱们grep所有的executable的后果截图。

通过这种形式,咱们能很快定位到比方init对应的代码在什么中央。

最初,咱们再简略介绍下OpenHarmony编译系统中和底层OS无关的一个条件编译控制变量ohos_kernel_type。目前,该变量有四个取值,别离为"liteos_a"、"liteos_m"、"liteos_riscv"和"linux":

  1. "liteos_a"和"linux"常常做为一组进行判断。liteos_a理论对应的是Cortex-A系列,其性能绝对较高,能够跑Linux零碎。
  2. "liteos_m"和"liteos_riscv"往往是一组的。liteos_m对应的是Cortex-M系列,liteos_riscv是Riscv芯片的示意,二者可能都是针对性能个别,功耗较低的设施。

ohos_kernel_type的取值由build/lite/product/解决方案名.json文件中的product字段决定。例如,咱们抉择的ipcamera_hi3518ev300的配置文件内容截图如下,它的kernel字段值为"liteos_a"。

编译实现后,所有编译生成物都在out/ipcamera_hi3518ev300目录下。

2 init源码精要解析

init是Linux零碎上的第一个利用过程,是其它过程的源头。对ipcamera_hi3518ev300来说,它的编译产物中也有一个init过程。

在下面提到的out/ipcamera_hi3518ev300目录下,有一个rootfs.tar文件。这个文件里就是设施上根文件系统的内容。关上其中的/rootfs/bin目录,能够看到此次编译的可执行程序如下截图所示:

借助图2里提到的方法,咱们能够定位到init对应的代码门路为base/startup/services/init_lite/。其内容如下图所示:

main.c是整个init的入口。咱们简略看一下它的代码,如下所示。

init main函数十分精简,十分合乎"lite"轻量简便的格调。当然,也不排除将来init的代码会越来越简单。咱们在AOSP上察看到的状况就是一个例子——AOSP里当初的init的相干代码非常复杂)。

咱们对InitReadCfg比拟感兴趣,这个函数外部将读取/etc/init.cfg文件。这个文件在图4中提到的rootfs.tar中能够找到,下图是其内容的示意:

init.cfg实质上是一个json格局的文件。它包含一个名为"jobs"的数组和一个名为"services"的数组。

  1. 对"jobs"来说:外部别离蕴含"pre-init"、"init"和"post-init"三个元素。从下面的截图中能够看出,这三个元素对应的就是设置挂载一些设施、设置好门路,启动服务等工作。
  2. 对"services"来说:它蕴含一组服务的定义。所谓的服务,就是零碎里的要害过程。能够猜测到,init将依据service的配置来启动对应的服务程序,并设置它的uid、gid、过程优先级和权限等。

如果开发者对Android零碎有肯定理解的话,会发现OpenHarmony和AOSP在init的工作流程上有着类似的设计思路。不过,对OpenHarmony指标设施来说,应用json格局无疑是比较简单且不便的。

最初,咱们再看一下init的另外一个重要职能——服务过程情况监控。init.cfg中的那些服务属于零碎要害过程。运行过程中如果它们出现异常导致过程退出,须要有个方法将它们重新启动以保障业务连续性。

这个性能的实现就是利用Linux零碎的SIGCHILD信号。init在SignalInitModule中监听了该信号并设置了对应的信号处理函数——SigHandler。SigHandler函数的具体处理过程则比此处说得要更简单一点。当初,这部分内容就留给读者们自行摸索了!!


原文链接:https://developer.huawei.com/consumer/cn/forum/topicview?tid=0202366642839450045&fid=0101303901040230869
作者:innost