未验证 提交 1a40ed60 编写于 作者: O openharmony_ci 提交者: Gitee

!10593 增加init子系统 组件化启动以及启动 log 的文档说明

Merge pull request !10593 from cheng_jinsong/docs1013
......@@ -82,6 +82,8 @@
- [系统参数](subsys-boot-init-sysparam.md)
- [沙盒管理](subsys-boot-init-sandbox.md)
- [插件](subsys-boot-init-plugin.md)
- [组件化启动](subsys-boot-init-sub-unit.md)
- [init运行日志规范化](subsys-boot-init-log.md)
- [appspawn应用孵化组件](subsys-boot-appspawn.md)
- [bootstrap服务启动组件](subsys-boot-bootstrap.md)
- [常见问题](subsys-boot-faqs.md)
......
# init运行时日志规范化
## 概述
### 功能简介
日志的基本功能就是记录init启动中的关键节点,以及定位故障问题。
- 基于日志可以定位故障问题,可以查看各子系统启动时长,命令执行时长等。
- 可以查看不同模块的日志tag,如param、uevent、module等。
- 输出关键阶段日志,如第一阶段启动日志、required partition设备节点、uevent创建日志、服务启动日志等。
- 日志等级可控,根据需要输出不同级别日志,目前日志级别分为INIT_DEBUG,
INIT_INFO,INIT_WARN,INIT_ERROR,INIT_FATAL。
### 基本概念
init日志根据OpenHarmony版本不同实现方式不同。
- 对于OpenHarmony标准版本,init日志采用内核的dmesg log实现。
- 对于OpenHarmony liteos L1版本init日志采用hilog接口实现。
- 对于OpenHarmony liteos L0版本init日志采用printf接口实现。
### 约束与限制
## 开发指导
### 场景介绍
init log主要应用在init的启动过程中,启动相关模块(param、ueventd、module等)中,以及对外提供的begetutils接口中。
### 接口说明
**表1** log接口说明
| 接口 | 接口格式和示例 | 说明 |
| -------- | -------- | -------- |
| INIT_LOGV | INIT_LOGV("Add %s to job %s", service->name, jobName); | 输出debug log。 |
| INIT_LOGI | INIT_LOGI("Start init first stage."); | 输出info log。 |
| INIT_LOGW | INIT_LOGW("initialize signal handler failed"); | 输出warning log。 |
| INIT_LOGE | INIT_LOGE("Failed to format other opt"); | 输出err log。 |
| INIT_LOGF | INIT_LOGF("Failed to init system"); | 输出fatal log。 |
| INIT_ERROR_CHECK | INIT_ERROR_CHECK(ctx != NULL, return NULL, "Failed to get cmd args "); | 判断 ctx != NULL 不成立的情况下输出log,同时执行 return NULL。 |
| INIT_INFO_CHECK | INIT_INFO_CHECK(sockopt != NULL, return SERVICE_FAILURE, "Failed to malloc for service %s", service->name); | 判断 sockopt != NULL 不成立的情况下输出log,同时执行 return SERVICE_FAILURE。 |
| INIT_WARNING_CHECK | INIT_WARNING_CHECK(argsCount <= SPACES_CNT_IN_CMD_MAX, argsCount = SPACES_CNT_IN_CMD_MAX, "Too much arguments for command, max number is %d", SPACES_CNT_IN_CMD_MAX); | 判断 argsCount <= SPACES_CNT_IN_CMD_MAX 不成立的情况下输出log,同时执行 argsCount = SPACES_CNT_IN_CMD_MAX。 |
| INIT_CHECK | INIT_CHECK(arg != NULL, return NULL); | 判断arg != NULL 不成立的情况下执行 return NULL。 |
| INIT_CHECK_RETURN_VALUE | INIT_CHECK_RETURN_VALUE(errno == 0, -1); | 判断errno == 0 不成立的情况下执行 return -1。 |
| INIT_CHECK_ONLY_RETURN | INIT_CHECK_ONLY_RETURN(cmd != NULL); | 判断cmd != NULL 不成立的情况下执行 return。 |
| INIT_CHECK_ONLY_ELOG | INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0, "execv %s failed! err %d.", argv[0], errno); | 判断execv(argv[0], argv) == 0 不成立的情况下只打印log "execv %s failed! err %d."。 |
### 开发实例
1. 调用接口打印日志
例如在 //base/startup/init/services/init/standard/init.c中调用接口INIT_LOGI("Start init first stage.")打印日志。
```c
void SystemPrepare(void)
{
MountBasicFs();
CreateDeviceNode();
LogInit();
// Make sure init log always output to /dev/kmsg.
EnableDevKmsg();
INIT_LOGI("Start init first stage.");
// Only ohos normal system support
// two stages of init.
// If we are in updater mode, only one stage of init.
if (InUpdaterMode() == 0) {
StartInitSecondStage();
}
}
```
通过dmesg可以查看打印的log,"Start init first stage."。
2. 通过命令设置日志等级
通过命令begetctl setloglevel level,其中level对应log的等级0~4,即INIT_DEBUG,INIT_INFO,INIT_WARN,INIT_ERROR,INIT_FATAL。
设置完成之后init的g_logLevel等级立即生效,上述log接口中log等级大于等于g_logLevel才会打印日志。例如:begetctl setloglevel 3,即设置log等级为INIT_ERROR,则上述的log接口中只有INIT_LOGE、INIT_LOGF才会打印log。
系统重启之后在init.cfg中"load_persist_params "命令之后生效设置的log等级。
......@@ -59,6 +59,8 @@ bootchart和bootevent只支持标准系统, begetctl 支持小型系统和标
| modulectl uninstall moduleName | 卸载动态插件,例如:<br>modulectl uninstall bootchart | 无 |
| modulectl install moduleName | 安装动态插件,例如:<br>modulectl install bootchart | 无 |
| modulectl list | 动态插件列表,例如:<br>begetctl modulectl list | 无 |
| setloglevel level | 设置log等级为info,例如:<br>begetctl setloglevel 1 | log等级设置范围0~4 |
| getloglevel | 获取当前init的log等级,例如:<br>begetctl getloglevel | 无 |
| bootevent disable | 关闭bootevent插件功能,例如:<br>bootevent disable | 无 |
| bootevent enable | 开启bootevent插件功能,例如:<br>begetctl 关闭bootevent插件功能 | 无 |
| dump_service parameter_service trigger | 命令行展示所有trigger信息,例如:<br>begetctl dump_service parameter_service trigger | 无 |
......@@ -67,16 +69,6 @@ bootchart和bootevent只支持标准系统, begetctl 支持小型系统和标
| dump api | 命令行展示init接口信息,例如:<br>begetctl dump api | 无 |
### 接口说明
**表1** 接口介绍<a name="table14737791479"></a>
| 函数 | 函数解释 |
| ---------- | ---------- |
| void PluginExecCmdByName(const char *name, const char *cmdContent) | 通过名称启动插件。 |
| void PluginExecCmdByCmdIndex(int index, const char *cmdContent) | 通过标志启动插件。 |
| int PluginExecCmd(const char *name, int argc, const char **argv) | 命令启动插件。 |
| int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd) | 添加安装插件命令。 |
### 开发步骤
新增一个插件, 以bootchart为例:
1. 安装so文件, 定义单独文件,实现下面函数。
......
# 组件化启动
## 概述
### 功能简介
构建四个基础组件镜像,提供相应的组件化目录,包括:
- 系统组件:system
- 产品通用配置组件:sys_prod
- 芯片组件:chipset
- 产品硬件配置组件:chip_prod;
确保系统参数以及启动脚本都可以按照组件的优先级进行扫描初始化;
完成系统组件和芯片组件的独立编译构建。
### 基本概念
- 基础组件
system:系统组件文件系统挂载点,与芯片及硬件无关的平台业务;
sys_prod:对系统组件的能力扩展以及能力定制,承载产品级差异能力,存放产品相关的配置文件;
chipset:芯片组件文件系统挂载点,为系统组件提供统一的硬件抽象服务,相同的芯片平台可统一一份芯片组件;
chip_prod:单板外设特有硬件能力以及产品级硬件差异配置, 存放芯片相关的配置文件。
- 组件化编译构建
通过"target_cpu" 指定系统组件的指令集;通过"inherit" 继承base、headless或者rich等通用组件集合;最后通过"subsystems" 定义该形态更多的部件。
- 系统参数以及启动脚本按照组件的优先级进行扫描初始化
系统参数以及启动脚本包括:服务的cfg配置文件、param文件、沙盒json配置文件以及module插件化库文件等。相关文件优先级顺序是 /system < /chipset < /sys_prod < /chip_prod,即优先级高的配置文件将取代、更新低优先级配置。
### 约束与限制
对于标准版本和小型系统都支持组件化编译构建,以及系统参数以及启动脚本按照组件的优先级进行扫描初始化。
## 开发指导
### 场景介绍
组件化启动主要是满足厂家、硬件平台通过模块化的组合快速实现产品开发。以下以rk3568产品为例介绍组件化启动。
### rk3568产品的组件化构建编译
//vendor/hihope/rk3568/config.json 配置文件实现构建此产品需要的组件,如下所示:
{
"product_name": "rk3568",
"device_company": "rockchip",
...
"target_cpu": "arm",
...
"inherit": [ "productdefine/common/inherit/rich.json", "productdefine/common/inherit/chipset_common.json" ],
"subsystems": [
{
"subsystem": "security",
"components": [
{
"component": "selinux",
"features": []
}
]
}
...
}
从中可以看出产品名称、芯片厂家、支持的指令集等;inherit指出依赖的通用组件;subsystems指出通用组件以外的部件。
//productdefine/common/inherit/rich.json 如下所示配置系统组件完整的部件;系统组件还可以包括base.json(所有产品都要包含的最小部件集合列表)、headless.json(没有ui界面的产品支持应用安装管理的最小部件集合)。
{
"version": "3.0",
"subsystems": [
{
"subsystem": "arkui",
"components": [
{
"component": "ace_engine",
"features": []
},
{
"component": "napi",
"features": []
}
]
},
{
"subsystem": "account",
"components": [
{
"component": "os_account",
"features": []
}
]
},
...
}
### 系统参数根据优先级扫描初始化
对于服务的cfg配置文件优先级是/system/etc < /system/etc/init < /chipset/etc,即优先级高的配置文件将取代、更新低优先级配置。例如/system/etc/init/camera_service.cfg,
{
"services" : [{
"name" : "camera_service",
"path" : ["/system/bin/sa_main", "/system/profile/camera_service.xml"],
"uid" : "cameraserver",
"gid" : ["system", "shell"],
"secon" : "u:r:camera_service:s0",
"permission" : ["ohos.permission.GET_SENSITIVE_PERMISSIONS"],
"permission_acls" : ["ohos.permission.GET_SENSITIVE_PERMISSIONS"]
}]
}
同时存在/chipset/etc/camera_B_service.cfg
{
"services" : [{
"name" : "camera_service",
"path" : ["/system/bin/sa_main", "/system/profile/camera_B_service.xml"],
"uid" : "cameraserver",
"gid" : ["system", "shell"],
"secon" : "u:r:camera_service:s0",
"permission" : ["ohos.permission.GET_SENSITIVE_PERMISSIONS"],
"permission_acls" : ["ohos.permission.GET_SENSITIVE_PERMISSIONS"],
"disabled" : 1
}]
}
那么根据优先级的要求,camera_service服务"path"属性将会被优先级高的["/system/bin/sa_main", "/system/profile/camera_B_service.xml"]取代,同时增加"disabled"属性。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册