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]僵尸进程 子进程终止后父进程不知道子进程已经终止 系统进程表中还存有子进程的一定信息(进程号、退出状态、运行时间) 此时这个进程被称之为僵尸进程
系统进程表如果被耗尽 系统就无法创建新的进程了