学习笔记,提纲擎领
参考资料:
https://www.cnblogs.com/xiaolei-kaiyuan/
09年初写的Android Recovery_百度
MTK 7.0 源码
RecoveryUI: 进行按键相关操作
ScreenRecoveryUI: 继承 RecoveryUI 界面显示操作操作
Device: 代表设备,有定义支持的相关 BuiltinAction 命令,有指针指向 RecoveryUI 的子类 ScreenRecoveryUI
// Mt_common.h (bootable\recovery)
#define PRELOADER_PART "/dev/block/mmcblk0boot0"
#define PRELOADER2_PART "/dev/block/mmcblk0boot1"
#define BOOT_PART "/dev/block/platform/mtk-msdc.0/by-name/boot"
#define CACHE_PART "/dev/block/platform/mtk-msdc.0/by-name/cache"
#define FAT_PART "/dev/block/platform/mtk-msdc.0/by-name/intsd"
#define SYSTEM_PART "/dev/block/platform/mtk-msdc.0/by-name/system"
#define DATA_PART "/dev/block/platform/mtk-msdc.0/by-name/userdata"
#define MISC_PART "/dev/block/platform/mtk-msdc.0/by-name/para"
#define RECOVERY_PART "/dev/block/platform/mtk-msdc.0/by-name/recovery"
#define CUSTOM_PART "/dev/block/platform/mtk-msdc.0/by-name/custom"
#define VENDOR_PART "/dev/block/platform/mtk-msdc.0/by-name/vendor"
#define LOGO_PART "/dev/block/platform/mtk-msdc.0/by-name/logo"
#define LK_PART "/dev/block/platform/mtk-msdc.0/by-name/lk"
#define TEE1_PART "/dev/block/platform/mtk-msdc.0/by-name/tee1"
#define TEE2_PART "/dev/block/platform/mtk-msdc.0/by-name/tee2"
#define PERSIST_PART "/dev/block/platform/mtk-msdc.0/by-name/persist"
#define NVDATA_PART "/dev/block/platform/mtk-msdc.0/by-name/nvdata"
#define MT_GPT_PART "/dev/block/platform/mtk-msdc.0/by-name"
// device\mediatek\build\build\tools\ptgen\MT6750\partition_table_MT6750_E266L.xls
preloader Raw data
pgpt Raw data
recovery Raw data
para Raw data
custom EXT4
factory EXT4
APD EXT4
ADF EXT4
expdb Raw data
frp Raw data
ppl Raw data
misc2 Raw data
persist EXT4
nvdata EXT4
metadata Raw data
protect1 EXT4
protect2 EXT4
seccfg Raw data
oemkeystore Raw data
proinfo Raw data
efuse Raw data
md1img Raw data
md1dsp Raw data
md1arm7 Raw data
md3img Raw data
nvram Raw data
lk Raw data
lk2 Raw data
boot Raw data
logo Raw data
tee1 Raw data
tee2 Raw data
secro Raw data
keystore Raw data
system EXT4
cache EXT4
userdata EXT4
intsd FAT
otp Raw data
flashinfo Raw data
sgpt Raw data
/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name
lrwxrwxrwx 1 root root 20 2017-07-08 16:39 ADF -> /dev/block/mmcblk0p5
lrwxrwxrwx 1 root root 20 2017-07-08 16:39 APD -> /dev/block/mmcblk0p4
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 boot -> /dev/block/mmcblk0p23
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 cache -> /dev/block/mmcblk0p30
lrwxrwxrwx 1 root root 20 2017-07-08 16:39 expdb -> /dev/block/mmcblk0p6
lrwxrwxrwx 1 root root 20 2017-07-08 16:39 factory -> /dev/block/mmcblk0p3
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 flashinfo -> /dev/block/mmcblk0p32
lrwxrwxrwx 1 root root 20 2017-07-08 16:39 frp -> /dev/block/mmcblk0p7
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 keystore -> /dev/block/mmcblk0p28
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 lk -> /dev/block/mmcblk0p21
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 lk2 -> /dev/block/mmcblk0p22
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 logo -> /dev/block/mmcblk0p24
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 md1arm7 -> /dev/block/mmcblk0p18
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 md1dsp -> /dev/block/mmcblk0p17
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 md1img -> /dev/block/mmcblk0p16
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 md3img -> /dev/block/mmcblk0p19
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 metadata -> /dev/block/mmcblk0p10
lrwxrwxrwx 1 root root 20 2017-07-08 16:39 nvdata -> /dev/block/mmcblk0p9
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 nvram -> /dev/block/mmcblk0p20
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 oemkeystore -> /dev/block/mmcblk0p14
lrwxrwxrwx 1 root root 20 2017-07-08 16:39 para -> /dev/block/mmcblk0p2
lrwxrwxrwx 1 root root 20 2017-07-08 16:39 ppl -> /dev/block/mmcblk0p8
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 proinfo -> /dev/block/mmcblk0p15
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 protect1 -> /dev/block/mmcblk0p11
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 protect2 -> /dev/block/mmcblk0p12
lrwxrwxrwx 1 root root 20 2017-07-08 16:39 recovery -> /dev/block/mmcblk0p1
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 seccfg -> /dev/block/mmcblk0p13
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 secro -> /dev/block/mmcblk0p27
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 system -> /dev/block/mmcblk0p29
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 tee1 -> /dev/block/mmcblk0p25
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 tee2 -> /dev/block/mmcblk0p26
lrwxrwxrwx 1 root root 21 2017-07-08 16:39 userdata -> /dev/block/mmcblk0p31
//////////////////////////////////////////////////////////////////////////////////////////////////
// 0. 带 --adbd 参数启动,其只支持 adb sideload 命令
// 1. 进行输入输出重定向,启动一个 log 子进程进行 log 输出工作,让 log 打印到指定文件里
// 2. 加载文件系统挂载表 fstab 文件,保存到内存的 fstab 中,类似 VOLD 中的操作,解析完成后
// 保存在全局变量 fstab 中,后面有用到
// 3. 搜索 fstab 文件中,判断是否有 /cache 分区
// 4. 如果支持第二个 sdcard 的话,创建 "/sdcard2" 目录
// 5. 主要是用来判断存储是什么类型的:Nand or Emmc ,这通过读取设备的 GPT(GUID Partion Table)全局唯一标识磁盘分区表
// 来实现,最后设置 phone_type 类型:NAND_TYPE or EMMC_TYPE
// 6. 进行文件系统挂载
// 1. 获得 fstab 中指定路径的那行参数
// 2. 获得 /proc/mounts 中已挂载分区的信息,保存在全局变量 g_mounts_state 中
// 3. 遍历 /proc/mounts 中的数据,获取传入挂点的那行参数,如 /dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/system /system ext4 ro,seclabel,relatime,data=ordered 0 0
// 4. 进行文件系统挂载:ubifs/yaffs2/ext4/squashfs/vfat
// 5. 挂载 /sdcard ,这个里面挂载了我们自己的添加的 ntfs/exfat 系统用来支持 ntfs/exfat 的 SD 存储卡
// 7. log 重命令, last_log/last_kmsg 重命令为 last_log.[number]/last_kmsg.[number]
// 8. 获得命令行参数,首先获得 /misc 分区下的命令,再获得 /cache 下的命令
// 最后将这些命令再写入 /misc, 让其重启再进入 recovery, 用于升级失败重试,升级成功则清除
// 9. 解析从 /misc 和 /cache 获得的参数,可以用的命令如下:
// static const struct option OPTIONS[] = {
// { "send_intent", required_argument, NULL, 'i' },
// { "update_package", required_argument, NULL, 'u' },
// { "retry_count", required_argument, NULL, 'n' },
// { "wipe_data", no_argument, NULL, 'w' },
// { "wipe_cache", no_argument, NULL, 'c' },
// { "show_text", no_argument, NULL, 't' },
// { "sideload", no_argument, NULL, 's' },
// { "sideload_auto_reboot", no_argument, NULL, 'a' },
// { "just_exit", no_argument, NULL, 'x' },
// { "locale", required_argument, NULL, 'l' },
// MT_OPTION
// { "stages", required_argument, NULL, 'g' },
// { "shutdown_after", no_argument, NULL, 'p' },
// { "reason", required_argument, NULL, 'r' },
// { "security", no_argument, NULL, 'e'},
// //[email protected] add 20161101 for asus ota fota begin
// { "requester", required_argument, NULL, 'q' },
// //[email protected] add 20161101 for asus ota fota end
// { NULL, 0, NULL, 0 },
// };
// 10. locale = "en_US" 这个不为空指针,不走这里,这里只是加载 /cache 下的命令
// 11. 使用 ScreenRecoveryUI 类初始化了 Device 类
// ScreenRecoveryUI 类:负责界面显示相关的操作,继承实现 RecoveryUI 抽象类
// 12. 获得 Device 类中的 ScreenRecoveryUI 对象,然后进行界面操作
// 13. 显示相关初始化
// 初始化全局变量 gr_font, 通过 libpng 打开 font.png, 保存到 gr_font->texture 中
// 【核心,假装用的此函数】:打开内核的 /dev/graphics/fb0 显示节点:
// 节点的文件描述符保存在 fb_fd 中
// mmap() 的内存显示空间,保存在全局变量 gr_framebuffer 中
// 设置 g_draw 指向显示缓冲区
// 对显示界面进行翻转操作
// 获得属性 ro.sf.lcd_density 显示密度,设置一此 ScreenRecoveryUI 的属性值,并分配一些内存
// 加载一些图片进 ScreenRecoveryUI 的变量中保存
// 加载图片流程:
// 打开 /res/images/ 下的图片
// 分配一个 surface 对象内存
// 将 png 图片读入 surface 对象中保存
// 然后将 surface 对象返回给对应 ScreenRecoveryUI 变量中保存
// 加载本地化的字体,png 图片中可以保存哪国语言信息?加载过一个 surface 内存中保存
// 加载 /res/images/ 下的图片进 surface 数组中,动画是通过一帧帧图片实现的
// 创建了一个进程,进行显示更新
// 死循环:
// 定时更新进度条,20ms 更新一次
// 如果需要重绘
// 更新全部,绘制菜单等
// 更新部分,如动画,进度条
// 监听 /dev/input/event 下的节点,当有按键事件时,回调 RecoveryUI::InputCallback() 进行处理
// 他会在里面调用 ProcessKey() 进行按键处理
// 14. 根据是否启用安全更新,来设置背景字符串
// 15. 如果命令行设置了 -update_package 更新指令,则解析下镜像存放路径格式为:
// -update_package=[分区]:[路径]
// 将更新的镜像路径存在 update_package 中
// 16. 先进行更新安装包
// 进行电池电量检测,至少 20%
// 首先将更新命令写入 /misc 中,用于升级失败后自动再进入升级
// 将当前更新路径写入 /tmp/last_install 中保存
// 确保 /tmp 和 /cache 路径被挂载,其他路径被卸载?
// 显示更新界面
// 进行路径挂载
// 将路径指向的文件 mmap 映射到内存中?
// 加载加密用的密钥:RSA 算法
// 对加载进来的安装包进行校验,使用 RSA
// 打开 update.zip 安装包
// 进行升级前的一些准备工作,如 data 分区备份与恢复
// 在 update.zip 中查找 "META-INF/com/google/android/update-binary" 更新程序
// 首先将 update.zip 解压到 /tmp/update_binary 中
// 然后创建一个子进程:
// 执行 "META-INF/com/google/android/update-binary" 更新程序
// ecex(/tmp/update_binary) 进行更新操作
// 父子通过管道通信,父提供一些重启、进度条显示服务
// 进行 modem 更新
// 更新成功后,清除 /cache 分区
// 更新 Modem 的 persist.sys.extmddlprogress 属性值
// 更新失败了,需要再重进 recovery 再进行更新
// 17. 进行双清、或从 adb 中获取安装包 或从 /sdcard 中更新 data 分区
// 18. 将更新结果写入 MOTA_RESULT_FILE = "/data/data/com.mediatek.systemupdate/files/updateResult" 和 /misc 中?
// 然后保存系统 log 到 cache 分区中:
// 保存 INTENT_FILE = "/cache/recovery/intent";
// 保存 LOCALE_FILE = "/cache/recovery/last_locale";
// "/tmp/recovery.log" ==》"/cache/recovery/log"
// "/tmp/recovery.log" ==》 "/cache/recovery/last_log"
// "/tmp/last_install" ==》 "/cache/recovery/last_install"
// 保存 kernel log ===> "/cache/recovery/last_kmsg"
// 然后清 /misc 设置,让其重启能正常进入系统
// 19. 等待用户按键操作
// 进行菜单显示与响应按键
// 处理按键事件
// 20. 更新系统属性
// 21. 死循环