Android P init进程reboot流程和调试方法

Android中的init进程是安卓系统用户空间启动的第一个进程。

相关源码:
system\core\reboot\reboot.c
system\core\init\init.cpp
system\core\init\reboot.cpp

inti进程源码路径为:
system/core/init/

reboot启动路程
reboot是一个二进制可执行文件,其源码路径为:
system\core\reboot

该目录只有两个文件,一个编译文件,一个c文件:
Android.bp
reboot.c

在system\core\reboot目录下编译,生成reboot可执行文件,生成目录在system/bin中

当我们在执行reboot命令时,就是执行的system/bin/reboot

int main(int argc, char* argv[]) {
    int ret;
    size_t prop_len;
    char property_val[PROPERTY_VALUE_MAX];
    static const char reboot[] = "reboot";
    const char* cmd = reboot;
    char* optarg = "";

    opterr = 0;
    do {
        int c;



        c = getopt(argc, argv, "p");

        if (c == -1) {
            break;
        }

        switch (c) {
        case 'p':
            cmd = "shutdown";
            break;
        case '?':
            fprintf(stderr, "usage: %s [-p] [rebootcommand]\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    } while (1);

    if(argc > optind + 1) {
        fprintf(stderr, "%s: too many arguments\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    if (argc > optind)
        optarg = argv[optind];
    if (!optarg || !optarg[0]) optarg = "shell";

    prop_len = snprintf(property_val, sizeof(property_val), "%s,%s", cmd, optarg);
    if (prop_len >= sizeof(property_val)) {
        fprintf(stderr, "%s command too long: %s\n", cmd, optarg);
        exit(EXIT_FAILURE);
    }

    ret = property_set(ANDROID_RB_PROPERTY, property_val);
    if (ret < 0) {
        perror(cmd);
        exit(EXIT_FAILURE);
    }

    // Don't return early. Give the reboot command time to take effect
    // to avoid messing up scripts which do "adb shell reboot && adb wait-for-device"
    if (cmd == reboot) {
        while (1) {
            pause();
        }
    }

    fprintf(stderr, "Done\n");
    return 0;
}

这里我们主要看ret = property_set(ANDROID_RB_PROPERTY, property_val);

#define ANDROID_RB_PROPERTY “sys.powerctl”

即设置了属性值sys.powerctl为“reboot,adb”或者“reboot,shell”或者“shutdown,shell”或者“reboot,-p”

“reboot,adb”,表示在adb中输入adb reboot进行重启
“reboot,shell”,表示在shell中输入reboot进行重启
“shutdown,shell”,表示在shell中输入reboot -p进行关机
“reboot,-p”,表示在adb中输入adb reboot -p进行关机

system/core/init/init.cpp

void property_changed(const std::string& name, const std::string& value) {
    // If the property is sys.powerctl, we bypass the event queue and immediately handle it.
    // This is to ensure that init will always and immediately shutdown/reboot, regardless of
    // if there are other pending events to process or if init is waiting on an exec service or
    // waiting on a property.
    // In non-thermal-shutdown case, 'shutdown' trigger will be fired to let device specific
    // commands to be executed.
    if (name == "sys.powerctl") {
		
		//property_set("vendor.reboot", "reboot");
		
        // Despite the above comment, we can't call HandlePowerctlMessage() in this function,
        // because it modifies the contents of the action queue, which can cause the action queue
        // to get into a bad state if this function is called from a command being executed by the
        // action queue.  Instead we set this flag and ensure that shutdown happens before the next
        // command is run in the main init loop.
        // TODO: once property service is removed from init, this will never happen from a builtin,
        // but rather from a callback from the property service socket, in which case this hack can
        // go away.
        shutdown_command = value;
        do_shutdown = true;
        
        
    }

    if (property_triggers_enabled) ActionManager::GetInstance().QueuePropertyChange(name, value);

    if (waiting_for_prop) {
        if (wait_prop_name == name && wait_prop_value == value) {
            LOG(INFO) << "Wait for property took " << *waiting_for_prop;
            ResetWaitForProp();
        }
    }
}

property_changed中监听了系统属性的变化,并且在sys.powerctl属性变化时,将do_shutdown = true;

我们再来看main函数中的执行:

int main(int argc, char** argv) {
    while (true) {
        // By default, sleep until something happens.
        int epoll_timeout_ms = -1;

        if (do_shutdown && !shutting_down) {
            do_shutdown = false;
            //modify by sunxiaolin 20191030
            LOG(INFO) << "sunxiaolin,init,sys.powerctl reboot or shutdown sleep(5000)!";
            property_set("vendor.reboot", "reboot");
            if (!(waiting_for_prop || Service::is_exec_service_running())) {
				//LOG(INFO) << "sunxiaolin,init,ExecuteOneCommand!";
            	am.ExecuteOneCommand();
        	}
        
            sleep(3);
        
            if (HandlePowerctlMessage(shutdown_command)) {
                shutting_down = true;
            }
        }

		//modify by sunxiaolin 20191105
        if (!(waiting_for_prop || Service::is_exec_service_running())) {
            am.ExecuteOneCommand();
        }
	}
}

如果收到sys.powerctl属性的变化,条件do_shutdown && !shutting_down得到满足,将执行:
HandlePowerctlMessage

system\core\init\reboot.cpp

bool HandlePowerctlMessage(const std::string& command) {
    unsigned int cmd = 0;
    std::vector<std::string> cmd_params = Split(command, ",");
    std::string reboot_target = "";
    bool run_fsck = false;
    bool command_invalid = false;

    if (cmd_params.size() > 3) {
        command_invalid = true;
    } else if (cmd_params[0] == "shutdown") {
        cmd = ANDROID_RB_POWEROFF;
        if (cmd_params.size() == 2) {
            if (cmd_params[1] == "userrequested") {
                // The shutdown reason is PowerManager.SHUTDOWN_USER_REQUESTED.
                // Run fsck once the file system is remounted in read-only mode.
                run_fsck = true;
            } else if (cmd_params[1] == "thermal") {
                // Turn off sources of heat immediately.
                TurnOffBacklight();
                // run_fsck is false to avoid delay
                cmd = ANDROID_RB_THERMOFF;
            }
        }
    } else if (cmd_params[0] == "reboot") {
        cmd = ANDROID_RB_RESTART2;
        if (cmd_params.size() >= 2) {
            reboot_target = cmd_params[1];
            // When rebooting to the bootloader notify the bootloader writing
            // also the BCB.
            if (reboot_target == "bootloader") {
                std::string err;
                if (!write_reboot_bootloader(&err)) {
                    LOG(ERROR) << "reboot-bootloader: Error writing "
                                  "bootloader_message: "
                               << err;
                }
            } else if (reboot_target == "recovery") {
                std::string err;
                if (!write_reboot_recovery(&err)) {
                    LOG(ERROR) << "reboot-recovery: Error writing "
                                  "recovery_message: "
                               << err;
                }
            }
            // If there is an additional parameter, pass it along
            if ((cmd_params.size() == 3) && cmd_params[2].size()) {
                reboot_target += "," + cmd_params[2];
            }
        }
    } else {
        command_invalid = true;
    }
    if (command_invalid) {
        LOG(ERROR) << "powerctl: unrecognized command '" << command << "'";
        return false;
    }

    LOG(INFO) << "Clear action queue and start shutdown trigger";
    ActionManager::GetInstance().ClearQueue();
    // Queue shutdown trigger first
    ActionManager::GetInstance().QueueEventTrigger("shutdown");
    // Queue built-in shutdown_done
    auto shutdown_handler = [cmd, command, reboot_target, run_fsck](const BuiltinArguments&) {
        DoReboot(cmd, command, reboot_target, run_fsck);
        return Success();
    };
    ActionManager::GetInstance().QueueBuiltinAction(shutdown_handler, "shutdown_done");

    // Skip wait for prop if it is in progress
    ResetWaitForProp();

    // Clear EXEC flag if there is one pending
    for (const auto& s : ServiceList::GetInstance()) {
        s->UnSetExec();
    }

    return true;
}

编译
在system/core/init下面mm,生成symbols/init

调试
直接push到根目录生效
adb push Z:\imx8_p9.0.0_2.1.0_auto_ga\android9.0.0\out\target\product\mek_8q\symbols\init /

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaolin2016

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值