RK3228H开发之Rockchip Recovery及android系统升级详解

假如想象 提交于 2020-02-08 04:25:57

一、引言

Recovery 模式指的是一种可以对安卓机内部的数据或系统进行修改的模式,(类似于 windows pe 或 DOS)。在这个模式下我们可以刷入新的安卓系统,或者对已有的系统进行备份或升级,也可以在此恢复出厂设置,本篇文章即来介绍下Rockchip中的recovery

二、Recovery 模式在框架层的位置

Android 启动后,会先运行 bootloader。Bootloader 会根据某些判定条件决定是否进入 recovery 模式。Recovery 模式会装载 recovery 分区,该分区包含 recovery.img。Recovery.img 包含了标准内核(和boot.img 中的内核相同)以及 recovery 根文件系统。
Android recovery 三个部分两个接口,recovery 的工作需要整个软件平台的配合,从架构角度看,有三个部分:

  1. Main System: 用 boot.img 启动的 Linux 系统,Android 的正常工作模式。
  2. Recovery:用 recovery.img 启动的 Linux 系统,主要是运行 recovery 程序。
  3. Bootloader:除了加载、启动系统,还会通过读取 flash 的 MISC 分区获得来自 Main System 和Recovery 的消息,并以此决定做何种操作。

两个通信接口:
/cache/recovery/:command、log、intent
BCB(Bootloader Control Block):misc 分区

Main System 如何进入 Recovery 模式

Main System 如何进入 Recovery 模式:当我们在 Main System 使用 update.zip 包进行升级时,系统会重启并进入 recovery 模式。在系统重启前,我们可以看到 Main System 定会向 recovery 域写入boot-recovery,用来告知 bootloader 重启后进入 Rcovery 模式。这一步是必须的,至于Main System 是否会向 recovery 域写入值我们在源码中不能肯定这一点。即便如此,重启进入 Recovery模式后,Bootloader 会从/cache/recovery/command 中读取值并放入到 BCB 的 recovery 域。而 MainSystem 在重启之前肯定会向/cache/recovery/command 中写入 Recovery 将要进行的操作命令。
在这里插入图片描述
1.installPackage: RecoverySystem 的接口,完成升级包路径转换,并调用 bootCommand。
2.bootCommand:RecoverySystem 的接口,将命令写入/cache/recovery/command,并调用pm.reboot。
3.Pm.reboot:PowerManager 的接口,重启并进入 Recovery 模式。

三、 OTA 包

OTA (over the air)升级是 Android 系统提供的标准软件升级方式。它功能强大,提供了完全升级(完整包)、增量升级模式(差异包),可以通过本地升级,也可以通过网络升级。

生成完整包

完整包所包含内容:system、recovery、boot.img
发布一个固件正确的顺序:

  1. make -j4
  2. make otapackage -j4
  3. ./mkimage.sh ota

发布固件必须使用./mkimage.sh ota,将 boot 与 kernel 打包,不需要单独烧 kernel,如果量产固件是分开的,将会影响后面差异包升级,除非你不需要用差异升级。
在 out/target/product/rkxxxx/目录下会生成 ota 完整包 rkxxxx-ota-eng.root.zip,改成update.zip 即可拷贝到 T 卡或者内置的 flash 进行升级。

生成差异包

OTA 差异包只有差异内容,包大小比较小,主要用于 OTA 在线升级,也可 T 卡本地升级。OTA 差异包制作需要特殊的编译进行手动制作。
(1)首先发布 v1 版本的固件,生成 v1 版本的完整包
(2)保存
out/target/product/rkxxxx/obj/PACKAGING/target_files_intermediates/rk3188-target_files-eng.root.zip 为 rkxxxx-target_files-v1.zip,作为 v1 版本的基础素材包。
(3)修改 kernel 代码或者 android 代码,发布 v2 版本固件,生成 v2 版本完整包
(4)保存
out/target/product/rkxxxx/obj/PACKAGING/target_files_intermediates/rk3188-target_files-eng.root.zip 为 rkxxxx-target_files-v2.zip,作为 v2 版本的基础素材包。
(5)生成 v1-v2 的差异升级包:
./build/tools/releasetools/ota_from_target_files -v -i rkxxxx-target_files-v1.zip-p out/host/linux-x86 -k build/target/product/security/testkey rkxxxx-target_files-v2.zip out/target/product/rk3188/rkxxxx-v1-v2.zip

说明: 生成差异包命令格式:
ota_from_target_files
-v -i 用于比较的前一个 target file
-p host 主机编译环境
-k 打包密钥
用于比较的后一个 target file
最后生成的 ota 差异包

注意事项

完整包和素材包是不一样的。
从生成差异包的方法可以知道,差异包是两个版本的素材包做差异生成,所以每发布一个版本固件必须保存 obj 下的素材包以及升级的完整包和./mkimage.sh ota 生成的各个 imgage。
如果有使用在线升级,必须给每个版本固件配置唯一的 ota 版本号:device/rockchip/rksdk/rksdk.mk 中的ro.product.version = 1.0.0(也可以是其他格式的版本号字符串)

四、RK 平台分区升级说明

1、RkLoader 升级

Loader 升级操作步骤

a) 将需要升级的 loader,以 RKLoader.bin 格式放到 device/rockchip/rkxxxx/ota/loader 目录下,OTA 打包时就会加入到升级包中。

注意事项:

a) android5.1 放到目录 device/rockchip/common/loader,如果没有请创建。
b) android 4.4 放到目录 device/rockchip/rksdk/loader,如果没有请创建。
c) Loader 必须保证版本号比固件中的版本号更高。

2、Parameter 升级

parameter 升级操作步骤:

a) 将需要升级的 parameter 文件到 device/rockchip/rkxxxx/ota/parameter/目录下,以parameter 名称开头即可,如 parameter_sdk。该目录下只能存在一个 parameter 文件。

目前谷歌标准 ota 包方式升级能支持 parameter 更新,但有一些限制:

a) 更新 parameter 只能使用 ota 完整包升级,不支持差异升级 parameter。
b) 根据 RK29 Parameter File Format Ver1.1.pdf 描述,backup 区不能改大,只能改小。如果想
改大 backup 区,必须擦除 idb,所以本机升级不能去改大 backup 区。
c) backup 区以及之前的分区大小和位置不能改变。之后的分区能随意改变和增加分区。
d) user 区可能被改变,所以不支持升级包放在内部 falsh 的升级,只能放在外部 sd 卡升级。或者能保证其所在分区位置大小不变。
e) recovery 区的地址不能改变,否则重启后就找不到 recovery 了。

注意事项:

a) android5.1 放到目录 device/rockchip/common/parameter/目录下,如果没有请创建。
b) Android4.4 放到目录 device/rockchip/rksdk/parameter/目录下,如果没有请创建。

3、Uboot、trust 升级

4、Resource 升级

Resource.img,已经默认包含在boot.img和recover.img里面了,所以不建议再单独对resource.img进行升级。

5、releasetool 说明

releasetool 是一个描述 RK 平台分区升级的 Python 脚本

五、Update.img 升级方式

可以将 update.img 存到 SD 卡根目录,USB 根目录,内部存储/data/media/0/ 下,如果系统检测到有该包,会自动检测包是否合法,如果合法会重启进入 recovery 模式,并进行升级

打包说明

  1. 进入到目录 RKTools/linux/Linux_Pack_Firmware/rockdev/
  2. 修改 package-file 文件,指向生成 img 的路径,或者将 img 拷贝进来。
  3. Parameter.txt : 确认你的 parameter.txt 中 MACHINE_MODEL 的值是否正确,该值将用来校验 img包是否合法,并且不能包含空格
  4. 运行 mkupdate.sh 脚本,会在该目录下生成 update.img,将拷贝到目标路径,即可进行升级

六、Recovery配置

1、Log重定向

Log 可以输出到串口、SD 卡、/cache/recovery/、三个地方
修改 bootable/recovery/Android.mk 文件

REDIRECT_LOG_TO := UART  将日志输出到串口
REDIRECT_LOG_TO := CACHE 将日志输出到/cache/recovery/目录下
REDIRECT_LOG_TO := SDCARD  将日志输出到 SD 卡中
2、屏幕旋转

修改 device/rockchip/common/BoardConfig.mk 文件

ROTATE_SCREEN := rotate_0 不旋转
ROTATE_SCREEN := rotate_90 旋转 90°
ROTATE_SCREEN := rotate_180  旋转 180°
ROTATE_SCREEN := rotate_270  旋转 270°
BOARD_HAS_FLIPPED_SCREEN := true 旋转 180°,针对 LCD 屏幕装反情况。
3、屏幕分屏

Recovery 屏幕分屏,将屏幕分为左右两部分,显示内容一样,用于 VR 功能。
修改 bootable/recovery/Android.m 文件:

DOUBLE_SCREEN := NO 不分屏
DOUBLE_SCREEN := YES  分屏
4、文件保存

将文件保存到/cache/recovery/Recovery_*,格式化不会清除该文件

5、RecoveryUI 说明

recovery 作为一个简单的 rootfs,提供非常有限的几个功能,只包含了几个简单的库,UI 显示采用的是直接刷 framebuffer 的形式。首先浏览一下 recovery main 函数里面的流程
在这里插入图片描述
如上代码所示,make_device()函数返回一个 Device 设备,所以我们只需要继承 Device 类(一些虚函数接口),就可对 RecoveryUI 进行简单的修改。
自定义 recovery 菜单与按键实现
修改 device/rockchip/common/BoardConfig.mk 文件

TARGET_RECOVERY_UI_LIB ?= librecovery_ui_rk30sdk

device/rockchip/common/recovery,里面有例子,可修改或参照

6、支持 EXT4 文件系统

修改 device/rockchip/common/BoardConfig.mk 文件

TARGET_USERIMAGES_USE_EXT4 ?= true
7、Update.img drm 签名校验

update.img 在升级时进行 drm 签名校验,防止第三方非法固件升级。Update.img 必须使用secureboot 工具签名,并勾选 sign check 复选框。
修改 device/rockchip/common/BoardConfig.mk 文件

RECOVERY_UPDATEIMG_RSA_CHECK ?= true

支持平台:android 4.4,android5.1

8、Boardid 串号
9、升级 U 盘升级包

当按键进入 recovery 时,自动升级 U 盘中的升级包(update.img 或 update.zip)
修改 device/rockchip/common/BoardConfig.mk 文件

RECOVERY_AUTO_USB_UPDATE ?= false

支持平台:android 5.1

10、代码结构
  1. Bootable/recovery/:
    a) Recovery 的主程序代码,其中 recovery.cpp 是入口,
    b) rkimage.cpp 是处理 update.img 的升级流程,
    c) install.cpp 是处理 update.zip 的升级流程。
  2. Build/tools/releasetools/:
    a) OTA 升级包的 Python 脚本,控制完整包与差异包的生成。
  3. Build/tools/drmsigntool/:
    a) 如果开启 drm,生成 ota 包时对 boot.img 进行签名,使用
    build/target/product/security/private.key,保证进行 OTA 升级后,drm 功能还能正常使用。
  4. Build/tools/mkparameter/:
    a) 编译 OTA 时打包可升级的 parameter 的工具。
  5. Build/tools/remkloader/:
    a) 编译 OTA 时打包可升级的 loader 的工具。
  6. Build/target/product/security/:
    a) 编译 OTA 包时签名使用的密钥。
    7.device/rockchip/common/recovery/:
    a) Recovery 菜单及按键定制
    b) 在 android 4.4 上是 device/rockchip/rksdk/recovery 目录
  7. Device/rockchip/common/loader:
    a) 将需要升级的 loader 放在该目录,可以打包到 ota 升级包中。
    b) 4.4 目录 device/rockchip/rksdk/loader
    c) 6.0 目录 device/rockchip/rkxxxx/ota/loader
  8. Device/rockchip/common/parmeter:
    a) 将需要升级的 parameter 放在该目录,可以打包到 ota 升级包中。
    b) 4.4 目录 device/rockchip/rksdk/loader
    c) 6.0 目录 device/rockchip/rkxxxx/ota/loader。
  9. out/target/product/rk3188/obj/PACKAGING/target_files_intermediates:
    a) OTA 升级包编译生成的素材吧,要做差异包必须保存该素材包。
  10. Device/rockchip/common/releasetools.py
    a) 定义 OTA 包中包含的内容。

七、升级步骤

1、OTA 包本地升级操作步骤

  1. 参照第二章,生成 OTA 包,并重新命名为 update.zip
  2. 将 update.zip 拷贝到 USB、SD 卡根目录,或/data/media/0/ 目录下
  3. 会自动检测升级包,并弹出升级对话框。
  4. 自动重启升级:重启进入 Recovery 系统中自动完成 OTA 包的升级,此时不能断电,等待升级完成会自动重启到 Android 主界面。

OTA 包网络升级操作步骤
5. 自动检测网络 OTA 升级包,提示下载升级。
6. 自动重启升级

八、SecureBoot 签名工具

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!