需要在fastboot里面添加功能用于保存,记录一下fastboot显示的过程。

android O新添加了选项,如下

platform/msm_shared/rules.mk

ifeq ($(ENABLE_FBCON_DISPLAY_MSG),1)
OBJS += \
$(LOCAL_DIR)/menu_keys_detect.o \
$(LOCAL_DIR)/display_menu.o
endif

要显示fastboot的选项,需要打开ENABLE_FBCON_DISPLAY_MSG, FBCON_DISPLAY_MSG。

project/msm8953.mk

ifeq ($(VERIFIED_BOOT),1)
ENABLE_SECAPP_LOADER := 1
ENABLE_RPMB_SUPPORT := 1
ifneq (,$(findstring DISPLAY_SPLASH_SCREEN,$(DEFINES)))
#enable fbcon display menu
ENABLE_FBCON_DISPLAY_MSG := 1 ## 这个打开了才会显示fastboot的选项框
endif
endif ifeq ($(ENABLE_FBCON_DISPLAY_MSG),1)
DEFINES += FBCON_DISPLAY_MSG=1 ## 代码中会用到
endif

app/aboot/aboot.c

void aboot_init()
{ fastboot:
/* We are here means regular boot did not happen. Start fastboot. */ /* register aboot specific fastboot commands */
aboot_fastboot_register_commands(); /* dump partition table for debug info */
partition_dump(); /* initialize and start fastboot */
fastboot_init(target_get_scratch_address(), target_get_max_flash_size()); #if DISPLAY_SPLASH_SCREEN
display_fastboot_on_screen();
#endif #if FBCON_DISPLAY_MSG
display_fastboot_menu();
#endif }

显示有两种情况,display_fastboot_on_screen()显示界面就是一个空白的界面,中间显示一个很小的"Fastboot Mode".

dev/fbcon/fbcon.c

void display_fastboot_on_screen(void)
{
unsigned count = config->width * config->height;
char *pixels;
char *draw_text = "Fastboot Mode";
char *c;
unsigned char_count, loop = 0, bpp; bpp = (config->bpp) / 8;
// Draw White Background
memset(config->base, RGB565_WHITE, count * bpp); // Draw
char_count = strlen(draw_text); pixels = config->base;
pixels += ((config->height - FONT_HEIGHT) / 2) * config->width * bpp;
pixels += ((config->width - (FONT_WIDTH + 1)*char_count) / 2) * bpp; c = draw_text;
while(loop < char_count)
{
fbcon_drawglyph_fastboot(pixels, config->width, bpp, font5x12 + (*c - 32) * 2);
loop++;
c++;
pixels += (FONT_WIDTH + 1) * bpp;
}
arch_clean_invalidate_cache_range((addr_t) config->base, (count * bpp)); fbcon_flush(); }

platform/msm_shared/display_menu.c

//fastboot显示出来的选项
static char *fastboot_option_menu[] = {
[0] = "START\n",
[1] = "Restart bootloader\n",
[2] = "Recovery mode\n",
[3] = "Power off\n",
[4] = "Boot to FFBM\n"
}; void display_fastboot_menu()
{
struct select_msg_info *fastboot_menu_msg_info;
fastboot_menu_msg_info = &msg_info; set_message_factor(); msg_lock_init();
mutex_acquire(&fastboot_menu_msg_info->msg_lock); /* There are 4 pages for fastboot menu:
* Page: Start/Fastboot/Recovery/Poweroff
* The menu is switched base on the option index
* Initialize the option index and last_msg_type
*/
fastboot_menu_msg_info->info.option_index = 0;
fastboot_menu_msg_info->last_msg_type =
fastboot_menu_msg_info->info.msg_type; display_fastboot_menu_renew(fastboot_menu_msg_info); // bootloader显示
mutex_release(&fastboot_menu_msg_info->msg_lock); dprintf(INFO, "creating fastboot menu keys detect thread\n");
display_menu_thread_start(fastboot_menu_msg_info); // 显示线程,检测按键按下,对应的显示
} // fastboot显示的文本,每次都会更新
void display_fastboot_menu_renew(struct select_msg_info *fastboot_msg_info)
{
int len;
int msg_type = FBCON_COMMON_MSG;
char msg_buf[64];
char msg[128];
device_info device;
/* The fastboot menu is switched base on the option index
* So it's need to store the index for the menu switching
*/
uint32_t option_index = fastboot_msg_info->info.option_index; fbcon_clear();
memset(&fastboot_msg_info->info, 0, sizeof(struct menu_info)); len = ARRAY_SIZE(fastboot_option_menu);
// 不同选项对应的字体颜色
switch(option_index) {
case 0:
msg_type = FBCON_GREEN_MSG;
break;
case 1:
case 2:
msg_type = FBCON_RED_MSG;
break;
case 3:
case 4:
msg_type = FBCON_COMMON_MSG;
break;
} fbcon_draw_line(msg_type);
display_fbcon_menu_message(fastboot_option_menu[option_index],
msg_type, big_factor);
fbcon_draw_line(msg_type); // 显示文字
display_fbcon_menu_message("\n\nPress volume key to select, and "\
"press power key to select\n\n", FBCON_COMMON_MSG, common_factor); display_fbcon_menu_message("FASTBOOT MODE\n", FBCON_RED_MSG, common_factor); get_product_name((unsigned char *) msg_buf);
snprintf(msg, sizeof(msg), "PRODUCT_NAME - %s\n", msg_buf);
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor); memset(msg_buf, 0, sizeof(msg_buf));
smem_get_hw_platform_name((unsigned char *) msg_buf, sizeof(msg_buf));
snprintf(msg, sizeof(msg), "VARIANT - %s %s\n",
msg_buf, target_is_emmc_boot()? "eMMC":"UFS");
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor); memset(msg_buf, 0, sizeof(msg_buf));
get_bootloader_version((unsigned char *) msg_buf);
snprintf(msg, sizeof(msg), "BOOTLOADER VERSION - %s\n",
msg_buf);
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor); memset(msg_buf, 0, sizeof(msg_buf));
get_baseband_version((unsigned char *) msg_buf);
snprintf(msg, sizeof(msg), "BASEBAND VERSION - %s\n",
msg_buf);
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor); memset(msg_buf, 0, sizeof(msg_buf));
target_serialno((unsigned char *) msg_buf);
snprintf(msg, sizeof(msg), "SERIAL NUMBER - %s\n", msg_buf);
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor); snprintf(msg, sizeof(msg), "SECURE BOOT - %s\n",
is_secure_boot_enable()? "enabled":"disabled");
display_fbcon_menu_message(msg, FBCON_COMMON_MSG, common_factor); snprintf(msg, sizeof(msg), "DEVICE STATE - %s\n",
is_device_locked()? "locked":"unlocked");
display_fbcon_menu_message(msg, FBCON_RED_MSG, common_factor); fastboot_msg_info->info.msg_type = DISPLAY_MENU_FASTBOOT;
fastboot_msg_info->info.option_num = len;
fastboot_msg_info->info.option_index = option_index;
}

按键线程

platform/msm_shared/menu_keys_detect.c

int select_msg_keys_detect(void *param) {
struct select_msg_info *msg_info = (struct select_msg_info*)param; msg_lock_init();
keys_detect_init();
while(1) {
/* 1: update select option's index, default it is the total option number
* volume up: index decrease, the option will scroll up from
* the bottom to top if the key is pressed firstly.
* eg: 5->4->3->2->1->0
* volume down: index increase, the option will scroll down from
* the bottom to top if the key is pressed firstly.
* eg: 5->0
* 2: update device's status via select option's index
*/
if (is_key_pressed(VOLUME_UP)) {
mutex_acquire(&msg_info->msg_lock);
menu_pages_action[msg_info->info.msg_type].up_action_func(msg_info);
mutex_release(&msg_info->msg_lock);
} else if (is_key_pressed(VOLUME_DOWN)) { // VOLUME_DOWN
mutex_acquire(&msg_info->msg_lock);
menu_pages_action[msg_info->info.msg_type].down_action_func(msg_info);
mutex_release(&msg_info->msg_lock);
} else if (is_key_pressed(POWER_KEY)) {
mutex_acquire(&msg_info->msg_lock);
menu_pages_action[msg_info->info.msg_type].enter_action_func(msg_info);
mutex_release(&msg_info->msg_lock);
}
mutex_acquire(&msg_info->msg_lock);
/* Never time out if the timeout_time is 0 */
if(msg_info->info.timeout_time) {
if ((current_time() - before_time) > msg_info->info.timeout_time)
msg_info->info.is_exit = true;
} if (msg_info->info.is_exit) {
msg_info->info.rel_exit = true;
mutex_release(&msg_info->msg_lock);
break;
}
mutex_release(&msg_info->msg_lock);
thread_sleep(KEY_DETECT_FREQUENCY);
} return 0;
}

对应的结构体中的函数指针如下:

static struct pages_action menu_pages_action[] = {
[DISPLAY_MENU_UNLOCK] = {
menu_volume_up_func,
menu_volume_down_func,
power_key_func,
},
[DISPLAY_MENU_UNLOCK_CRITICAL] = {
menu_volume_up_func,
menu_volume_down_func,
power_key_func,
},
[DISPLAY_MENU_YELLOW] = {
boot_warning_volume_keys_func,
boot_warning_volume_keys_func,
power_key_func,
},
[DISPLAY_MENU_ORANGE] = {
boot_warning_volume_keys_func,
boot_warning_volume_keys_func,
power_key_func,
},
[DISPLAY_MENU_RED] = {
boot_warning_volume_keys_func,
boot_warning_volume_keys_func,
power_key_func,
},
[DISPLAY_MENU_LOGGING] = {
boot_warning_volume_keys_func,
boot_warning_volume_keys_func,
power_key_func,
},
[DISPLAY_MENU_EIO] = {
boot_warning_volume_keys_func,
boot_warning_volume_keys_func,
power_key_func,
}

分析其中的power按键功能

static void power_key_func(struct select_msg_info* msg_info)
{
int reason = -1; switch (msg_info->info.msg_type) {
case DISPLAY_MENU_YELLOW:
case DISPLAY_MENU_ORANGE:
case DISPLAY_MENU_RED:
case DISPLAY_MENU_LOGGING:
reason = CONTINUE;
break;
case DISPLAY_MENU_EIO:
pwr_key_is_pressed = true;
reason = CONTINUE;
break;
case DISPLAY_MENU_MORE_OPTION:
if(msg_info->info.option_index < ARRAY_SIZE(verify_index_action))
reason = verify_index_action[msg_info->info.option_index];
break;
case DISPLAY_MENU_UNLOCK:
case DISPLAY_MENU_UNLOCK_CRITICAL:
if(msg_info->info.option_index < ARRAY_SIZE(unlock_index_action))
reason = unlock_index_action[msg_info->info.option_index];
break;
case DISPLAY_MENU_FASTBOOT:
if(msg_info->info.option_index < ARRAY_SIZE(fastboot_index_action))
reason = fastboot_index_action[msg_info->info.option_index];
break;
default:
dprintf(CRITICAL,"Unsupported menu type\n");
break;
} if (reason != -1) {
update_device_status(msg_info, reason); // 更新显示状态
}
}
} static void update_device_status(struct select_msg_info* msg_info, int reason)
{
char ffbm_page_buffer[FFBM_MODE_BUF_SIZE];
fbcon_clear();
struct device_info device;
switch (reason) {
case RECOVER: // 根据选项进行设置
if (msg_info->info.msg_type == DISPLAY_MENU_UNLOCK) {
set_device_unlock_value(UNLOCK, TRUE);
} else if (msg_info->info.msg_type == DISPLAY_MENU_UNLOCK_CRITICAL) {
set_device_unlock_value(UNLOCK_CRITICAL, TRUE);
} if (msg_info->info.msg_type == DISPLAY_MENU_UNLOCK ||
msg_info->info.msg_type == DISPLAY_MENU_UNLOCK_CRITICAL) {
/* wipe data */
struct recovery_message msg; memset(&msg, 0, sizeof(msg));
snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
write_misc(0, &msg, sizeof(msg));
}
reboot_device(RECOVERY_MODE);
break;
case RESTART:
reboot_device(0);
break;
case POWEROFF:
shutdown_device();
break;
case FASTBOOT:
reboot_device(FASTBOOT_MODE);
break;
case CONTINUE:
display_image_on_screen();
/* Continue boot, no need to detect the keys'status */
msg_info->info.is_exit = true;
break;
case BACK:
display_bootverify_menu_renew(msg_info, msg_info->last_msg_type);
before_time = current_time(); break;
case FFBM:
memset(&ffbm_page_buffer, 0, sizeof(ffbm_page_buffer));
snprintf(ffbm_page_buffer, sizeof(ffbm_page_buffer), "ffbm-00");
write_misc(0, ffbm_page_buffer, sizeof(ffbm_page_buffer)); reboot_device(0);
break;
} enum device_select_option {
POWEROFF = 0,
RESTART,
RECOVER,
FASTBOOT,
BACK, CONTINUE,
FFBM,
};

Tony Liu

2018-2-2

高通 fastboot 显示的更多相关文章

  1. Android图形合成和显示系统---基于高通MSM8k MDP4平台

    介绍了Android SurfaceFlinger层次以下的图形合成和显示系统,主要基于高通MSM8k MDP4x平台. 做为Android Display专题.SurfaceFlinger的详细介绍 ...

  2. 【转】高通平台android 环境配置编译及开发经验总结

    原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...

  3. 高通spi 屏幕 -lk代码分析

    lk SPI驱动 1. 初始化时钟 在lk中,我们是从kmain开始执行下来的,而执行顺序则是先初始化时钟,也就是在platform_early_init函数中开始执行的: 在这里我们需要修改这个函数 ...

  4. 高通方案的Android设备几种开机模式的进入与退出

    高通方案的Android设备主要有以下几种开机模式,Android.EDL.Fastboot.Recovery和FFBM,其进入及退出的方式如下表. 开机模式 屏幕显示 冷启动 热启动 按键退出 命令 ...

  5. 高通sdm845_la2.0源码编译及使用QFIL刷机

    一.下载源码 高通芯片代码下载地址:https://chipcode.qti.qualcomm.com/ . *_amss_standard_oem : 高通私有源码(*为sdm845-la--. * ...

  6. 高通移植mipi LCD的过程LK代码

    lk部分:(实现LCD兼容) 1. 函数定位 aboot_init()来到target_display_init(): 这就是高通原生lk LCD 兼容的关键所在.至于你需要兼容多少LCD 就在whi ...

  7. GJM : Unity3D 高通Vuforia SDK AR 开发

    一.AR概念: 增强现实(Augmented Reality,简称AR),是在虚拟现实的基础上发展起来的新技术,也被称之为混合现实.是通过计算机系统提供的信息增加用户对现实世界感知的技术,将虚拟的信息 ...

  8. 高通vuforia+Unity3D 制作ar app

    很简单就可以用Unity3D做出增强现实的一个小例子 新人第一次写博客,若出现错误望指正^_^ 需要下载de东西: unity3d 5.0 http://unity3d.com/get-unity   ...

  9. 高通平台FastMMI(FFBM模式)简介与进入方法

    参考: http://blog.csdn.net/tfslovexizi/article/details/51499979 http://www.voidcn.com/blog/jimbo_lee/a ...

随机推荐

  1. Hibernate 建立一对多双向关联关系

    下面内容整理自<精通Hibernate>第二版 注:既然是双向关联."一对多双向关联"和"多对一双向关联"是同一回事. 对象位于内存中,在内存中从一 ...

  2. pandas数组(pandas Series)-(2)

    pandas Series 比 numpy array 要强大很多,体现在很多方面 首先, pandas Series 有一些方法,比如: describe 方法可以给出 Series 的一些分析数据 ...

  3. 谷歌Chrome浏览器小于12px字号显示的BUG

    webkit的私有属性:html{-webkit-text-size-adjust:none;}

  4. vscode 换行符\n 变成\r\n

    VSCode是一个开源的强大代码编写器,但是如果没有好好的配置使用,会适得其反. 这里总结VSCode的一些配置,方便自己查询,也方便网友. 1.编辑器配置 为特定类型文件指定缩进大小.缩进类型(空格 ...

  5. javascript基础拾遗(一)

    1.判断变量类型 var num = '123'; if(typeof num == 'number'){ alert('this is a number'); } else{ throw 'this ...

  6. 使用windowAnimations定义Activity及Dialog的进入退出效果

    看了android的源代码和资源文件,终于明白如何去修改设置Dialog和Activity的进入和退出效果了.设置Dialog首先通过getWindow()方法获取它的窗口,然后通过getAttrib ...

  7. NGUI制作字体的三种方法

    主要参考两篇博文: (1).NGUI制作字体的三种方法 (2).使用位图字体工具BMFont从图片生成自定义字体 1.BMFont下载地址 http://www.angelcode.com/produ ...

  8. 项目日志的管理和应用 log4js-Node.js中的日志管理模块使用与封装

    开发过程中,日志记录是必不可少的事情,尤其是生产系统中经常无法调试,因此日志就成了重要的调试信息来源. Node.js,已经有现成的开源日志模块,就是log4js,源码地址:点击打开链接 项目引用方法 ...

  9. sed行处理详解(交换行,合并行,删除行等)

    1.合并行 zj@zj:~/Script/blog_script$ cat test11234合并上下两行zj@zj:~/Script/blog_script$ sed '$!N;s/\n/\t/' ...

  10. Docker考前突击

    dockerfile 介绍 镜像(Image)     容器(Container)     仓库(Repository)