Android的init进程是如何启动的

这里我就PXA的代码为例,说下Android系统是如何起来的,特别是Android启动的第一个进程,init进程是如何启动的。

首先uboot会通过bootargs把rdinit的所在路径传递给kernel-->

run_command("setenv bootargs rdinit=/busybox/rdinit cpmem=16M reserve_pmem=0x3000000 comm_v75 android uart_dma", 0);

可以看到红色部分即需要传递的路径地址,然而rdinit是什么呢,这里先简单说下所谓rdinit其实就是一个板级相关的脚本,里面会决定从哪启动ramdisk?nfs?mmc?等等,

那么好我们接下来看kernel里接收这个参数的函数,所在文件kernel/init/main.c

static int __init rdinit_setup(char *str)
{
 unsigned int i;

 ramdisk_execute_command = str;
 /* See "auto" comment in init_setup */
 for (i = 1; i < MAX_INIT_ARGS; i++)
  argv_init[i] = NULL;
 return 1;
}
__setup("rdinit=", rdinit_setup);

内核会把路径传递给全局变量ramdisk_execute_command,并通过

sys_access((const char __user *) ramdisk_execute_command, 0)函数执行rdinit脚本,脚本里会执行rootfs下的init,而这个init是android里的用户程序,位置在system/core/init/init.c

下面我们来简单讲下rdinit脚本,以PXA的这份rdinit为例,它做了这么几件事

1. rdinit_prepare,这个函数里主要为init进程启动作准备,mount proc sysfs等工作

2. 根据dev来判断从哪里启动,

for dev in $ROOTFS_DEV ; do
    if [ "$dev" = "flash" ]; then
        try_boot_from_ramdisk $INIT_MTDBLK
        continue
    fi
    if [ "$dev" = "nfs" ]; then
        if try_prepare_network ; then
            for type in $ROOTFS_TYPE ; do
                if [ "$type" = "android" ]; then
                    try_boot_from_android_nfs
                fi
                if [ "$type" = "generic" ]; then
                    try_boot_from_rootfs_nfs
                fi


            done
        fi
    fi
    if [ "$dev" = "mmc0" ]; then
        try_boot_from_ramdisk "$INIT_MMCBLK"0
        if [ $? = 0 ]; then
            try_boot_from_mmc 0
        fi
        continue
    fi
    if [ "$dev" = "mmc1" ]; then
        try_boot_from_ramdisk "$INIT_MMCBLK"1
        if [ $? = 0 ]; then
            try_boot_from_mmc 1
        fi
        continue
    fi
done

接下去就是跑android init进程了,写的比较的粗略,具体的细节还是需要自己去看代码体会。

你可能感兴趣的:(Android的init进程是如何启动的)