整包系统升级原理(结合海思源码分析)

 一.安装包的结构及作用

二.进入Recovery模式之前

三.之后再到Recovery模块的执行

四.安装过程

五.update-binary的执行流程

一.安装包的结构及作用

|boot.img//用来更新boot分区,由kernel和ramdisk(根文件系统的映射)组成

|logo.img//开机logo

|file_contexts//用于给 SELinux 监测和重新加载正确的文件上下文(amlogic升级包里有)

|META-INF/

|CERT.RSA以及CERT.SF//签名文件

|MANIFEST.MF//定义了与包的组成结构相关的数据

|com/

|android/

|metadate//包含一些设备信息及环境变量的元数据,如设备型号版本型号等

|otacert//ota证明

|google/

|android/

|update-binary//升级的可执行文件

|updater-script//升级的脚本文件

|recovery

|recovery-from-boot.p//是boot.img和recovery.img的补丁,主要用来更新recovery分区

|etc/

|install-recovery.sh//其更新脚本

|system//与盒子里对应的目录相同,在升级后会放到系统的system分区,可以更新系统的一些应用和应用 所需的一些库等

二.进入Recovery模式之前
Recovery中的三个部分,他的工作需要整个软件平台的配合,从通信架构上来看,主要有三个部分
1. MainSystem:正常启动模式(BCB中无命令),使用boot.img启动的Android的正常工作模式。更新时,系统的操作就是使用OTA或从SD卡中升级包。在重启进入Recovery模式之前,会向BCB中写入命令,会在重启后让bootloader进入Recovery模式
2.Recovery:系统进入Recovery模式后会装载Recovery分区,该分区包含recovery.img(同boot.img相同,包含了标准的内核和根文件系统)。进入该模式后主要是运行 Recovery服务(/sbin/recovery)来做相应的操作(重启、升级、擦除cache分区、擦除data分区等)
3. Bootloader:除了正常的加载启动系统之外,还会通过读取MISC分区(BCB)获得来至Main system和Recovery的消息

一般Android升级流程是,将安装包放到服务器上,然后由服务器向Android设备推送升级包。在盒子中有一个apk用于检测是否有版本更新,如果有更新包则下载,放置安装包的位置下载完成并校验成功后,通过调用系统的接口进入升级流程,还有就是Android的U盘升级apk升级

  系统下载安装包验证签名后会去调用installpackage

  调用接口RecoverySystem.installPackage(context, file);

代码位置:/frameworks/base/core/java/android/os/RecoverySystem.java

 

校验签名

开始获取文件的名字与路径,判断分区所处位置得到filename   最后获得arg的升级命令

--update_package=root:path: Mainsystem将这条命令写入command,/cache/recovery/command:这个文件保存着Mainsystem传给Recovery的命令行,会进行相应的更新升级包的操作

设立了一个属性sys.sw.immediately.upgrade来判断是立刻升级,还是稍后升级

将获取到的arg写到command里,代表系统要按照这个路径去升级这个文件,进入Recovery模式后,将该文件中的命令读取并写入BCB中

 

写完命令到command之后,调用powermanager.Java进行重启,创建线程锁住屏幕,使之常亮不关机,系统能继续运行

什么是BCB?

BCB(bootloader control block)是bootloader与Recovery的通信接口,也是Bootloader与Mainsystem之间的通信接口。他存储在flash中的MISC分区,占用三个page,其本身就是一个结构体,具体成员以及各成员含义如下:

struct bootloader_message{
char command[32];
char status[32];
char recovery[1024];
};
command成员:即当我们想要在重启进入Recovery模式时,会更新这个成员的值。另外在成功更新后结束Recovery时,会清除这个成员的值,防止重启时再次进入Recovery模式。

status成员:在完成相应的更新后,Bootloader会将执行结果写入到这个字段。
recovery成员:可被Main System写入,也可被Recovery服务程序写入。该文件内容格式为:“recovery\n   ...   \n”该文件存储的就是一个字符串,必须以recovery\n开头,否则这个字段的所有内容域会被忽略.“recovery\n”之后的部分,是/cache/recovery/command支持的命令。可以将其理解为Recovery操作过程中对命令操作的备份。

Recovery过程为:先读取BCB然后读取/cache/recovery/command,然后将二者重新写回BCB,这样在进入Mainsystem之前,可以确保操作被执行。在操作之后进入Mainsystem之前,Recovery又会清空BCB的command域和recovery域,这样确保重启后不再进入Recovery模式

三.之后再到Recovery模块的执行

代码路径bootable/recovery/recovery.cpp

 

直接到main函数里面查看代码,如果启动的参数带有adbd,就执行sideload方式安装,sideload:

接收更新包文件,将之改名为update.zip,放在/tmp/目录下,等到recovery发现update.zip,后面的安装步骤就一致了

 

  1. load_volume_table作用根据存储芯片类型来读取不同的分区表

  1. 读取recovery的启动参数,先执行升级的命令,再读取BCB中的命令,

最后再执行/cache/recovery/command文件的命令

 

  1. 调用make_device(),创建device对象,执行ui对象初始化,显示输出界面

SELinux 等同于进程,对象是被访问的资源(文件,端口等),主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)

  1. 系统升级准备工作

 

确定使用升级包的路径

 

  1. 读取参数中的命令,执行更新系统的命令,调用install_package()进行安装;

 

  1. 根据命令来擦除指定位置的数据

 

 

  1. 执行出错显示界面,根据参数关闭或重启系统

四.安装过程

代码位置bootable/recovery/install.cpp

被调用的函数install_package()

 

作为安装入口,检查的路径,调用really_install_package()继续安装

 

  1. 校验签名,ui显示

 

2判断芯片是否符合,调用try_update_binary继续安装

 

 

将zip里面的META-INF/com/google/android/update-binary拷贝到/tmp/update-binary

创建子进程,调用脚本update-binary来更新系统文件

 

 

五.update-binary的执行流程

路径bootable/recovery/updater/update.c

 

在更新的过程会通过管道通知父进程更新ui显示

 

 


执行升级脚本之前进行 mlcverify的信息读取判断 flash 类型是否为nand。获取mlcverify失败的时候 mlcverify没有烧写mlcverify损坏依然允许进行升级

 

 

调用脚本进行升级

 

脚本Update-script

 

 

Update-script的作用可以通过getprop获取属性,show_process显示安装进度,通过mount安装system分区到/system目录,通过package_extract_dir 将包里system目录下的文件安装到/system目录下,symlink建立系统中的符号连接,set_perm赋予文件权限

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值