0
点赞
收藏
分享

微信扫一扫

【鸿蒙OS开发入门】12 - 启动流程代码分析之第一个用户态进程:init 进程 之 pre-init 任务详解

【鸿蒙OS开发入门】12 - 启动流程代码分析之第一个用户态进程:init 进程 之 pre-init 任务详解

  • 一、 /etc/init.cfg 系统默认cfg
  • 1.1 /etc/init.Hi3516DV300.cfg
  • 二、/system/etc/init 下的cfg
  • 2.1 faultloggerd32.cfg 崩溃临时日志管理模块
  • 2.2 hilogd.cfg 日志文件系统

本系列文章汇总:

  1. 《【鸿蒙OS开发入门】01 - 搭建Ubuntu虚拟机开发环境》
  2. 《【鸿蒙OS开发入门】02 - 启动流程代码分析之Uboot 第一阶段:之解压并引导加载u-boot.bin》
  3. 《【鸿蒙OS开发入门】03 - 启动流程代码分析之Uboot 第二阶段:之board_init初始化》
  4. 《【鸿蒙OS开发入门】04 - 启动流程代码分析之Uboot 第二阶段:之U_BOOT_CMD原理》
  5. 《【鸿蒙OS开发入门】05 - 启动流程代码分析之Uboot 第二阶段:之bootm引导加载Kernel OS》
  6. 《【鸿蒙OS开发入门】06 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核》
  7. 《【鸿蒙OS开发入门】07 - 安装docker环境编译openharmony 2.0代码》
  8. 《【鸿蒙OS开发入门】08 - 启动流程代码分析之KernelOS:之启动 liteos_a 内核》
  9. 《【鸿蒙OS开发入门】09 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核 中do_basic_setup()所干的大事》
  10. 《【鸿蒙OS开发入门】10 - 启动流程代码分析之第一个用户态进程:init 进程》
  11. 《【鸿蒙OS开发入门】11 - 启动流程代码分析之第一个用户态进程:init 进程 之 Services简介》
  12. 《【鸿蒙OS开发入门】12 - 启动流程代码分析之第一个用户态进程:init 进程 之 pre-init 任务详解》
  13. 《【鸿蒙OS开发入门】13 - 启动流程代码分析之第一个用户态进程:init 进程 之 init 任务详解》
  14. 《【鸿蒙OS开发入门】14 - 启动流程代码分析之第一个用户态进程:init 进程 之 post-init 任务详解》
  15. 《【鸿蒙OS开发入门】15 - 启动流程代码分析之第一个用户态进程:init 进程 之 libuv 做了啥?》

在前面,我们大概介绍了harmony os系统中有哪些Services,本来本文我们要接着分析下,这些service 又是何时启动的。

但实际了,前面在 ParseInitCfg() 中解析出这么多service 后,并没有启动,只是将相关的信息都保存起来了,供后续调用。

接下来几篇文章,我们先来看下 pre-init、init、post-init​ 这些流程中,又做了什么事,分析完这些后,估计我们对services 启动的时机会有更加深入的了解。

# base\startup\init_lite\services\src\main.c
int main(int argc, char **argv)
{
......
// 4. 分别执行pre-init、init、post-init 等相关的事情
InitReadCfg();
--------->
+ ParseInitCfg(INIT_CONFIGURATION_FILE); // "/etc/init.cfg"
+ DumpAllServices(); // 打印所有的服务信息,系统中所有现有的服务保存在 static Service* g_services 中,通过g_servicesCnt来进行索引计数。
+ DoJob("pre-init"); // 执行 `/etc/init.cfg` 中 `pre-init`的内容
+ DoJob("init"); // 执行 `/etc/init.cfg` 中 `init`的内容
+ DoJob("post-init"); // 执行 `/etc/init.cfg` 中 `post-init`的内容
+ ReleaseAllJobs(); // 释放init.cfg中所有的jobs 命令所占用的空间
<---------
......
}

DoJob("pre-init");​的作用是,触发启动 json cfg​文件中所有pre-init 字段的命令,我们分别来看看这些命令的功能吧。

一、 /etc/init.cfg 系统默认cfg

在init.cfg​加载了"/etc/init.usb.cfg", "/etc/init.usb.configfs.cfg", "/etc/init.Hi3516DV300.usb.cfg", "/etc/init.Hi3516DV300.cfg"这几个config,会把它们的信息全部整合进来。

先来看下 init.cfg 中的pre-init阶段的事情吧:

  1. 关闭Sysrq 系统调试工具
0 - disable sysrq completely
1 - enable all functions of sysrq
2 - enable control of console logging level
4 - enable control of keyboard (SAK, unraw)
8 - enable debugging dumps of processes etc.
16 - enable sync command
32 - enable remount read-only
64 - enable signalling of processes (term, kill, oom-kill)
128- allow reboot/poweroff
256- allow nicing of all RT tasks

使能Sysrq工具后,系统会生成 /proc/sysrq-trigger 这个节点用于调试:
#echo m > /proc/sysrq-trigger 导出内存分配信息
#echo t > /proc/sysrq-trigger 导出当前任务状态信息
#echo p > /proc/sysrq-trigger 导出当前CPU寄存器和标志位信息
#echo c > /proc/sysrq-trigger 产生空指针panic事件,人为导致系统崩溃
#echo s > /proc/sysrq-trigger 即时同步所有挂载的文件系统
#echo u > /proc/sysrq-trigger 即时重新挂载所有的文件系统为只读
#echo w > /proc/sysrq-trigger转储处于uninterruptable阻塞状态的任务
  1. 启动ueventd Services服务,供后续管理设备节点
  2. 挂载vendor​分区在/vendor目录
  3. 挂载userdata​分区在/data目录
# base/startup/init_lite/services/etc/init.cfg
{
"import" : [
"/etc/init.usb.cfg",
"/etc/init.usb.configfs.cfg",
"/etc/init.usb.cfg",
"/etc/init.Hi3516DV300.usb.cfg",
"/etc/init.Hi3516DV300.cfg"
],
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"write /proc/sys/kernel/sysrq 0", // 关闭Sysrq 系统调试工具
"mkdir /acct/uid", // 创建 /acct/uid目录
"chown root system /dev/memcg/memory.pressure_level", // 设置内存压力的通知事件,配合cgroup.event_control一起使用
"chmod 0040 /dev/memcg/memory.pressure_level",
"mkdir /dev/memcg/apps/ 0755 system system",
"mkdir /dev/memcg/system 0550 system system",
"start ueventd", // 启动 ueventd Services服务,供后续管理设备节点
"mkdir /vendor", // 挂载 vendor分区在 /vendor目录
"mkdir /data", // 挂载 userdata分区在 /data目录
"mount ext4 /dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor /vendor wait rdonly barrier=1",
"mount ext4 /dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata /data wait nosuid nodev noatime barrier=1,data=ordered,noauto_da_alloc"
]
},

1.1 /etc/init.Hi3516DV300.cfg

在/etc/init.usb.cfg", "/etc/init.usb.configfs.cfg", "/etc/init.Hi3516DV300.usb.cfg"中没有pre-init的任务,

我们来看下/etc/init.Hi3516DV300.cfg 中的pre-init任务干了啥:

修改系统所保留空闲内存的最低限值为10240,约为404kb

m i n _ f r e e _ k b y t e s = s q r t ( l o w m e m _ k b y t e s ∗ 16 ) = 4 ∗ s q r t ( l o w m e m _ k b y t e s ) min\_free\_kbytes = sqrt(lowmem\_kbytes * 16) = 4 * sqrt(lowmem\_kbytes) min_free_kbytes=sqrt(lowmem_kbytes∗16)=4∗sqrt(lowmem_kbytes) (注:lowmem_kbytes即可认为是系统内存大小)

# device/hisilicon/hi3516dv300/build/rootfs/init.Hi3516DV300.cfg
{
"import" : [
"init.${ro.hardware}.usb.cfg"
],
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"write /proc/sys/vm/min_free_kbytes 10240"
]
}

二、/system/etc/init 下的cfg

存在 pre-init 的cfg 总共有这些文件:

./base/hiviewdfx/faultloggerd/services/config/faultloggerd32.cfg:3: "name" : "pre-init",
./base/hiviewdfx/hilog/services/hilogd/etc/hilogd.cfg:3: "name" : "pre-init",

我们分别来看下吧。

2.1 faultloggerd32.cfg 崩溃临时日志管理模块

export LD_PRELOAD /system/lib/libdfx_signalhandler.z.so:​ 提前加载 /system/lib/libdfx_signalhandler.z.so 这个动态链接库。

# base/hiviewdfx/faultloggerd/services/config/faultloggerd32.cfg
{
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"export LD_PRELOAD /system/lib/libdfx_signalhandler.z.so"
]
}, {
"name" : "post-fs-data",
"cmds" : [
"mkdir /data/log/faultlog/ 0770 system system",
"mkdir /data/log/faultlog/temp/ 0770 system system",
"start faultloggerd"
]
}
],
"services" : [{
"name" : "faultloggerd",
"path" : ["/system/bin/faultloggerd"],
"uid" : "root",
"gid" : ["system", "log"],
"writepid" : [
"/dev/cpuset/system-background/tasks"
]
}
]
}

2.2 hilogd.cfg 日志文件系统

修改 max_dgram_qlen​ 为 600,这个参数是域通信 Socket 在数据报( UDP )方式下,队列里最大数据报个数。

官方解释:max_dgram_qlen limits how many datagrams can be queued on a unix domain socket's (SOCK_DGRAM) receive buffer. If a sender tries to send more datagrams, it blocks (in a blocking sendto) or returns error (in a non-blocking sendto). The default value is 10.

# base/hiviewdfx/hilog/services/hilogd/etc/hilogd.cfg
{
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"write /proc/sys/net/unix/max_dgram_qlen 600"
]
}, {
"name" : "post-fs-data",
"cmds" : [
"mkdir /data/log/ 0770 system log",
"mkdir /data/log/hilog/ 0750 logd log",
"start hilogd"
]
}
],
"services" : [{
"name" : "hilogd",
"path" : ["/system/bin/hilogd"],
"disabled" : 1,
"uid" : "logd",
"gid" : "log",
"socket" : [
"hilogInput dgram 0666 logd logd passcred",
"hilogControl seqpacket 0600 logd logd false"
]
}
]
}

可以看出,在pre-init​ 阶段,主要是启动ueventd​服务,以及挂载vendor、userdata 这两个分区

下篇,我们来看下 init 阶段做了哪些事情吧!

举报

相关推荐

0 条评论