安卓8 Android O 进入recovery判断流程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shangyexin/article/details/86565711

bootloader会根据slot metadata确定读取哪一个slot的boot分区进行启动。

每一个slot上有两个rootfs:

  • boot分区自带recovery mode的ramdisk;
  • system分区包含了Android系统的rootfs;

启动中,如何选择加载boot分区的ramdisk还是system分区的rootfs呢?
答案是由kernel的命令行参数skip_initramfs来决定。

下面来看skip_initramfs参数是如何起作用的。

系统同时包含init\noinitramfs.c和init\initramfs.c的代码,并在initramfs.c模块中定义并解析skip_initramfs参数:

# init\initramfs.c
static int __initdata do_skip_initramfs;

static int __init skip_initramfs_param(char *str)
{
    if (*str)
        return 0;
    # 设置do_skip_initramfs标志
    do_skip_initramfs = 1;
    return 1;
}
//用于解析命令行的`skip_initramfs`参数
__setup("skip_initramfs", skip_initramfs_param);

如果命令行设置了skip_initramfs,则do_skip_initramfs会被设置为1。

linux调用populate_rootfs默认会并加载boot分区自带的ramdisk(recovery),但如果do_skip_initramfs被设置为1,则会调用default_rootfs生成一个极小的rootfs:

# init\initramfs.c
static int __init populate_rootfs(void)
{
    char *err;

    # 如果do_skip_initramfs置1,则调用default_rootfs生成一个极小的rootfs
    if (do_skip_initramfs)
        return default_rootfs();

    //没有设置do_skip_initramfs的情况下,才会解析并加载`boot`分区所包含的`ramdisk`
    err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
    if (err)
        panic("%s", err); /* Failed to decompress INTERNAL initramfs */
    ...
    return 0;
}

default_rootfs的内容很简单,用于在内存中生成一个极小的rootfs,仅包含/dev和root两个文件夹以及一个设备节点/dev/console:

# init\noinitramfs.c
/*
 * Create a simple rootfs that is similar to the default initramfs
 */
static int __init default_rootfs(void)
{
    int err;
    // 创建/dev文件夹用于存放/dev/console设备节点
    err = sys_mkdir((const char __user __force *) "/dev", 0755);
    if (err < 0)
        goto out;
    # 创建/dev/console设备节点
    err = sys_mknod((const char __user __force *) "/dev/console",
            S_IFCHR | S_IRUSR | S_IWUSR,
            new_encode_dev(MKDEV(5, 1)));
    if (err < 0)
        goto out;
    # 创建/root目录,作为根用户root的home
    err = sys_mkdir((const char __user __force *) "/root", 0700);
    if (err < 0)
        goto out;

    return 0;

out:
    printk(KERN_WARNING "Failed to create a rootfs\n");
    return err;
}

因此skip_initramfs参数决定了加载哪一个rootfs,进入哪一个系统。

展开阅读全文

没有更多推荐了,返回首页