1. 介绍
init进程是Linux系统第一个用户进程,是Android系统应用程序的根进程,即1号进程(PID为1);Android中的init文件位于/init,代码位于system/core/init目录
Linux中第一个进程为init_task,也即0号进程(PID为0),init进程由init_task进程fork而来,在kernel初始化完成后init_task便化身为idle进程
更多内核初始化init_task和init进程的信息,参考
2. 云竹
if (!strcmp(basename(argv[0]), "ueventd")) { return ueventd_main(argc, argv); } if (!strcmp(basename(argv[0]), "watchdogd")) { return watchdogd_main(argc, argv); } if (argc > 1 && !strcmp(argv[1], "subcontext")) { InitKernelLogging(argv); const BuiltinFunctionMap function_map; return SubcontextMain(argc, argv, &function_map); } if (REBOOT_BOOTLOADER_ON_PANIC) { InstallRebootSignalHandlers(); }
2.1 ueventd和watchdogd
在Android.mk中
LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \ ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \ ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd
这里是在/sbin/目录下创建init的软连接,因为ueventd和watchdogd应用的代码也位于init目录中,通过程序名称来决定运行的代码
而在system/core/rootdir/init.rc文件中
on early-init ... start ueventd ... service ueventd /sbin/ueventd class core critical seclabel u:r:ueventd:s0 shutdown critical
由此可见,ueventd会在init解析rc文件的early-init阶段被执行;而watchdogd由厂商来定制是否要运行
2.2 信号处理
当编译userdebug或者eng版本时,会在Android.mk中打开REBOOT_BOOTLOADER_ON_PANIC选项,该选项打开时会注册init进程的特殊信号处理函数,当init收到SIGABRT、SIGBUS、SIGSEGV等异常信号时Android系统将进入bootloader模式
3. 第一阶段
init中根据环境变量INIT_SECOND_STAGE来决定运行代码,首先是运行第一阶段,在第一阶段结束时设置环境变量,然后通过execv系统调用重新执行init程序,随后执行第二阶段
3.1 挂载文件系统
首先挂载了如下文件系统
---------------------------------------------- | 设备 | 类型 | 挂载目录 | ---------------------------------------------- | tmpfs | tmpfs | /dev | | devpts | devpts | /dev/pts | | proc | proc | /proc | | sysfs | sysfs | /sys | | selinuxfs | selinuxfs | /sys/fs/selinux | | tmpfs | tmpfs | /mnt | ----------------------------------------------
创建如下文件夹
/dev/socket: 用于Android套接字
创建如下字符设备文件
/dev/kmsg: 1/11 /dev/kmsg_debug: 1/11 /dev/random: 1/8 /dev/urandom: 1/9
参考: