android动态分区AB升级,Android A/B System OTA分析(四)系统的启动和升级

Android从7.0开始引入新的OTA升级方式,A/B System Updates,这里将其叫做A/B系统,涉及的内容较多,分多篇对A/B系统的各个方面进行分析。本文为第四篇,系统的启动和升级。

本文基于AOSP 7.1.1_r23 (NMF27D)代码进行分析。

1. 系统的启动

1.1 bootloader检查slot metadata

系统复位后,bootloader会去读取boot_control私有的存储数slot metadata并进行解析,以此确定从哪一个slot启动。

以下是Android官方的一个bootloader加载流程图:

d90b52da66c75deb60a84ff1af88d681.png1.2 linux系统的启动

上一步中,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,但如果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,进入哪一个系统。

加载android系统的命令行参数

skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity "

例如Broadcom的7252SSFFDR3参考平台的启动Android系统的参数为:

mem=1016m@0m mem=1024m@2048m bmem=339m@669m bmem=237m@2048m \

brcm_cma=784m@2288m \

ramoops.mem_address=0x3F800000 ramoops.mem_size=0x800000 ramoops.console_size=0x400000 \

buildvariant=userdebug \

veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f buildvariant=eng \

rootwait init=/init ro \

root=/dev/dm-0 dm="system none ro,0 1 android-verity PARTUUID=c49e0acb-1b38-95e5-548a-2b7260e704a4" skip_initramfs

除去rootf

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值