OpenHarmony开发手册:Release的init程序启动流程规范

159 篇文章 1 订阅
159 篇文章 0 订阅

一、启动概述

在产品代码成功编译通过后,开始进行下一步的运行调测阶段,而运行调测第一步便需要了解系统的启动过程。对于 OpenHarmony 来说,系统启动流程如下:

---> uboot启动
    ---> uboot启动内核
        ---> 内核挂载根文件系统(此时为ramdisk文件系统)
            ---> 运行ramdisk中的第一个程序
                ---> 根据fstab中内容挂载文件系统
                    ---> 切换root路径为/usr
                        ---> 第一个程序为init则进行系统初始化
                        ---> 第一个程序为init_early则通过execv启动init

关于 uboot 启动到内核挂载根文件系统部分属于 Linux 内容,这里不做介绍,以下我们开始来介绍从 ramdisk 启动的第一个程序,我们以 init_early 模式为例开启我们新的篇章

二、ramdisk 文件系统介绍

2.1 什么是 ramdisk 文件系统

ramdisk 是一种将内存中的的一块区域作为物理磁盘来使用的一种技术,也可以说,ramdisk 是在一块内存区 域中创建的块设备,用于存放文件系统。对于用户来说,可以把 ramdisk 与通常的硬盘分区同等对待来使用。ramdisk 不适合作为长期保存文件的介质,掉电后 ramdisk 的内容会消失。

2.2 ramdisk 文件系统和 ramdisk.img 有什么关系

在 Linux 中,根文件系统是需要挂载到实际的物理磁盘中的,而 ramdisk.img 便是 ramdisk 文件系统挂载的磁盘,即 ramdisk.img 是 ramdisk 文件系统的打包镜像。
可以对比 rootfs,我们通过 busybox 制作出来的是 rootfs 文件系统,但是实际启动使用的时候我们时我们需要将 rootfs 文件系统打包制作成 rootfs.ext4 一样。

三、init_early 程序介绍

3.1 init_early 程序注意事项

init_early 程序作为第一个启动的程序,由于当前挂载的文件系统为 ramdisk 文件系统,该系统的目的仅仅是为了拉起 OpenHarmony 真正的文件系统,可以说仅仅是为了 init_early 程序的运行,因此内部的库很少,仅有以下内容,所以 init_early 程序仅可以依赖以下这些库

wen_fei@rh-Z790-UD:~/OpenHarmony/dayu800-v4.1-release/out/dayu800/packages/phone/ramdisk/lib64
$ tree
.
├── chipset-pub-sdk
│   ├── libpcre2.z.so
│   ├── libsec_shared.z.so
│   └── libselinux.z.so
├── libclang_rt.asan.so
├── libc++.so
├── libc.so
├── libinit_module_engine.so -> libinit_stub_empty.so
├── libinit_stub_empty.so
├── libload_policy.z.so
└── platformsdk
    └── librestorecon.z.so

3.2 为什么要有 init_early 程序

作为第一个基于 ramdisk 文件系统启动的程序,能够依赖的库有限,因此能实现的功能相对也不能复杂,通过使用 init_early 拉起 init 进程可以在尽可能减小 ramdisk.img 大小的同时很好的让 init 程序开发更加丰富的内容。
其次如果 init 程序加载有问题也可以通过 init_early 程序先启动到 shell,然后在 shell 中运行 init 进行调测。
以上内容均为个人猜想。

3.3 init_early 代码路径

该部分代码的编译参考:base/startup/init/services/init/standard/BUILD.gn
其 main 函数位于:base/startup/init/services/init/standard/main_early.c

3.4 init_early 代码介绍

从其 main_early.c 代码中可以看出 init_early 主要完成以下几个功能

  • 忽略终端信号,将 SIGPIPE 交给系统处理

  • 使能 InitLog 的 INIT_INFO 级别(非核心)

  • 初始化 EarlyLog(非核心)

  • 创建常用的文件和设备节点

  • 执行钩子函数,一般钩子链表是通过__attribute__((constructor))构造的函数添加的

  • 确实是否为升级模式

  • 根据 ramdisk 镜像中的 fstab 文件挂载镜像

  • 启动第二阶段 init

    • 关闭 stdio(此时便不能通过 printf 打印 log)
    • 切换 root 路径为/usr(system 文件系统)
    • 让 init 程序代码当前的 init_early 程序进行

注意这里是程序不是进程,因为 init_early 在 ramdisk 中是软链接为 init,因此进程对应的是 init,而不是 init_early

四、init 启动介绍

4.1 init 运行前准备工作

由于 init_early 的铺垫,此时 init 启动的实际文件系统已经不在 ramdisk 文件系统中了,而是位于 system 文件系统中。因此链接库的路径指定是通过 etc/ld-musl-namespace-riscv64.ini 该文件中设置的路径按照顺序链接的,所以首先必须确定 system 镜像中是否有该文件。
在 init 程序中有很多函数通过 MODULE_CONSTRUCTOR 将其添加到了 Hook 链表中,在 init 实际运行的时候会调用 HOOK 的执行接口,将所有的预处理函数调用执行。

4.2 init 启动失败调测

如果 init_early 加载 init 程序运行直接失败,我们可以在 init_early 最后添加如下代码后让串口进入 shell,然后在 shell 中直接运行 init 跟踪定位

execv("/bin/sh", NULL);

4.3 init 启动的流程

这部分就通过 init 的 main 函数进行阅读理解了,注意 HOOK 链表项都是通过 MODULE_CONSTRUCTOR 接口在 main 函数执行前添加的,详细请了解 gcc 的 __attribute__((constructor)) 属性
init 的 main 函数位于:base/startup/init/services/init/main.c

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为资料太多,太杂,教授的人也多,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

为了确保高效学习,建议规划清晰的学习路线,涵盖以下关键阶段:

 →【纯血版鸿蒙全套最新学习资料】希望这一份鸿蒙学习资料能够给大家带来帮助~


 鸿蒙(HarmonyOS NEXT)最新学习路线

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频学习资料+学习PDF文档

HarmonyOS Next 最新全套视频教程 (鸿蒙语法ArkTS、TypeScript、ArkUI教程……)

​​

 纯血版鸿蒙全套学习资料(面试、文档、全套视频等)

                   

​​​​鸿蒙APP开发必备

​​

总结

【纯血版鸿蒙全套最新学习资料】

总的来说,华为鸿蒙不再兼容安卓,对程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,才能在这个变革的时代中立于不败之地。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值