OpenHarmony-1.启动流程

  • OpenHarmony启动流程

1.kernel的启动

流程图如下所示:
在这里插入图片描述  OpenHarmony(简称OH)的标准系统的底层系统是linux,所以调用如下代码:

linux-5.10/init/main.c:
noinline void __ref rest_init(void)
{struct task_struct *tsk;int pid;rcu_scheduler_starting();/** We need to spawn init first so that it obtains pid 1, however* the init task will end up wanting to create kthreads, which, if* we schedule it before we create kthreadd, will OOPS.*/pid = kernel_thread(kernel_init, NULL, CLONE_FS);...
}
static int __ref kernel_init(void *unused)
{...if (!try_to_run_init_process("/sbin/init") ||!try_to_run_init_process("/etc/init") ||!try_to_run_init_process("/bin/init") ||!try_to_run_init_process("/bin/sh"))return 0;panic("No working init found.  Try passing init= option to kernel. ""See Linux Documentation/admin-guide/init.rst for guidance.");
}

  由于OH标准系统是基于kernel内核开发的,所以启动init进程,那么OH的init进程的入口为/base/startup/init/services/init/main.c中。

2.init 进程模块架构

在这里插入图片描述

  • 基础环境初始化:init 进程挂载 tmpfs 和 procfs,创建基本的 dev 设备节点,提供一个基本的根文件系统。

    • tmpfs:这是一个内存上的文件系统,用于存储临时数据,比如在启动期间创建的目录、缓存等。它不会持久化到磁盘,当系统重启时会自动清除。
    • procfs:这个文件系统提供内核运行时信息的接口,如进程列表、系统配置、硬件状态等。init进程通常会挂载procfs,以便在启动早期获取和管理这些信息。
  • 从/proc/cmdline中读取fstab分区表。

  • 热插拔事件监听:init 进程启动 ueventd 来监控内核中的设备热插拔事件,为新插入的 block 设备分区(如 system和 vendor 分区)创建相应的 dev 设备节点。当设备被插入或移除时,内核会通过 uevent(用户空间事件)机制发送消息给 ueventd。ueventd作为系统服务的一部分,负责监听这些netlink事件,并根据接收到的事件类型动态管理相应的设备节点。

  在OH中BUILD.gn用于编译构建模块的。

 base/startup/init/services/init/standard/BUILD.gn:15 init_common_sources = [16   "../init_capability.c",17   "../init_common_cmds.c",18   "../init_common_service.c",19   "../init_config.c",20   "../init_group_manager.c",21   "../init_service_file.c",22   "../init_service_manager.c",23   "../init_service_socket.c",24   "../main.c",25 ]33 ohos_executable("init") {34   sources = [35     "../adapter/init_adapter.c",36     "../standard/device.c",37     "../standard/fd_holder_service.c",38     "../standard/init.c",39     "../standard/init_cmdexecutor.c",40     "../standard/init_cmds.c",41     "../standard/init_control_fd_service.c",42     "../standard/init_jobs.c",43     "../standard/init_mount.c",44     "../standard/init_reboot.c",45     "../standard/init_service.c",46     "../standard/init_signal_handler.c",47     "../standard/switch_root.c",48   ]4950   modulemgr_sources = [51     "//base/startup/init/interfaces/innerkits/hookmgr/hookmgr.c",52     "//base/startup/init/interfaces/innerkits/modulemgr/modulemgr.c",53   ]54   sources += modulemgr_sources

  从BUILD.gn看到OH标准系统的init进程的入口就是init_common_sources的main.c。

base/startup/init/services/init/main.c:
#include <signal.h>
#include "init.h"
#include "init_log.h"static const pid_t INIT_PROCESS_PID = 1;int main(int argc, char * const argv[])
{int isSecondStage = 0;(void)signal(SIGPIPE, SIG_IGN);// Number of command line parameters is 2//从kernel启动的init进程并未携带任何参数,这里是init的第一阶段if (argc == 2 && (strcmp(argv[1], "--second-stage") == 0)) {isSecondStage = 1;}if (getpid() != INIT_PROCESS_PID) {INIT_LOGE("Process id error %d!", getpid());return 0;}EnableInitLog(INIT_INFO);//第一次这里走的是SystemPrepareif (isSecondStage == 0) {SystemPrepare();} else {LogInit();}SystemInit();//启动rcs进程SystemExecuteRcs();SystemConfig();SystemRun();return 0;
}

  这里将init进程的代码分成了通用的和特有的两部分,共同的代码均在 /base/startup/init/services/init/文件夹下,其中有lite/和standard/分别用来构建小型系统和标准系统的init进程。这里主要分析标准进程的启动流程。

2.1.SystemPrepare

  由于从kernel进程启动的init进程并未传递任何参数,所以会先执行SystemPrepare:

base/startup/init/services/init/standard/init.c:
225 void SystemPrepare(void)
226 {
227     MountBasicFs();     //挂载一些基本目录并创建一些设备节点
228     CreateDeviceNode();
229     LogInit();
230     // Make sure init log always output to /dev/kmsg.
231     EnableDevKmsg();
232     INIT_LOGI("Start init first stage.");
233     HookMgrExecute(GetBootStageHookMgr(), INIT_FIRST_STAGE, NULL, NULL);
234     // Only ohos normal system support
235     // two stages of init.
236     // If we are in updater mode, only one stage of init.
237     if (InUpdaterMode() == 0) {  //检查是否处于升级模式,如果没有处于升级模式,就进入init第二阶段
238         StartInitSecondStage();
239     }
240 }
  • SystemPrepare主要工作:
    挂载一些基本目录,比如/dev,/mnt,/storage,/dev/pts,/proc,/sys,/sys/fs/selinux,接着创建一些设备节点比如/dev/null,/dev/random,/dev/urandom 等,检查系统是否处于升级模式,如果不处于升级模式就启动init的第二阶段。

2.2.StartInitSecondStage

base/startup/init/services/init/standard/init.c
static void StartInitSecondStage(void)
{int requiredNum = 0;//从/proc/cmdline中读取fstab分区表Fstab *fstab = LoadRequiredFstab();char **devices = (fstab != NULL) ? GetRequiredDevices(*fstab, &requiredNum) : NULL;if (devices != NULL && requiredNum > 0) {//启动Ueventd进程int ret = StartUeventd(devices, requiredNum);if (ret == 0) {//挂载分区ret = MountRequriedPartitions(fstab);}FreeStringVector(devices, requiredNum);devices = NULL;ReleaseFstab(fstab);fstab = NULL;if (ret < 0) {// If mount required partitions failure.// There is no necessary to continue.// Just abortINIT_LOGE("Mount required partitions failed; please check fstab file");// Execute sh for debugging
#ifndef STARTUP_INIT_TESTexecv("/bin/sh", NULL);abort();
#endif}}if (fstab != NULL) {ReleaseFstab(fstab);fstab = NULL;}// It will panic if close stdio before execv("/bin/sh", NULL)CloseStdio();//启动init进程的第二阶段INIT_LOGI("Start init second stage.");SwitchRoot("/usr");// Execute init second stagechar * const args[] = {"/bin/init","--second-stage",NULL,};//启动init进程并传递参数--second-stage if (execv("/bin/init", args) != 0) {INIT_LOGE("Failed to exec \"/bin/init\", err = %d", errno);exit(-1);}
}
  • StartInitSecondStage函数主要就是读取分区表并挂载同时启动Ueventd进程接着再次调用init并传递–second-stage参数。这里的执行execv函数将不会返回,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样。只有调用失败了,它们才会返回一个-1,从原程序的调用点接着往下执行。所以接下来的都是init第二阶段的执行过程。再次启动init进程后,当然还是走到了/base/startup/init/services/init/main.c不过不同的是由于携带了–second-stage参数,所以会走到LogInit。接着串行执行SystemInit, SystemExecuteRcs,SystemConfig和SystemRun。

startup/init/services/etc/init.cfg

refer to

  • https://huaweicloud.csdn.net/64df3b15dc60580edc7735f4.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/14288.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

ANR分析实例

目录 一、ANR出的问题原因 二、日志分析 2.1 CPU 负载 2.2 内存 2.3 堆栈信息 三、案例分析 3.1 主线程无卡顿&#xff0c;处于正常状态堆栈 3.2 主线程执行耗时操作 3.3 主线程被锁阻塞 3.4 CPU被抢占 3.5 内存紧张导致ANR 3.6 系统服务超时导致ANR 3.7 Input dis…

知识库搭建:高企创新创业的智慧引擎与未来趋势

在当今这个科技迅猛发展的时代&#xff0c;高新技术企业&#xff08;简称“高企”&#xff09;作为推动经济社会进步的重要力量&#xff0c;正面临着前所未有的创新挑战与机遇。知识库&#xff0c;这一信息时代的关键工具&#xff0c;不仅汇聚了高企内部的丰富知识与经验&#…

D67【python 接口自动化学习】- python基础之数据库

day67 Python操作MySQL基础使用 学习日期&#xff1a;20241113 学习目标&#xff1a;MySQL数据库-- 136 Python操作MySQL基础使用 学习笔记&#xff1a; pymysql 创建MySQL的数据库链接 执行sql语句 总结 Python中使用第三方库&#xff1a;pymysql来操作MySQL&#xff0c;…

容器管理平台KubeSphere的使用

在之前的课程中我们是在minikube中安装了K8S环境,然后通过kubectl命令来管理K8S的,这种用命令来管理的方式虽然对程序员来说看起来很炫酷,但有时候用起来还是挺麻烦的。这节课程给大家介绍一款企业级容器管理平台KubeSphere,使用它能更方便地管理K8S中的容器,希望对大家有…

低代码可视化-uniapp气泡弹窗组件可视化-代码生成器

气泡弹窗组件是产品设计中常用的控件之一&#xff0c;以下是对uniapp气泡弹窗组件可视化的详细解析&#xff1a; 一、组件定义 气泡弹窗组件&#xff08;diy-popover &#xff09;指的是当触发某项操作时&#xff0c;在页面上方或特定位置展示的弹出层容器&#xff0c;容器内…

Unity3D学习FPS游戏(11)敌人AI巡逻(NavMesh)

前言&#xff1a;前面两篇博客已经实现了简单的敌人&#xff0c;但是呢&#xff0c;这样很无趣。因为敌人只会站在原地被攻击&#xff0c;所以本篇我们将实现敌人AI巡逻&#xff0c;让敌人动起来。 敌人AI巡逻 场景丰富一下导航网格NavMesh构建导航网格导航网格优化玩家被当作…

遇到“msvcr120.dll丢失”要怎么解决?详解msvcr120.dll的解决方法

遇到“msvcr120.dll丢失”错误通常表明你的系统缺少一个关键的DLL文件&#xff0c;这是Microsoft Visual C 2013的一部分。这个问题可能导致某些程序无法运行&#xff0c;影响电脑性能。不过&#xff0c;解决这一问题并不复杂。接下来&#xff0c;本文将向你展示几种简单的修复…

git相关知识

前言&#xff1a;在学习git之前首先需要了解几个概念&#xff1a;工作区&#xff0c;暂存区&#xff0c;版本库。 工作区&#xff1a;是电脑上写代码或者文件的目录。 暂存区&#xff1a;一般存放在.git目录下的index中&#xff0c;也称索引。&#xff08;git add&#xff09…

Spring Boot项目的配置文件有哪些?加载优先级谁最高?配置优先级谁最高?

目录 一. 结论 二. .prperties、.yml、.yaml 文件类型简介及注意点 2.1 文件简介 2.2. .prperties&#xff08;默认格式/传统格式&#xff09; 2.3 application.yml&#xff08;主流格式&#xff09; 2.4 application.yaml&#xff08;主流格式&#xff09; 2.5 配置文件…

蓝牙眼镜WT6900HA语音控制芯片方案:开启智能穿戴新篇章

前言&#xff1a; 随着科技的飞速发展&#xff0c;智能穿戴设备已经逐渐融入我们的日常生活。从智能手表到智能手环&#xff0c;再到如今的智能蓝牙眼镜&#xff0c;这些设备不仅改变了我们的生活方式&#xff0c;更引领了一场科技革命。 今天&#xff0c;我们要为大家介绍一款…

项目管理【02】项目开发完整指南

移动端项目开发完整指南&#xff1a;从需求到上线 在移动应用开发过程中&#xff0c;一个项目从最初的需求到最终上线&#xff0c;需要经过多个关键阶段。本文将详细介绍整个开发流程中的最佳实践&#xff0c;帮助开发团队更高效地完成项目。 一、准备阶段 项目启动前的准备工…

快手直播间采集教程,快手引流,快手截流,截流工具,直播间截流,快手直播间采集,获客系统,获客软件

功能&#xff1a; 1.输入快手直播间链接可一键监控直播间 2.可采集新进直播间的人 3.可采集直播间所有动作&#xff0c;包含&#xff1a;发弹幕的人和内容、送礼物的人和送的礼物、点亮爱心的人 4.可一键导出新进直播间的快手ID 5.可一键导出直播间动作列表&#xff0c;也可以筛…

sol机器人pump机器人如何实现盈利的?什么是Pump 扫链机器人?

什么是Pump 扫链机器人&#xff0c;它的盈利逻辑优化策略是什么&#xff1f; Pump 扫链机器人&#xff0c;通过智能化、自动化的买卖操作帮助投资者实现快速盈利。在此基础上&#xff0c;我们对该机器人的盈利逻辑进行了深度优化&#xff0c;涵盖了买入策略和止盈策略的各个方面…

【vue2】13.自定义指令

目录 自定义指令 自定义指令的作用? 自定义指令的使用步骤? 1. 注册 (全局注册 或 局部注册) 2. 标签上 v-指令名 使用 自定义指令 - 指令的值 1. 通过指令的值相关语法&#xff0c;可以应对更复杂指令封装场景 2. 指令值的语法&#xff1a; 自定义指令 - v-loading…

【LLM】Agent的相关Benchmark

note 文章目录 note一、SuperCLUE-Agent二、AgentBench三、跨系统benchmark&#xff1a;CRAB四、SWE-bench 一、SuperCLUE-Agent SuperCLUE-Agent是一个 Agent智能体中文原生任务能力测评基准&#xff0c;评估方面包括&#xff1a; 工具使用能力&#xff08;调用API、检索API、…

MATLAB用CNN-LSTM神经网络的语音情感分类深度学习研究

全文链接&#xff1a;https://tecdat.cn/?p38258 原文出处&#xff1a;拓端数据部落公众号 在语音处理领域&#xff0c;对语音情感的分类是一个重要的研究方向。本文将介绍如何通过结合二维卷积神经网络&#xff08;2 - D CNN&#xff09;和长短期记忆网络&#xff08;LSTM&…

机器学习基础03

目录 1.KNN算法-分类 1.1样本距离判断 1.1.1欧式距离 1.1.2曼哈顿距离 1.2KNN 算法原理 1.3KNN缺点 1.4API 2.模型选择与调优 2.1保留交叉验证 2.2K-折交叉验证 2.3分层k-折交叉验证Stratified k-fold 2.4其它验证 2.5API 3.模型保存与加载 3.1保存模型 3.2加…

【go从零单排】go语言中testing的几种类型

&#x1f308;Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 &#x1f4d7;概念 Go 语言中的 testing 包是用于编写和运行测试的标准库。它提供了丰富的功能&…

[笔记]自动化中破解验证码

01需求分析 1.打开一个chrome浏览器 2.输入论坛的网址: http://114.116.2.138:8090/forum.php 3.输入用户名admin 4.输入密码123456 5.点击登录 6.输入验证码 7.再点击登录 02准备工作 selenium环境搭建 参考地址: https://blog.csdn.net/python_jeff/article/details…

2024下半年软考系统架构设计师案例分析题试题与答案

解析中包含所有真题图片 解析中包含所有真题图片 解析中包含所有真题图片 解析中包含所有真题图片 第一题 解析见&#xff08;点我&#xff09;&#xff1a;https://blog.csdn.net/u014624241/article/details/143701384 第二题 解析见&#xff08;点我&#xff09;&#…