Android用的linux内核,以完成OS该有的功能,例如,文件系统,网络,内存管理,进程调度,驱动等 ,向下管理硬件资源向上提供系统调用。另一些Android特有驱动也放在内核之中。
 当linux内核启动完成后,便进行Android的初始化工作。
内核端
内核是在main.c中进行初始化,从kernel_init开始
static int __init kernel_init(void * unused)
{
	lock_kernel();
	/*
	 * init can run on any cpu.
	 */
	set_cpus_allowed_ptr(current, CPU_MASK_ALL_PTR);
	/*
	 * Tell the world that we're going to be the grim
	 * reaper of innocent orphaned children.
	 *
	 * We don't want people to have to make incorrect
	 * assumptions about where in the task array this
	 * can be found.
	 */
	init_pid_ns.child_reaper = current;
	cad_pid = task_pid(current);
	smp_prepare_cpus(setup_max_cpus);
	do_pre_smp_initcalls();
	start_boot_trace();
	smp_init();
	sched_init_smp();
	cpuset_init_smp();
	do_basic_setup();
	/*
	 * check if there is an early userspace init.  If yes, let it do all
	 * the work
	 */
	if (!ramdisk_execute_command)
		ramdisk_execute_command = "/init";
	if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
		ramdisk_execute_command = NULL;
		prepare_namespace();
	}
	/*
	 * Ok, we have completed the initial bootup, and
	 * we're essentially up and running. Get rid of the
	 * initmem segments and start the user-mode stuff..
	 */
	init_post();
	return 0;
}
在main.c 函数init_post()开始执行Android相关代码
	if (ramdisk_execute_command) {
		run_init_process(ramdisk_execute_command);
		printk(KERN_WARNING "Failed to execute %s\n",
				ramdisk_execute_command);
	}
	/*
	 * We try each of these until one succeeds.
	 *
	 * The Bourne shell can be used instead of init if we are
	 * trying to recover a really broken machine.
	 */
	if (execute_command) {
		run_init_process(execute_command);
		printk(KERN_WARNING "Failed to execute %s.  Attempting "
					"defaults...\n", execute_command);
	}
	run_init_process("/sbin/init");
	run_init_process("/etc/init");
	run_init_process("/bin/init");
	run_init_process("/bin/sh");
run_init_process便是加载执行文件。可以看到有六处出现了这个函数,但是执行的是第一个,
 也就是run_init_process(ramdisk_execute_command), 变量ramdisk_execute_command在kernel_init执行时被赋值为’/init’, 也就是说,将会执行根文件目录下的init进程,而这个进程正是Android的初始化进程.
Android端
在根目录下可以看到init是个软链接,真正的init文件在/system/bin下面
 
 进入目录,真身就在里面

 加载执行后,就是大家耳熟能详的init进程了,开始进入Android的世界。
int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
    __asan_set_error_report_callback(AsanReportCallback);
#endif
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }
    if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
            return SubcontextMain(argc, argv, &function_map);
        }
        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
        }
        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
        }
    }
    return FirstStageMain(argc, argv);
}
init可执行文件的命名
在源码/system/core/init目录下查看mk和bp文件,在文件Android.mk中
LOCAL_MODULE := init_first_stage
LOCAL_MODULE_STEM := init
在文件Android.bp中
cc_binary {
    name: "init_second_stage",
    recovery_available: true,
    stem: "init",
    defaults: ["init_defaults"],
    static_libs: ["libinit"],
    required: [
        "e2fsdroid",
        "init.rc",
        "mke2fs",
        "sload_f2fs",
        "make_f2fs",
        "ueventd.rc",
    ],
    srcs: ["main.cpp"],
    symlinks: ["ueventd"],
    target: {
        recovery: {
            cflags: ["-DRECOVERY"],
            exclude_shared_libs: [
                "libbinder",
                "libutils",
            ],
        },
    },
}
在Android 11源码中,mk文件和bp文件还是共存的,但mk在编译时会被转换成bp文件。在初始化的过程中,与Android密切相关的又分为两个阶段,但无论在第一阶段,还是第二阶段,其stem都是init。



















