需要在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. 扩展music-list.vue让列表前三名显示🏆奖杯

    1.在music-list.vue中写DOM <li @click="seletItem(song,index)" class="song-item" v ...

  2. 对dump的文件进行状态统计

    1.jps -lvm  查出pid 2.jstack  pid >1.dump 3.grep java.lang.Thread.State 1.dump| awk '{print $2$3$4$ ...

  3. FFmpeg Basic学习笔记(4)

    图像处理 常见的图片格式包括YUV.BMP.JPG.GIF.PNG. 图像的创建 可以使用下面命令从输入源中截取图像 ffmpeg -i input -ss t image.type 从videocl ...

  4. Android.mk简介

    http://www.cnblogs.com/hnrainll/archive/2012/12/18/2822711.html Android.mk文件是GNU Makefile的一小部分,它用来对A ...

  5. 09Vue.js快速入门-Vue入门之Vuex实战

    9.1. 引言 Vue组件化做的确实非常彻底,它独有的vue单文件组件也是做的非常有特色.组件化的同时带来的是:组件之间的数据共享和通信的难题. 尤其Vue组件设计的就是,父组件通过子组件的prop进 ...

  6. C#学习笔记(9)——委托(窗体传值)

    说明(2017-5-30 11:38:06): 1. 窗体1传值到窗体2,只要实例化Form2,“Form2 frm2 = new Form2(txt1.Text)”,这里要给Form2加一个带参数的 ...

  7. MAC层作用

    对于无线传感网 MAC,顾名思义,就是介质访问控制,是用来控制无线介质的访问的,由于无线传输是共享空中资源的,必然存在多个无线传感器节点对传输介质的争用,MAC层协议就是用来解决这个问题的,包括冲突的 ...

  8. 基于jQuery自适应宽度跟高度可自定义焦点图

    基于jQuery自适应宽度跟高度可自定义焦点图.这是一款带左右箭头,缩略小图切换的jQuery相册代码.效果图如下: 在线预览   源码下载 实现的代码. html代码: <section cl ...

  9. AJAX开发技术

    AJAX技术 AJAX(Asynchronous JavaScript and XML,异步JavaScript和XML),AJAX并不是一项新的技术,它产生的主要目的是用于页面的局部刷新,从之前的代 ...

  10. Android 面试知识集1

    今晚在复习Android基础的时候,找到了一些很有价值的基础知识,分享给给位Android的开发者.这些是基础知识,同时也可以当做面试准备.面试题其实是很好的基础知识学习,有空会好好整理相关基础知识. ...