Android7.0探索之旅--init进程

当kernel通过run_init_process启动init进程后,进入system/core/init/init.cpp的main函数,标志着进入用户空间。在main函数中,根据启动参数判断系统启动阶段。第一阶段会挂载文件系统,初始化selinux,并重新执行init,转变为init domain。通过log可观察到kernel启动结束。接着,解析init.rc文件,启动服务,进入无限循环执行命令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进入用户空间

在kernel中通过run_init_process来执行init进程,之后就会进入system/core/init/init.cpp的main函数,这才真正的进入用户空间。

进入main函数后,会进行判断是否是系统启动的第一阶段,只有启动参数中有--second-stage才为第二阶段

bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);

如果现在为系统启动的第一阶段, 就开始获取基本的文件系统,我们需要将他们放在一起处理。挂载文件系统到相应的目录。

    // Get the basic filesystem setup we need put together in the initramdisk
    // on / and then we'll let the rc file figure out the rest.
    if (is_first_stage) {
        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
        mkdir("/dev/pts", 0755);
        mkdir("/dev/socket", 0755);
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
        #define MAKE_STR(x) __STRING(x)
        mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
        mount("sysfs", "/sys", "sysfs", 0, NULL);
    }
对klog进行初始化,设置klog level为NOTICE,所以可以将NOTICE级别的log输出,而INFO级别的log就打印不出来

具体原因,请阅读Android7.0 klog机制

    klog_init();
    klog_set_level(KLOG_NOTICE_LEVEL);

系统启动流程的关键log来了,可以通过该行log知道init进程启动起来了,也表示kernel启动结束。大家注意klog level为NOTICE所以可以打印出来。

    NOTICE("init %s started!\n", is_first_stage ? "first stage" : "second stage");
//示例log , 我们可以通过时间戳2.042999s, 获得从开始启动kernel到进入init花费多长时间,也就是开机过程中kernel耗时情况。
[01-01 08:26:55.194] <13>[    2.042999] c3 init: init first stage started!

如果为第一阶段的话会对selinux进行初始化

    // Set up SELinux, including loading the SELinux policy if we're in the kernel domain.
    selinux_initialize(is_first_stage);

selinux初始化函数,我们可以修改该函数,本地手动开关selinux来调试问题。

static void selinux_initialize(bool in_kernel_domain) {
    Timer t;       //使用Timer计时,计算selinux初始化耗时

    selinux_callback cb;
    cb.func_log = selinux_klog_callback;
    selinux_set_callback(SELINUX_CB_LOG, cb);
    cb.func_audit = audit_callback;
    selinux_set_callback(SELINUX_CB_AUDIT, cb);

    if (in_kernel_domain) {   //第一阶段in_kernel_domain为true
        INFO("Loading SELinux policy...\n");   //该行log打印不出,INFO级别
        if (selinux_android_load_policy() < 0) {
            ERROR("failed to load policy: %s\n", strerror(errno));
            security_failure();
        }

        bool kernel_enforcing = (security_getenforce() == 1);
        bool is_enforcing = selinux_is_enforcing();
        if (kernel_enforcing != is_enforcing) {
            if (security_setenforce(is_enforcing)) {      //设置selinux的模式,是开还是关
                ERROR("security_setenforce(%s) failed: %s\n",
                      is_enforcing ? "true" : "false", strerror(errno));
                security_failure();
   
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值