Android Q 按键启动recovery模式
相关文件路径
LINUX/android/bootable/bootloader/lk/app/aboot/aboot.c
LINUX/android/bootable/bootloader/lk/app/aboot/recovery.c
LINUX/android/bootable/recovery/recovery.cpp
LINUX/android/bootable/recovery/recovery_main.cpp
LINUX/android/bootable/recovery/recovery_ui/ui.cpp
按键启动,加载lk,根据不同信息,加载不同镜像文件(boot或recovery)
前言
提示:这里可以添加本文要记录的大概内容:
例如:开发Android项目时,涉及到OTA升级时,经常使用recovery内容,本文主要讲解按键进入receovry的流程。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Recovery简介
Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware升级。
升级一般通过运行升级包中的META-INF/com/google/android/update-script脚本来执行自定义升级,脚本中是一组recovery系统能识别的UI控制,文件系统操作命令,例如write_raw_image(写FLASH分区),copy_dir(复制目录)。该包一般被下载至SDCARD和CACHE分区下。。
二、相关文件目录
LINUX/android/bootable/bootloader/lk/app/aboot/aboot.c
LINUX/android/bootable/bootloader/lk/app/aboot/recovery.c
LINUX/android/bootable/recovery/recovery.cpp
LINUX/android/bootable/recovery/recovery_main.cpp
LINUX/android/bootable/recovery/recovery_ui/ui.cpp
1.检测按键
代码如下(示例):
unsigned char *update_cmdline(const char * cmdline)
{
........
检测系统是否从emmc启动
if (target_is_emmc_boot()) {
}
检测HOMW按键和音量按键是否按下
if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN))
{
dprintf(ALWAYS,"dload mode key sequence detected\n");
reboot_device(EMERGENCY_DLOAD);
dprintf(CRITICAL,"Failed to reboot into dload mode\n");
boot_into_fastboot = true;
}
if (!boot_into_fastboot)
{
if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP))
-----当按下音量+时,记录此时进入recovery模式
boot_into_recovery = 1;
if (!boot_into_recovery &&
(keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))
boot_into_fastboot = true;
}
系统未启动,如何检测VolumeUp按键被按下?
LINUX/android/bootable/msm8952/init.c
#define TLMM_VOL_UP_BTN_GPIO_8937 38 对应引脚的GPIO
static void target_keystatus()
{
keys_init();
if(target_volume_down())
keys_post_event(KEY_VOLUMEDOWN, 1);
if(target_volume_up())
keys_post_event(KEY_VOLUMEUP, 1);
}
/* Return 1 if vol_up pressed */
int target_volume_up()
{
if(platform_is_msm8937() || platform_is_msm8917()){
vol_up_gpio = TLMM_VOL_UP_BTN_GPIO_8937;
}
/* Get status of GPIO */
status = gpio_status(vol_up_gpio);
/* Active low signal. */
return !status;
}
保存按键message
LINUX/android/bootable/bootloader/bootloader/lk/dev/keys/keys.c
static unsigned long key_bitmap[BITMAP_NUM_WORDS(MAX_KEYS)];
if (value)
bitmap_set(key_bitmap, code);
else
bitmap_clear(key_bitmap, code);
........
2.启动recovery服务
代码如下(示例):
LINUX/android/bootable/recoveryAndroid.bp
cc_binary {
name: "recovery",
recovery: true,
defaults: [
"libinstall_defaults",
"librecovery_defaults",
],
srcs: [
"recovery_main.cpp",
],
LINUX/android/bootable/recovery/recovery_main.cpp
int main(int argc, char** argv) {
auto ret = fastboot ? StartFastboot(device, args) : start_recovery(device, args);
}
LINUX/android/bootable/recovery/recovery.cpp
recover界面显示列表信息
Device::BuiltinAction start_recovery(Device* device, const std::vector<std::string>& args) {
static constexpr struct option OPTIONS[] = {
{
"fastboot", no_argument, nullptr, 0 },
{
"fsck_unshare_blocks", no_argument, nullptr, 0 },
{
"just_exit", no_argument, nullptr, 'x' },
{
"locale", required_argument, nullptr, 0 },
{
"prompt_and_wipe_data", no_argument, nullptr, 0 },
{
"reason", required_argument, nullptr, 0 },
{
"rescue", no_argument, nullptr, 0 },
{
"retry_count", required_argument, nullptr, 0 },
{
"security", no_argument, nullptr, 0 },
{
"show_text", no_argument, nullptr, 't' },
{
"shutdown_after", no_argument, nullptr, 0 },
{
"sideload", no_argument, nullptr, 0 },
{
"sideload_auto_reboot", no_argument, nullptr, 0 },
{
"update_package", required_argument, nullptr, 0 },
{
"wipe_ab", no_argument, nullptr, 0 },
{
"wipe_cache", no_argument, nullptr, 0 },
{
"wipe_data", no_argument, nullptr, 0 },
{
"wipe_package_size", required_argument, nullptr, 0 },
{
nullptr, 0, nullptr, 0 },
};
USER版本无法通过按键进入Recovery模式
if (is_ro_debuggable()) {
ui->ShowText(true);
}
status = INSTALL_NONE; // No command specified
recovery模式异常,显示No Command界面
ui->SetBackground(RecoveryUI::NO_COMMAND);
status = INSTALL_NONE;
}