3 Star 2 Fork 7

handy / ohos_startup_faqs

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

1. init部件常见问题

1.1 如何新增系统服务进程

1.2 系统服务进程常见问题

  • 新增系统服务进程无法启动

  • 系统服务进程退出后不自动重启

    查看服务进程的cfg文件,是否将"once"项配置为1;该项若为1,则表示为一次性进程,进程退出后不会再被init拉起

  • 如何默认disable系统服务进程

    当前服务的cfg文件中配置"disable" 项未启用,可以通过配置"start-mode" 项来控制启动方式

  • 如何关闭系统服务进程沙盒

    在服务的cfg文件中配置 "sandbox" : 0 即服务不进入沙盒、1为进入沙盒,默认服务是进入沙盒

1.3 如何新增系统参数

1.4 系统参数访问控制权限

  • 如何设置一个系统参数

    1、hdc shell进入终端,执行param set param.key.xxx(系统参数名) param.value.xxx(系统参数名值), 确认参数是否可以设置成功,成功则无需其他设置

    2、代码侧设置系统参数,调用SetParameter接口,具体参照接口说明

    3、执行param set 失败,则根据失败的日志确定对应的排查操作:

    若dac 权限不足,参照DAC访问控制权限设置进行设置

    若selinux 权限不足,根据" avc: denied" 告警信息设置对应规则

    若内存不够,参照系统参数标签文件大小配置进行扩展

  • 如何读取一个系统参数

    1、hdc shell进入终端,执行param get param.key.xxx(系统参数名), 查看参数是否可以读取成功,读取成功则无需其他操作

    2、代码侧获取系统参数,调用GetParameter接口,具体参照接口说明

    3、执行param get 失败,则根据失败的日志确定对应的排查操作:

    首先需要确认改参数是否被设置,若没有被设置,则需要先设置该参数;若已设置,则进行下一步排查

    若dac 权限不足,参照DAC访问控制权限设置进行设置

    若selinux 权限不足,根据" avc: denied" 告警信息设置对应规则

  • 如何订阅一个系统参数的变化

    1、hdc shell进入终端,执行param shell,进入Parameter shell后执行 watcher parameter param.key.xxx(系统参数名),当系统参数值发生变化时,会收到类似"Receive parameter commit 691 change aaa.aaa 11111"的消息

    2、代码侧监控系统参数变化,调用WatchParameter接口

    3、执行watcher parameter 失败,则根据失败的日志确定对应的排查操作:

    若dac 权限不足,参照DAC访问控制权限设置进行设置

    若selinux 权限不足,根据" avc: denied" 告警信息设置对应规则

  • 三方应用为何无法访问系统参数

    三方应用访问系统参数需要配置对应的selinux权限

1.5 启动子系统错误码说明

系统服务

错误码说明

枚举 枚举值 错误信息 说明
INIT_OK 0 执行成功
INIT_EPARAMETER 1 parameter 接口参数无效
INIT_EFORMAT 2 Format string fail 字符串格式化错误
INIT_ECFG 3 cfg error cfg解析错误
INIT_EPATH 4 Invalid path 服务path配置错误
INIT_EFORK 5 Fork fail fork子进程失败
INIT_ESANDBOX 6 Create sandbox fail 服务进沙盒失败
INIT_EACCESSTOKEN 7 Set access token fail 设置access token失败
INIT_ESOCKET 8 Create socket fail 创建socket失败
INIT_EFILE 9 Create file fail 创建文件失败
INIT_ECONSOLE 10 Open console fail 打开console失败
INIT_EHOLDER 11 Publish holder fail Publish holder失败
INIT_EBINDCORE 12 Bind core fail 绑核失败
INIT_EKEEPCAP 13 Set keep capability fail 设置keep capability失败
INIT_EGIDSET 14 Set gid fail 设置服务gid失败
INIT_ESECCOMP 15 Set SECCOMP fail 设置服务安全策略
INIT_EUIDSET 16 Set uid fail 设置服务uid失败
INIT_ECAP 17 Set capability fail 设置服务capability失败
INIT_EWRITEPID 18 Write pid fail pid写入失败
INIT_ECONTENT 19 Set sub content fail 设置服务安全上下文失败
INIT_EPRIORITY 20 Set priority fail 设置服务优先级失败
INIT_EEXEC_CONTENT 21 Set exec content fail 设置selinux标签失败
INIT_EEXEC 22 Exec fail 执行exec失败

系统参数

错误码说明

枚举 枚举值 说明
PARAM_CODE_ERROR -1 系统错误
PARAM_CODE_SUCCESS 0 成功
PARAM_CODE_INVALID_PARAM 100 系统参数接口的入参为空
PARAM_CODE_INVALID_NAME 101 系统参数key不符合规范,长度或非法字符
PARAM_CODE_INVALID_VALUE 102 系统参数value值不符合规范,长度或非法字符
PARAM_CODE_REACHED_MAX 103 树节点已达最大值
PARAM_CODE_NOT_SUPPORT 104 不支持此接口
PARAM_CODE_TIMEOUT 105 访问服务端超时
PARAM_CODE_NOT_FOUND 106 没有找到该参数
PARAM_CODE_READ_ONLY 107 系统参数为只读参数
PARAM_CODE_IPC_ERROR 108 IPC通信异常
PARAM_CODE_NODE_EXIST 109 系统参数的节点存在
PARAM_WATCHER_CALLBACK_EXIST 110 watcher的callback重复添加
PARAM_WATCHER_GET_SERVICE_FAILED 111 watcher获取服务失败
PARAM_CODE_MEMORY_MAP_FAILED 112 建立文件共享内存映射失败
PARAM_WORKSPACE_NOT_INIT 113 workspace 没有初始化
PARAM_CODE_FAIL_CONNECT 114 连接paramServer 失败
PARAM_CODE_MEMORY_NOT_ENOUGH 115 系统参数空间不足
DAC_RESULT_INVALID_PARAM 1000 无用,定义权限错误的起始值
DAC_RESULT_FORBIDED 1001 DAC权限被禁止
SELINUX_RESULT_FORBIDED 1002 selinux权限被禁止
PARAM_CODE_MAX 1003 枚举最大值

错误定位关键日志

  • system parameter set:

    SetParameter failed! the errNum is: xx!

    SystemSetParameter failed! name is : xxx, errNum is: xx!

  • system parameter get:

    GetParameter_ failed! the errNum is: xx!

    SystemReadParam failed! name is: xxxx, errNum is: xx!

  • system parameter wait:

    WaitParameter failed! the errNum is: xx!

    SystemWaitParameter failed! name is: xxx, errNum is: xx!

  • system parameter Watcher:

    WatchParameter failed! the errNum is xx!

    SystemWatchParameter is failed! keyPrefix is:xxx, errNum is:xx!

1.6 主要配置文件说明

2. appspawn部件常见问题

2.1 应用孵化失败问题

原因分析:

  1. appspawn服务拉起失败。
  2. appspawn无权限或权限受限。
  3. 系统应用孵化失败。
  4. 沙盒配置失败。

解决方法:

  1. ps -ef | grep appspawn,查看appspawn 服务是否存在。
  2. 关闭selinux,重新验证,如果正常,则是selinux 策略配置不正确导致的,重新配置或添加对应的selinux权限。请参考base/security/selinux_adapter selinux 策略配置仓中的说明。
  3. ps -ef | grep ohos, 确定系统应用是否存在;确认系统应用权限, 关闭selinux, 重新验证,如果正常, 则是selinux 策略配置不正确导致,重新配置或添加对应的selinux权限。 selinux 策略配置 请参考 base/security/selinux_adapter 仓中的说明。
  4. 沙盒路径错误或selinux 权限不正确。关闭selinux, 重新验证,如果正常, 则是selinux 策略配置不正确导致,重新配置或添加对应的selinux权限。 selinux 策略配置 请参考 base/security/selinux_adapter 仓中的说明。

2.2 应用沙箱问题

原因分析:

  1. 沙盒路径配置错误。
  2. 权限受限。

解决方法:

  1. 检查沙盒路径是否存在错误。
  2. 权限受限会导致mount失败,报permission denied 错误,对于应用沙盒。 可以通过nsenter -t -m /bin/sh 命令查看。关闭selinux, 重新验证,如果正常, 则是selinux 策略配置不正确导致,重新配置或添加对应的selinux权限。 selinux 策略配置 请参考 base/security/selinux_adapter 仓中的说明。

3. 整机启动常见问题

3.1 开机过程介绍

请参考系统开机启动过程

3.2 整机常见问题

3.2.1. 卡在开机Logo界面

  1. 原因分析:init 二级启动没有完成。 解决方法:执行begetctl setloglevel 0并重启设备,通过串口查看内核日志。 确认init的二级启动是否正常完成, 关键log如下:
[32.173144][pid=1] [Init] [INFO] [init.c:206]Start init second stage.
[33.173144][pid=1] [Init] [DEBUG] [init.c:206]Parse init configs from /etc/init.cfg.

​ 如果此时hdcd服务没有启动,或者分区没有挂载好,无法执行begetctl 命令。需要修改init 代码,设置log等级。确保init 的debug log能正常输出。

  1. 原因分析:init.cfg 解析失败。

    1. cfg json格式错误。
    2. 无法正确解析:无权限或权限受限。

    解决方法:

    1. 排查cfg文件json格式, init cfg文件遵循json格式,按要求修改cfg文件。
    2. 日志中有 permission denied,init 进程报权限问题。1. 判断是否是selinux 导致的,关闭selinux 重新验证,如果正常,无权限报错。则是selinux 策略配置不正确导致的。 请配置正确的selinux 策略。selinux 策略配置,请参考base/security/selinux_adapter 仓中的说明。
  2. 原因分析:required mount 分区没有正常挂载。

    1. cmdline中没有配置或格式错误。
    2. ramdisk中没有fstag.requried 文件。

    解决方法:

    1. 查看日志, 查看Kernel command line 中是否required mount 分区配置; 如果配置, 查看cmdline格式是否出错,按照格式修改或添加命令。

      [0.000000] Kernel command line: currentslot=0 bootslots=0 rw rootwait earlycon=uart8250,mmio32,0xfe660000 console=ttyFIQ0 ohos.boot.eng_mode=on root=PARTUUID=614e0000-0000 hardware=rk3568 default_boot_device=fe310000.sdhci ohos.required_mount.system=/dev/block/platform/fe310000.sdhci/by-name/system@/usr@ext4@ro,barrier=1@wait,required ohos.required_mount.vendor=/dev/block/platform/fe310000.sdhci/by-name/vendor@/vendor@ext4@ro,barrier=1@wait,required ohos.required_mount.misc=/dev/block/platform/fe310000.sdhci/by-name/misc@none@none@none@wait,required ohos.required_mount.bootctrl=/dev/block/platform/fe310000.sdhci/by-name/bootctrl@none@none@none@wait,required

      或 在设备中通过cat /proc/cmdline 查看。

      或 在设备中通过cat /proc/cmdline 查看。

    2. 查看 ramdisk.img 中是否存在fstab.required文件。

  3. 原因分析:图形服务没有启动, 导致无开机动画。

    1. ps -ef 查看图形服务是否存在。

    解决方案: 根据日志定位问题。

  4. 原因分析: bootanimation 启动失败。

    1. 查看bootanimation服务是否被拉起。
    2. 判断bootanimation是否被重复拉起。

    解决方法:

    1. 在日志中查看log:

      [10.175192] [pid=1] [Init] [INFO] [init_service_manager.c:1088]Start service bootanimation

      表示服务启动。

  5. 原因分析:data分区没有正常挂载

    1. 设备分区表没有配置userdata分区。
    2. device的fstab 中没有给出data分区的挂载配置。
    3. device 给的fstab中配置的文件系统与userdata 镜像实际的文件系统不匹配。如fstab 中配置的是ext4, 而userdata 镜像实际的文件系统是f2fs。

    解决方法:

    对应的关键内核日志:

    1. "wait for file:/dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata failed after"。
    2. 日志中看不到userdata 任何挂载相关的输出。
    3. "Mount /dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata to /data failed", 如果fstab 配置了nofail, log 有"Mount no fail device /dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata to /data failed" nofail,表示该设备的挂载,不可以失败。

3.2.2. 卡在开机动画界面

原因分析:

  1. 开机动画没有正常退出。
  2. 系统应用孵化失败。
  3. 服务上报bootevent不完整,所有注册了bootevent 的服务,没有全部上报。

解决方法:

  1. 查看服务是否在反复重启, 重启服务是否配置critical。
  2. ps -ef | grep ohos, 确定系统应用是否存在;日志中有 permission denied,init进程报权限问题。 确认系统应用权限,关闭selinux, 重新验证,如果正常, 则是selinux 策略配置不正确导致,重新配置或添加对应的selinux权限。 selinux 策略配置 请参考base/security/selinux_adapter 仓中的说明。
  3. 通过bootevent事件分析, 通过排查没有上报的bootevent的服务, 可能会导致开机动画卡死,比如systemUI。

3.2.3. 自动重启

原因分析:

  1. init服务中定义“importance”的属性。
  2. critcial 使能, 关键进程符合critical 会重启。
  3. init进程挂掉会导致panic。

解决方法:

  1. 小型系统中服务配置importance属性为0,importance: 0重启, 1 不重启。
  2. 关键进程服务配置critcial 会导致进程重启。
  3. CloseStdio();之前执行execv("/bin/sh", NULL)。

3.2.4. reboot命令无法重启

原因分析:

  1. reboot 插件安装失败。
  2. reboot 命令错误。
  3. ohos.startup.powerctrl reboot 系统参数设置失败。
  4. reboot selinux 权限受限。

解决方法:

  1. 插件安装成功,在板子中查看/system/lib/init/reboot/librebootmodule.z.so是否安装成功。
  2. 执行begetctl setloglevel 0设置日志级别,日志打印:
 08-10 18:48:07.653  1421  1421 D C02c0b/BEGET: [init_reboot_innerkits.c:51]Reboot cmd reboot

​ 查看 reboot 命令, reboot命令不超过96。

  1. hdc shell 执行param set ohos.startup.powerctrl reboot, 观察是否重启, 重启表示系统参数设置成功。
  2. 日志中有 permission denied,init 进程报权限问题。关闭selinux, 重新验证, 如果验证成功,则是selnux策略配置不正确导致, 重新配置或添加对应的selinux权限。 selinux 策略配置 请参考base/security/selinux_adapter 仓中的说明。

3.2.5. 系统参数设置失败

原因分析:

  1. 没有DAC权限。
  2. 没有对应的selinux权限。
  3. parameter 的初始化失败。
  4. parameter 的内存不足。
  5. socket 超时,可能是init 没有及时响应parameter 请求。

解决方法:

  1. 配置dac权限。 请参考系统参数DAC访问控制定义文件
  2. selinux权限受限。 selinux 策略配置, 请参考base/security/selinux_adapter 仓中的说明。 系统参数配置selinux策略
  3. 权限受限。 1. selinux权限受限,请参考 selinux 策略配置 2. 初始化内存不足,请参考系统参数标签文件大小配置
  4. 申请内存。请参考 系统参数标签文件大小配置
  5. 权限受限。

3.2.6. 系统/芯片沙盒问题

  • 原因分析: 相关服务访问不到所需要的so等资源文件

  • 解决方案: 分析hilog,通过分析log检查失败的原因,在设备中搜索报错so的path,修改对应so的BUILD.gn文件。如下步骤:

    • log分析,hilog搜索关键字"failed"或".so"结果

      08-05 17:27:29.302   488   488 E C02500/driver_loader_full: get driver entry failed, /vendor/lib/libcamera_host_service_1.0.z.so load fail, Error loading shared library libdisplay_buffer_proxy_1.0.z.so: No such file or directory (needed by /system/lib/chipset-pub-sdk/libdisplay_buffer_hdi_impl.z.so)
      08-05 17:27:29.303   488   488 E C02500/devhost_service_full: DevHostServiceAddDevice failed and return -207
      08-05 17:27:29.305   488   488 E C02500/devhost_service_stub: Dis patch failed, add service failed and ret is -207
      08-05 17:27:29.307   488   488 I C02500/devhost_service_stub: add device 0x7000201
      08-05 17:27:29.308   488   488 E C02500/driver_loader_full: /vendor/lib/libhdi_media_layer_service.z.so no valid, errno:2
    • 根据结果,camera报错是由于libdisplay_buffer_proxy_1.0.z.so加载失败,两种方式进行处理,方式一在沙盒中对该file进行mount进行快速修复(仅支持本地debug,源码修改需要进行评审),方式二需要修改对应BUILD.gn文件

      • 快速修复方式:沙盒中mount file/path

        • 系统沙盒: 编辑设备中/system/etc/sandbox/system-sandbox.json文件,默认只mount vendor路径下的部分文件,如有报错缺失在其中进行单独mount

        • chipset沙盒: 编辑设备中/system/etc/sandbox/chipset-sandbox.json文件,默认只mount system路径下的部分文件,如有报错缺失在其中进行单独mount

        • 如上case需要在/system/etc/sandbox/chipset-sandbox.json中添加如下:

        "mount-bind-files" : [
        	{
                "src-path" : "/system/lib/libdisplay_buffer_proxy_1.0.z.so",
                "sandbox-path" : "/system/lib/libdisplay_buffer_proxy_1.0.z.so",
                "sandbox-flags" : [ "bind", "rec", "private" ]
            },{...}
        ],
      • 方式二:添加innerapi_tags

        ohos_shared_library("xxx") {
        	...
        	innerapi_tags = [
            	"chipsetsdk",
            ]
        }
      • innerapi_tags相关:

        • 沙盒权限相关的tags包含"passthrough"、"chipsetsdk"、"passthrough_indirect "、"chipsetsdk_indirect"

        • 可通过 Openharmony实时架构信息网站查看so信息,如果是间接依赖模块使用chipsetsdk_indirect或者passthrough_indirect , 其余使用chipsetsdk或者passthrough

        • 安装到系统目录的so使用"chipsetsdk"和"chipsetsdk_indirect",供芯片组件访问

        • 安装到芯片目录的so使用"passthrough"和"passthrough_indirect ",供系统组件访问

        • 通过innerapi_tags标记添加可以指定so安装的路径,比如标记了chipsetsdk的就装在/lib/chipset-sdk/目录下,具体逻辑源码如下,代码路径: build/templates/cxx/cxx.gni

        # auto set auto_relative_install_dir by innerapi_tags
        if (defined(invoker.innerapi_tags)) {
            is_chipsetsdk = false
            is_platformsdk = false
            is_passthrough = false
            foreach(tag, filter_include(invoker.innerapi_tags, [ "chipsetsdk*" ])) {
              is_chipsetsdk = true
            }
            foreach(tag, filter_include(invoker.innerapi_tags, [ "platformsdk*" ])) {
              is_platformsdk = true
            }
            foreach(tag, filter_include(invoker.innerapi_tags, [ "passthrough*" ])) {
              is_passthrough = true
            }
            if (is_chipsetsdk && is_platformsdk) {
              auto_relative_install_dir = "chipset-pub-sdk"
            } else if (is_chipsetsdk) {
              auto_relative_install_dir = "chipset-sdk"
            } else if (is_platformsdk) {
              auto_relative_install_dir = "platformsdk"
            }
            if (is_passthrough) {
              auto_relative_install_dir = chipset_passthrough_dir
            }
            ...
        }

4. Init 日志记录机制梳理

4.1 Init 日志类型介绍

Init的日志记录主要分为hilog 和demsg, hilog主要记录系统业务流程相关的日志,demsg 记录内核相关的日志。

4.2 Init 日志级别的控制

init 日志级别分为五级,可以通过设置(INIT_DEBUG_LEVEL)persist.init.debug.loglevel参数来控制

InitLogLevel:
  INIT_DEBUG = 0,
  INIT_INFO,
  INIT_WARN,
  INIT_ERROR,
  INIT_FATAL

Kmsg 日志级别:

"<7>" =====> "DEBUG"
"<6>" =====> "INFO"
"<4>" =====> "WARNING"
"<3>" =====> "ERROR"
"<3>" =====> "FATAL"

4.3 Init 日志控制的关键宏

INIT_DMESG 控制是否记录内核日志 /dev/kmsg INIT_FILE 控制是否将日志写入文件 /data/init_agent/begetctl.log INIT_AGENT 控制是否走Hilog记录日志

关键接口:

  void EnableInitLog(InitLogLevel level) 使能log

  void SetInitLogLevel(InitLogLevel level) 设置log 的级别,控制日志的输出

  void StartupLog(InitLogLevel logLevel, uint32_t domain, const char *tag, const char *fmt, ...) 是init log的入口

STARTUP_LOGI 是对StartupLog 定义的宏,在头文件/base/startup/init/interfaces/innerkits/include/beget_ext.h中定义,其他log都是基于STARTUP_LOGI这个宏重定义的:

  • deviceInfo模块(init/device_info/idevice_info.h):
  DINFO_LOGI
  DINFO_LOGE
  DINFO_LOGV
  • Paran Js接口模块(init/interfaces/kits/jskits/src/native_parameters_js.h):
  PARAM_JS_LOGI
  PARAM_JS_LOGE
  PARAM_JS_LOGV
  PARAM_JS_LOGW
  • Shell模块(init/services/begetctl/shell/shell_utils.h):
  BSH_LOGI
  BSH_LOGE
  BSH_LOGV
  • LoopEvent模块(init/services/loopevent/utils/le_utils.h):
  LE_LOGI
  LE_LOGE
  LE_LOGV
  • Plugin 模块(init/services/modules/plugin_adapter.h):
  PLUGIN_LOGI
  PLUGIN_LOGE
  PLUGIN_LOGV
  PLUGIN_LOGW
  • Param 模块(init/services/param/include/param_utils.h):
  PARAM_LOGI
  PARAM_LOGE
  PARAM_LOGV
  PARAM_LOGW
  • ParameWatcher 模块(init/services/param/watcher/include/watcher_utils.h):
  WATCHER_LOGI
  WATCHER_LOGE
  WATCHER_LOGV
  • Init 流程部分的log 也是直接基于StartupLog 函数定义的宏,主要有(init/services/log/init_log.h):
  INIT_LOGV
  INIT_LOGI
  INIT_LOGW
  INIT_LOGE
  INIT_LOGF

空文件

简介

OpenHarmony启动子系统FAQ。 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/handyohos/ohos_startup_faqs.git
git@gitee.com:handyohos/ohos_startup_faqs.git
handyohos
ohos_startup_faqs
ohos_startup_faqs
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891