【鸿蒙南向开发】OpenHarmony——分区切换之reboot源码解析

简介

系统在执行升级操作时,执行指令reboot updater,对misc分区写入相关信息,然后重启系统进行分区切换操作,加载updater分区并执行OTA升级,本文仅介绍reboot的操作原理,以下内容主要基于v3.0-Release版进行分析。

代码路径

base\startup\init_lite\services\cmds\reboot\init_cmd_reboot.c
base\startup\init_lite\interfaces\innerkits\reboot\init_reboot.c
base\startup\init_lite\services\src\init_reboot.c

目录结构

base/startup/init_lite/             # init组件
├── LICENSE
└── services
    ├── include                  # init组件头文件目录
    ├── src                      # init组件源文件目录
    └── test                     # init组件测试用例源文件目录
        └── unittest
vendor
└──huawei
        └──camera
                └──init_configs  # init配置文件目录(json格式,镜像烧写后部署于/etc/init.cfg)

init_cmd_reboot.c文件位于init组件中,init组件负责处理从内核加载第一个用户态进程开始,到第一个应用程序启动之间的系统服务进程启动过程。启动恢复子系统除负责加载各系统关键进程之外,还需在启动的同时设置其对应权限,并在子进程启动后对指定进程实行保活(若进程意外退出要重新启动),对于特殊进程意外退出时,启动恢复子系统还要执行系统复位操作。

流程图

image.png

源码解读

1.init_cmd_reboot.c文件的main函数

在命令行输入reboot updater指令,会调用到下面的函数中:

int main(int argc, char* argv[])
{
    if (argc > REBOOT_CMD_NUMBER) { //判断输入参数是否合法
        printf("usage: reboot shutdown\n       reboot updater\n       reboot updater[:options]\n       reboot\n");
        return 0;
    }
    if (argc == REBOOT_CMD_NUMBER && strcmp(argv[1], "shutdown") != 0 &&
        strcmp(argv[1], "updater") != 0 &&
        strncmp(argv[1], "updater:", strlen("updater:")) != 0) {
        printf("usage: reboot shutdown\n       reboot updater\n       reboot updater[:options]\n       reboot\n");
        return 0;
    }
    int ret;
    if (argc == REBOOT_CMD_NUMBER) {
        ret = DoReboot(argv[1]);
    } else {
        ret = DoReboot(NULL);
    }
    if (ret != 0) {
        printf("[reboot command] DoReboot Api return error\n");
    } else {
        printf("[reboot command] DoReboot Api return ok\n");
    }
    while (1) {
        pause();
    }
    return 0;
}

main函数中主要作用是识别reboot指令,执行DoReboot操作。

2.DoReboot函数中的libuv库

int DoReboot(const char *cmdContent)
{
    uid_t uid1 = getuid();
    uid_t uid2 = geteuid();//鉴权操作,reboot需要在root权限下执行
    if (uid1 != 0 || uid2 != 0) {
        INIT_LOGE("uid1=%d, uid2=%d, user MUST be root, error!", uid1, uid2);
        return -1;
    }
    //省略部分不重要代码
    /...
    .../
    if (snprintf_s(value, MAX_REBOOT_NAME_SIZE, MAX_REBOOT_NAME_SIZE - 1, "%s%s", "reboot,", cmdContent) < 0) {
        IN
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值