android8.1系统启动过程(二) init进程

android init进程  init进程源码位置 system/core/init/init.cpp  编译后init系统中的位置在 /init    第一个应用程序

-rwxr-x---   1 root   root   1855344 1970-01-01 08:00 init    init.c生成的可执行文件  也是系统第一个进程 守护进程
generic_x86_64:/ # ps -A
USER           PID  PPID     VSZ    RSS WCHAN            ADDR S NAME                       
root             1     0   12000   2580 ep_poll        53455a S init

init.cpp  源码分析    AOSP/system/core/init/init.cpp

              --  创建目录(下电消失) 挂载分区

                   其中挂载了  tmpfs    挂载目录 /dev 、

                                       devpts    挂载目录 /dev/pts  、

                                       proc    挂载目录 /proc、

                                       sysfs    挂载目录 /sys、

                                       selinuxfs    挂载目录 /sys/fs/selinux

                     系统运行时目录

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));
        // Don't expose the raw commandline to unprivileged processes.
        chmod("/proc/cmdline", 0440);
        gid_t groups[] = { AID_READPROC };
        setgroups(arraysize(groups), groups);
        mount("sysfs", "/sys", "sysfs", 0, NULL);
        mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
        mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
        mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
        mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));

              --  解析启动脚本(服务、操作、环境变量)

              --  启动服务

              --  守护服务


InitKernelLogging(argv);   初始化内核log

/dev/kmsg   内核的log

generic_x86_64:/dev # cat kmsg
6,0,0,-;Initializing cgroup subsys cpu
6,1,0,-;Initializing cgroup subsys cpuacct
5,2,0,-;Linux version 3.18.74+ (android-build@wpiv11.hot.corp.google.com) (gcc version 4.9 20140827 (prerelease) (GCC) ) #1 SMP PREEMPT Thu Oct 12 17:13:17 UTC 2017
6,3,0,-;Command line: qemu=1 androidboot.hardware=ranchu clocksource=pit android.qemud=1 console=0 android.checkjni=1 qemu.gles=1 qemu.encrypt=1 qemu.opengles.version=131072 cma=262M androidboot.android_dt_dir=/sys/bus/platform/devices/ANDR0001:00/properties/android/ ramoops.mem_address=0xff018000 ramoops.mem_size=0x10000 memmap=0x10000$0xff018000
6,4,0,-;e820: BIOS-provided physical RAM map:

property_init();    对属性进行初始化

start_property_service();    启动属性服务


signal_handler_init();    AOSP/system/core/init/signal_handler.cpp

设置子进程信号处理函数用于防止init进程的子进程成为僵尸进程[1]    系统会在子进程结束或者终止的时候发出  SIGCHLD信号  signal_handler_init()  就是用来接收SIGCHLD信号的


export_kernel_boot_props();  

    得到硬件信息和版本 

generic_x86_64:/ # cat /proc/cpuinfo                                           
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
prop_map[] = {
        { "ro.boot.serialno",   "ro.serialno",   "", },
        { "ro.boot.mode",       "ro.bootmode",   "unknown", },
        { "ro.boot.baseband",   "ro.baseband",   "unknown", },
        { "ro.boot.bootloader", "ro.bootloader", "unknown", },
        { "ro.boot.hardware",   "ro.hardware",   "unknown", },
        { "ro.boot.revision",   "ro.revision",   "0", },
    };
generic_x86_64:/ # getprop ro.hardware                                         
ranchu

export_kernel_boot_props();

  解析内核启动参数 主要是解析uboot输入的参数 

prop_map[] = {
        { "ro.boot.serialno",   "ro.serialno",   "", },
        { "ro.boot.mode",       "ro.bootmode",   "unknown", },
        { "ro.boot.baseband",   "ro.baseband",   "unknown", },
        { "ro.boot.bootloader", "ro.bootloader", "unknown", },
        { "ro.boot.hardware",   "ro.hardware",   "unknown", },
        { "ro.boot.revision",   "ro.revision",   "0", },
    };

     内核启动参数查看

generic_x86_64:/ # cat /proc/cmdline                                           
qemu=1 androidboot.hardware=ranchu clocksource=pit android.qemud=1 console=0 android.checkjni=1 qemu.gles=1 qemu.encrypt=1 qemu.opengles.version=131072 cma=262M androidboot.android_dt_dir=/sys/bus/platform/devices/ANDR0001:00/properties/android/ ramoops.mem_address=0xff018000 ramoops.mem_size=0x10000 memmap=0x10000$0xff018000

property_load_boot_defaults()    AOSP/system/core/property_service.cpp

    导入默认环境变量

void property_load_boot_defaults() {
    if (!load_properties_from_file("/system/etc/prop.default", NULL)) {
        // Try recovery path
        if (!load_properties_from_file("/prop.default", NULL)) {
            // Try legacy path
            load_properties_from_file("/default.prop", NULL);
        }
    }
    load_properties_from_file("/odm/default.prop", NULL);
    load_properties_from_file("/vendor/default.prop", NULL);

    update_sys_usb_config();
}
generic_x86_64:/ # cat default.prop                                            
#
# ADDITIONAL_DEFAULT_PROPERTIES
#
ro.secure=0
ro.allow.mock.location=1
ro.debuggable=1
#
# BOOTIMAGE_BUILD_PROPERTIES
#
ro.bootimage.build.date=2020年 12月 17日 星期四 14:36:12 CST
ro.bootimage.build.date.utc=1608186972
ro.bootimage.build.fingerprint=Android/aosp_x86_64/generic_x86_64:8.1.0/OPM1.171019.011/godv12171436:eng/test-keys
persist.sys.usb.config=adb
generic_x86_64:/ # getprop ro.debuggable                                       
1

DoFirstStageMount()  

    挂载 system、vendor 等系统分区   Android8.1 系统将 system、vendor 分区的挂载功能移植到 kernel device-tree 中进行。在 kernel 的 dts 文件中,需要包含如下的 firmware 分区挂载节点,在 DoFirstStageMount 函数执行过车用中会检查、读取 device-tree 中记录的分区挂载信息

bool DoFirstStageMount() {
    // Skips first stage mount if we're in recovery mode.
    if (IsRecoveryMode()) {
        LOG(INFO) << "First stage mount skipped (recovery mode)";
        return true;
    }

    // Firstly checks if device tree fstab entries are compatible.
    if (!is_android_dt_value_expected("fstab/compatible", "android,fstab")) {
        LOG(INFO) << "First stage mount skipped (missing/incompatible fstab in device tree)";
        return true;
    }

    std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create();
    if (!handle) {
        LOG(ERROR) << "Failed to create FirstStageMount";
        return false;
    }
    return handle->DoFirstStageMount();
}

 


[1]僵尸进程    子进程终止后父进程不知道子进程已经终止  系统进程表中还存有子进程的一定信息(进程号、退出状态、运行时间)  此时这个进程被称之为僵尸进程  

                       系统进程表如果被耗尽  系统就无法创建新的进程了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值