高通recovery流程分析(编译、界面、图片)

目录

recovery 界面菜单

recovery 界面操作

recovery 启动流程

recovery 编译makefile

recovery 图片大小

ramdisk、boot.img、recovery.img之间的关系


author daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主

recovery 界面菜单

recovery 界面显示

高通recovery流程分析(编译、界面、图片)_第1张图片

android recoveryuse

路径

bootable/recovery/device.cpp

背景设置

void ScreenRecoveryUI::draw_background_locked() {

 gr_color(0, 0, 0, 255); 

}

第一个参数 0:表示红色分量的强度,这里是最小值,表示没有红色。

第二个参数 0:表示绿色分量的强度,这里是最小值,表示没有绿色。

第三个参数 0:表示蓝色分量的强度,这里是最小值,表示没有蓝色。

第四个参数 255:表示透明度或不透明度,这里是最大值,表示完全不透明。

因此,gr_color(0, 0, 0, 255) 表示的是一个完全不透明的黑色。

如果要设置绿色不透明背景,修改参数为gr_color(0, 255, 0, 255)

路径

bootable/recovery/screen_ui.cpp

#include "device.h"
static const char* MENU_ITEMS[] = {
    "Reboot system now",
    "Reboot to bootloader",
    "Apply update from ADB",
    "Apply update from SD card",
    "Wipe data/factory reset",
#ifndef AB_OTA_UPDATER
    "Wipe cache partition",
#endif  // !AB_OTA_UPDATER
    "Mount /system",
    "View recovery logs",
    "Run graphics test",
    "Power off",
    NULL,
};

static const Device::BuiltinAction MENU_ACTIONS[] = {
    Device::REBOOT,
    Device::REBOOT_BOOTLOADER,
    Device::APPLY_ADB_SIDELOAD,
    Device::APPLY_SDCARD,
    Device::WIPE_DATA,
#ifndef AB_OTA_UPDATER
    Device::WIPE_CACHE,
#endif  // !AB_OTA_UPDATER
    Device::MOUNT_SYSTEM,
    Device::VIEW_RECOVERY_LOGS,
    Device::RUN_GRAPHICS_TEST,
    Device::SHUTDOWN,
};

static_assert(sizeof(MENU_ITEMS) / sizeof(MENU_ITEMS[0]) ==
              sizeof(MENU_ACTIONS) / sizeof(MENU_ACTIONS[0]) + 1,
              "MENU_ITEMS and MENU_ACTIONS should have the same length, "
              "except for the extra NULL entry in MENU_ITEMS.");

const char* const* Device::GetMenuItems() {
  return MENU_ITEMS;
}

这段代码定义了两个数组:MENU_ITEMS和MENU_ACTIONS。这两个数组用于存储菜单项和对应的操作。

MENU_ITEMS是一个字符串数组,包含了一系列菜单项的名称。每个菜单项都是一个字符串常量。

MENU_ACTIONS是一个Device::BuiltinAction类型的数组,用于存储与每个菜单项对应的操作。Device::BuiltinAction是一个枚举类型,表示设备的内置操作,如重启、应用更新、擦除数据等。

在MENU_ITEMS数组的末尾,有一个NULL指针,表示数组的结束。

代码中的GetMenuItems()函数返回了MENU_ITEMS数组的地址,即菜单项的名称数组的地址。

最后,代码使用了static_assert语句来确保MENU_ITEMS和MENU_ACTIONS数组的长度相同,除了MENU_ITEMS数组中的额外的NULL条目。如果长度不同,编译时将会报错。

recovery 界面操作

代码中的GetMenuItems()函数返回了MENU_ITEMS数组的地址,即菜单项的名称数组的地址。具体经过switch和case进行具体的操作

// Return REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER.  Returning NO_ACTION
// means to take the default, which is to reboot or shutdown depending
// on if the --shutdown_after flag was passed to recovery.
static Device::BuiltinAction
prompt_and_wait(Device* device, int status) {
    for (;;) {
        finish_recovery(NULL);
        switch (status) {
            case INSTALL_SUCCESS:
            case INSTALL_NONE:
                ui->SetBackground(RecoveryUI::NO_COMMAND);
                break;

            case INSTALL_ERROR:
            case INSTALL_CORRUPT:
                ui->SetBackground(RecoveryUI::ERROR);
                break;
        }
        ui->SetProgressType(RecoveryUI::EMPTY);

        int chosen_item = get_menu_selection(nullptr, device->GetMenuItems(), 0, 0, device);

        // device-specific code may take some action here.  It may
        // return one of the core actions handled in the switch
        // statement below.
        Device::BuiltinAction chosen_action = device->InvokeMenuItem(chosen_item);

        bool should_wipe_cache = false;
        switch (chosen_action) {
            case Device::NO_ACTION:
                break;

            case Device::REBOOT:
            case Device::SHUTDOWN:
            case Device::REBOOT_BOOTLOADER:
                return chosen_action;

            case Device::WIPE_DATA:
                wipe_data(ui->IsTextVisible(), device);
                if (!ui->IsTextVisible()) return Device::NO_ACTION;
                break;

            case Device::WIPE_CACHE:
                wipe_cache(ui->IsTextVisible(), device);
                if (!ui->IsTextVisible()) return Device::NO_ACTION;
                break;

            case Device::APPLY_ADB_SIDELOAD:
            case Device::APPLY_SDCARD:
                    //省略代码……    
                break;

            case Device::VIEW_RECOVERY_LOGS:
                choose_recovery_file(device);
                break;

            case Device::RUN_GRAPHICS_TEST:
                run_graphics_test(device);
                break;

            case Device::MOUNT_SYSTEM:
#ifdef USE_MDTP
                if (is_mdtp_activated()) {
                    ui->Print("Mounting /system forbidden by MDTP.\n");
                }
                else
#endif
              //省略代码……    
                              break;
        }
    }
}

这段代码定义了一个函数prompt_and_wait,该函数用于提示用户选择一个操作,并等待用户的输入。

函数的参数包括一个指向Device对象的指针device和一个整数status。

函数使用一个无限循环for (;;) {}来不断执行以下操作:

调用finish_recovery(NULL)函数,完成recovery操作的最后步骤。

根据status的值,设置recovery界面的背景和进度条的类型。

如果status的值是INSTALL_SUCCESS或INSTALL_NONE,则将背景设置为RecoveryUI::NO_COMMAND;如果status的值是INSTALL_ERROR或INSTALL_CORRUPT,则将背景设置为RecoveryUI::ERROR。

将进度条的类型设置为RecoveryUI::EMPTY,表示没有进度信息。

调用get_menu_selection函数,显示菜单并等待用户选择。该函数的参数包括一个空指针nullptr,表示不显示标题;device->GetMenuItems(),表示获取设备的菜单项;0,表示不显示菜单的起始索引;0,表示不显示菜单的结束索引;device,表示设备对象。

函数最终返回用户选择的操作,可以是Device::REBOOT、Device::SHUTDOWN或Device::REBOOT_BOOTLOADER。如果用户没有选择任何操作,则返回Device::NO_ACTION,表示采取默认操作,即根据--shutdown_after标志决定是重启还是关机。

recovery 启动流程

参考链接

Recovery启动流程(2)---UI界面【转】-腾讯云开发者社区-腾讯云

https://www.cnblogs.com/xiaolei-kaiyuan/p/5456227.html

android-ramdisk.img分析、recovery.img&boot.img执行过程

我们知道,当我们通过按键或者应用进入recovery模式,实质是kernel后加载recovery.img,kernel起来后执行的第一个进程就是init,此进程会读入init.rc启动相应的服务。在recovery模式中,启动的服务是执行recovery可执行文件,此文件是bootable/recovery/recovery.cpp文件生成,我们就从recovery.cpp文件开始分析。

从recovery.cpp main()中可知,进入recovery后会分析/cache/recovery/command文件,根据内容来设定显示的文字语言

SetLocale函数根据locale判断所用的字体是否属于阿拉伯语系,阿拉伯语的书写习惯是从右到左,如果是阿拉伯语系的话,就设置一个标志,后面根据这个标志决定从右到左显示文字或进度条。关于显示文字的语言通过代码即可查看,这里只简单的列出语言设置的几条主线,不贴出具体的代码(太多了)。

recovery 编译makefile

makefile路径

build/core/Makefile

代码

高通recovery流程分析(编译、界面、图片)_第2张图片

/res 对应路径

bootable/recovery/res-xhdpi

bootable/recovery/res-mdpi

高通recovery流程分析(编译、界面、图片)_第3张图片

build/core/Makefile

# Otherwise, use the default medium density.
recovery_densities := ldpi
endif

ifneq (,$(wildcard $(recovery_resources_common)-$(recovery_density)))
recovery_resources_common := $(recovery_resources_common)-$(recovery_density)
else
# recovery_resources_common := $(recovery_resources_common)-xhdpi
recovery_resources_common := $(recovery_resources_common)-mdpi
endif

recovery 图片大小

路径

bootable/recovery/fonts

内容

2*22.png 打开如图用ps查看,并裁剪其中一个字符的大小是12*22像素

高通recovery流程分析(编译、界面、图片)_第4张图片高通recovery流程分析(编译、界面、图片)_第5张图片

注意要包含空余空余

img文件

高通recovery流程分析(编译、界面、图片)_第6张图片

编译出来的recovery.img

ramdisk、boot.img、recovery.img之间的关系

ramdisk.img会被打包到boot.img和recovery.img中(不是同一个ramdisk.img).

ramdisk.img中比较重要的文件是"init","init.rc",其中init是system/core/init/init.c编译而来,

boot.img中ramdisk里的init.rc位于system/core/init/init.rc,

recovery.img中ramdisk里的init.rc位于bootable/recovery/etc/init.rc。

kernel加载结束以后第一个进程是执行init,init会解析init.rc文件,并起相应的服务。

由此可以知道正常开机和进入recovery模式起的进程是不同的。

感悟

        recovery这个块是自己在调试低分辨率屏幕时,kernel阶段正常显示,但是recovery界面灭有显示而排查的,后面发现主要是由于lk阶段的panel_xxxx_video.h文件初始化的command有关,但是recovery的fronts中的字符库分辨率大小确实影响了显示recovery.img的背景显示。

        另外在排查问题的过程中阅读别人的博客学习,但是很容易就忘记,所以就把优质博客记录下来一方面方便自己查阅,另一方面也是帮助大家过滤

你可能感兴趣的:(Android,高通驱动,linux,recovery,Android)