Init是鸿蒙OS的第一个用户态进程,类似于现在Linux发行版中的systemd。Init进程的代码在basestartupservicesinit_lite实现。

main函数

鸿蒙如何获取md5指纹和公钥_配置文件

本函数的注解非常清晰,总共4步,

打印系统信息

注册信号处理函数

读取系统配置文件并进行相关处理

进入循环等待信号处理

下面分别解读一下1-3步的相关代码

PrintSysInfo函数

本函数主要功能就是打印系统信息。

鸿蒙如何获取md5指纹和公钥_鸿蒙os开放进程_02

详细的看GetVersionId函数,由于代码比较长,我们主要看核心处理的部分:

鸿蒙如何获取md5指纹和公钥_ide_03

主要功能就是获取设备的相关类型,厂商,品牌,型号等信息。具体看一个函数GetProductType:

鸿蒙如何获取md5指纹和公钥_鸿蒙如何获取md5指纹和公钥_04

我们可以看到,只是调用了硬件抽象层的函数HalGetProcutType,而这个函数依据不同的硬件有不同的实现,因此我们就不继续往下深入了。

SignalInitModule函数

鸿蒙如何获取md5指纹和公钥_ide_05

鸿蒙如何获取md5指纹和公钥_鸿蒙如何获取md5指纹和公钥_06

从信号处理函数来看,init进程主要助理两个信号,SIGCHLD和SIGTERM。

先说简单的SIGTERM信号,这时候init会通过StopAllService函数结束所有的系统服务。如果是收到某个服务终止的SIGCHLD信号,则要视服务的重要性进行处理,有可能重启系统。具体服务包括哪些则通过配置文件进行定义,后续详细说明。

InitReadCfg函数

鸿蒙如何获取md5指纹和公钥_#define_07

InitReadCfg这个函数,感觉名称不是很合适,因为不光是读了配置文件,实际还通过DoJob函数,执行了很多启动前,中和后的操作。

配置文件的地址如下:

#defineINIT_CONFIGURATION_FILE"/etc/init.cfg"

看一下具体init.cfg的一个例子,来自于HiSpark AI Camera套件

vendorhuaweicamerainit_configsinit_liteos_a_3516dv300.cfg

这里面定义了init前后中需要执行的jobs以及init启动完成之后启动的服务。

{
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"mkdir /storage/data/log",
"chmod 0755 /storage/data/log",
"chown 4 4 /storage/data/log",
"mkdir /storage/data/softbus",
"chmod 0700 /storage/data/softbus",
"chown 7 7 /storage/data/softbus",
"mkdir /sdcard",
"chmod 0777 /sdcard",
"mount vfat /dev/mmcblk0 /sdcard rw,umask=000",
"mount vfat /dev/mmcblk1 /sdcard rw,umask=000"
]
}, {
"name" : "init",
"cmds" : [
"start shell",
"start apphilogcat",
"start foundation",
"start bundle_daemon",
"start appspawn",
"start media_server",
"start wms_server"
]
}, {
"name" : "post-init",
"cmds" : [
"chown 0 99 /dev/dev_mgr",
"chown 0 99 /dev/hdfwifi",
"chown 0 99 /dev/gpio",
"chown 0 99 /dev/i2c-0",
"chown 0 99 /dev/i2c-1",
"chown 0 99 /dev/i2c-2",
"chown 0 99 /dev/i2c-3",
"chown 0 99 /dev/i2c-4",
"chown 0 99 /dev/i2c-5",
"chown 0 99 /dev/i2c-6",
"chown 0 99 /dev/i2c-7",
"chown 0 99 /dev/uartdev-0",
"chown 0 99 /dev/uartdev-1",
"chown 0 99 /dev/uartdev-2",
"chown 0 99 /dev/uartdev-3",
"chown 0 99 /dev/spidev0.0",
"chown 0 99 /dev/spidev1.0",
"chown 0 99 /dev/spidev2.0",
"chown 0 99 /dev/spidev2.1"
]
}
],
"services" : [{
"name" : "foundation",
"path" : "/bin/foundation",
"uid" : 7,
"gid" : 7,
"once" : 0,
"importance" : 1,
"caps" : [10, 11, 12, 13]
}, {
"name" : "shell",
"path" : "/bin/shell",
"uid" : 2,
"gid" : 2,
"once" : 0,
"importance" : 0,
"caps" : [4294967295]
}, {
"name" : "appspawn",
"path" : "/bin/appspawn",
"uid" : 1,
"gid" : 1,
"once" : 0,
"importance" : 0,
"caps" : [2, 6, 7, 8, 23]
}, {
"name" : "apphilogcat",
"path" : "/bin/apphilogcat",
"uid" : 4,
"gid" : 4,
"once" : 1,
"importance" : 0,
"caps" : []
}, {
"name" : "media_server",
"path" : "/bin/media_server",
"uid" : 5,
"gid" : 5,
"once" : 1,
"importance" : 0,
"caps" : []
}, {
"name" : "wms_server",
"path" : "/bin/wms_server",
"uid" : 0,
"gid" : 0,
"once" : 1,
"importance" : 0,
"caps" : []
}, {
"name" : "bundle_daemon",
"path" : "/bin/bundle_daemon",
"uid" : 8,
"gid" : 8,
"once" : 0,
"importance" : 0,
"caps" : [0, 1]
}
]
}

鸿蒙OS的Service

鸿蒙OS的init进程启动后,如上面的例子所示init进程接下来会启动很多服务,对于这些服务,鸿蒙OS有一个统一管理,所有的服务都被注册到如下的动态数组当中。

鸿蒙如何获取md5指纹和公钥_配置文件_08

Service的定义

鸿蒙如何获取md5指纹和公钥_鸿蒙os开放进程_09

从定义中不难看出,对于每个Service,除了基本的名字,可执行文件路径,进程id,还记录了这个Service的crash次数和第一次crash的时间,另外还定义了Service的属性和权限。

对于属性,参考如下常量定义,主要是在该Service奔溃之后是否需要重启。

// service attributes
#define SERVICE_ATTR_INVALID      0x001  // option invalid
#define SERVICE_ATTR_ONCE         0x002  // do not restart when it exits
#define SERVICE_ATTR_NEED_RESTART 0x004  // will restart in the near future
#define SERVICE_ATTR_NEED_STOP    0x008  // will stop in reap
#define SERVICE_ATTR_IMPORTANT    0x010  // will reboot if it crash

对于Perms,则依据操作系统的定义而不同。

对于Service,都有启动,停止和重启三个动作。

对于Service Manager,则提供了以下动作:

void RegisterServices(Service* services, int servicesCnt);
void StartServiceByName(const char* serviceName);
void StopAllServices();
void ReapServiceByPID(int pid);