概述
一.安装包的结构及作用
二.进入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服务程序写入。该文件内容格式为:“recoveryn ... n”该文件存储的就是一个字符串,必须以recoveryn开头,否则这个字段的所有内容域会被忽略.“recoveryn”之后的部分,是/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,后面的安装步骤就一致了
- load_volume_table作用根据存储芯片类型来读取不同的分区表
- 读取recovery的启动参数,先执行升级的命令,再读取BCB中的命令,
最后再执行/cache/recovery/command文件的命令
- 调用make_device(),创建device对象,执行ui对象初始化,显示输出界面
SELinux 等同于进程,对象是被访问的资源(文件,端口等),主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)
- 系统升级准备工作
确定使用升级包的路径
- 读取参数中的命令,执行更新系统的命令,调用install_package()进行安装;
- 根据命令来擦除指定位置的数据
- 执行出错显示界面,根据参数关闭或重启系统
四.安装过程
代码位置bootable/recovery/install.cpp
被调用的函数install_package()
作为安装入口,检查的路径,调用really_install_package()继续安装
- 校验签名,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赋予文件权限
最后
以上就是魁梧大地为你收集整理的整包系统升级原理(结合海思源码分析)的全部内容,希望文章能够帮你解决整包系统升级原理(结合海思源码分析)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复