100余款高清原厂车标开机logo 包含100多款高清原厂车商开机logo, 三种分辨率 1024×600 800×480 222×124 任你选择, 还等什么快上车 现在很多车载大屏都是基于Android系统,其中都会有一个开机 logo 替换程序,任你选择各大车商 logo 替换,一开机就能查看效果。 一直对这块很感兴趣,研究了发现 MTK 平台可以通过 Nvram 来存储数据,这是一种可行的方案,应用层写入index,uboot 和 kernel 读取 index 绘制对应的 logo 以达到动态替换效果。 100余款车商logo资源 Little Kernel 会在 platform_early_init 阶段首先会获取 lcm params,其工作流程就是透过读id找到现在插入的LCM, 根据 LCM 的分辨率申请相应大小的 frame buffer并确定 frame buffer 起始地址,接着为 logo.bin 预留4M Ram 之后在 platform_init 阶段,直接将 logo.bin 载入到 4M Ram 中 完成载入后,在 platform_init 中 mt_disp_show_boot_logo() 会调用show_logo(0);完成第一张logo显示。 其中的index=0代表在 logo.bin 中压缩的第一张图片,logo.bin 中的图片压缩顺序可以察看文件 vendormediatekproprietarybootablebootloaderlkdevlogorules.mk Kernel logo 的工作方式与 U-boot logo 不同,是透过init.rc中注册的,boot_logo_updater service 完成读取raw data文件, 进行绘画的,所以在 kernel logo 只是经过了 bmp 向 raw 的转换,在目录 vendormediatekproprietarybootablebootloaderlkdevlogo 下 通过 bmp_to_raw 工具将 bmp 转换为 raw 文件,之后透过脚本文件将 boot_logo 文件搬移到 outtargetproductxxxobjBOOTLOADER_OBJbuild-xxxdevlogowxga下,打包到 logo.bin,download 到手机中
注:图片来自 https://blog.csdn.net/u011784994/article/details/105561958 U-boot logo,将不同分辨率的图片压缩至 logo.bin 中,在读取时根据不同的 NVflag 显示相应的图片即可 platform.c 中 lk_display_show_logo(void) 读取 NVflag 传递给 mt_logo.c 调用 void mt_disp_show_boot_logo(int logo_index) Kernel logo,需要将不同分辨率的 boot_logo raw data文件生成出来并 copy 到手机中,boot_logo_updater根据不同的分辨率进行识别, 读取相应的logo文件。在 boot_logo_updater 识别部分对 NVflag 进行判断,进而调用不同的boot_logo。 charging_animation.cpp 中 void show_kernel_logo() 读取 NVflag 根据 device/mediateksample/xxx/ProjectConfig.mk 中 BOOT_LOGO= wxga 对应字段,找到 vendormediatekproprietarybootablebootloaderlkdevlogowxga 文件夹中对应的图片分辨率 在 PS 中新建同等分辨率,置入素材,最终保存为 bmp 格式即可。 NVRAM( Non-Volatile Random Access Memory) 是非易失性随机访问存储器,指断电后仍能保持数据的一种 RAM。 MTK 源码中提供了相关的工具类读写,写入 NVRam 中的数据恢复出厂也不会丢失。 有关 NVRAM 可查看 MTK NVRAM 应用层读写 Nvram 方法网上有很多,而且很容易验证。uboot 和 kernel 读取比较稀少,找了很久参考如下的文章 经过N次不停修改尝试后,最终苍天不负,终于搞定。 有了以上对于 NVram 相关认知,那我们就来撸代码吧。 java 层主要通过 INvram 接口来读写,对应的需要导入静态库, LOCAL_STATIC_JAVA_LIBRARIES += vendor.mediatek.hardware.nvram-V1.0-java-static 显然在AS 中是编译不过的,所以只能放到源码环境通过配置 Android.mk 的方式编译。 测试用 Android.mk 文件 也有可能你的源码中 nvram 版本不是 V1.0,可以通过 find -name “*.java” | xargs grep “/vendor/nvdata/” 命令搜索 那个 app 也操作了 nvram,复制对应mk中的版本号就行。 测试用 NVActivity 代码如下 测试 demo 运行图,demo apk 下载链接
简单验证后能正常读写 nvram,那我们就需要对 demo 进行大改造,思路如下 1、预置开机logo缩略图,通过 GridView 加载展示 2、点击 GridView 中图片弹框提示是否需要替换开机logo 3、确定替换将logo缩略图对应index值写入 nvram 中 4、重启可查看效果 核心读写 nvram 方法已提供,其它代码太多就不贴了。 修改代码清单 kernel logo 绘制方法位于 charging_animation.cpp 中 void show_kernel_logo() 头文件中增加 int nvram_read_index(void) 获取 index 方法 vendormediatekproprietaryexternallibshowlogocharging_animation.h vendormediatekproprietaryexternallibshowlogocharging_animation.cpp 同时还需要在 Android.mk 中导入所需 nvram 库 vendormediatekproprietaryexternallibshowlogoAndroid.mk 调试小技巧 通过 jni log 打印读取的数据,查找其中index值,其中需要进制转换,分别打印了 16 进制和 10 进制,通过 log 查找正确的结果 烧写时只勾选 lk、boot、logo 替换即可,加快烧写验证速度。 uboot 阶段相比 kernel 要困难太多,一开始没法看日志,不知道读取的值是否正确,后来灵机一动,加上去除之前 oem 解锁后屏幕 显示警告文字也是在 uboot 阶段显示,那这里应该也行,果不其然通过 video_printf() 打印日志调试就很方便,mtk 真是太牛逼了! uboot logo 绘制方法位于 mt_logo.cpp 中 void mt_disp_show_boot_logo(void) 修改头文件,传递 index 值,显示动态替换logo vendormediatekproprietarybootablebootloaderlkplatformmt6735includeplatformmt_logo.h 修改实现方法,参数传递 logo_index vendormediatekproprietarybootablebootloaderlkplatformmt6735mt_logo.c platform 中读取 nvram 值传递给 mt_logo vendormediatekproprietarybootablebootloaderlkplatformmt6735platform.c 经过上面修改,读写 nvram 都已正常,最后预置 logo bmp 图片打包即可,还需修改如下两个地方 在 (BOOT_LOGO)_kernel.raw 后面增加要打包进的资源图片名称,可配置 N 个,index值在 kernel 后依次累加。 vendormediatekproprietarybootablebootloaderlkdevlogorules.mk 增加对应的 bmp 转化 raw 规则 vendormediatekproprietarybootablebootloaderlkdevlogoupdate 在对应文件下放置 wxga_uboot_kernel.bmp 图片 修改前 修改后
前言
开机Logo加载原理
1、u-boot logo显示原理
2、kernel logo 显示原理
3、logo.bin生成过程
4、替换原理
开机Logo制作
知识储备
1、实现思路
2、NVram 相关介绍
3、不同区域读取 NVRam 数据
动态替换实现
1、java 层读写 NVram
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) #引入静态库读写nvram LOCAL_STATIC_JAVA_LIBRARIES += vendor.mediatek.hardware.nvram-V1.0-java-static LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := NvramDemo #编译后的apk路径在data目录下 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) include $(BUILD_PACKAGE)
package com.android.qrdc; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.TextView; import java.util.ArrayList; import java.util.Arrays; import vendor.mediatek.hardware.nvram.V1_0.INvram; import com.android.internal.util.HexDump; public class NVActivity extends Activity { private static final String TAG = "NVActivity"; private TextView tv_result; private EditText cmdEt; private static void log(String msg) { Log.e("NVActivity", msg); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.nv_layout); tv_result = findViewById(R.id.tv_result); cmdEt = findViewById(R.id.cmdEt); } public void readNv(View v) { log("readNv click"); tv_result.setText("read result"+ readData()); } public void writeNv(View v) { String cmd = cmdEt.getText().toString(); log("writeNv click -----" + cmd); writeData(Integer.parseInt(cmd)); } @Override protected void onDestroy() { super.onDestroy(); } public static final String PRODUCT_INFO_FILENAME = "/vendor/nvdata/APCFG/APRDEB/PRODUCT_INFO"; private static void writeData(int n) { byte[] write_buff = new byte[]{0, 0, 0, 0}; byte[] by = getBytes(n); for (int i = 0; i < 4; i++) { write_buff[i] = by[i]; } try { INvram agent = INvram.getService(); if (agent != null) { ArrayList<Byte> dataArray = new ArrayList<>(4); for (byte b : write_buff) { dataArray.add(new Byte(b)); } int ret_1 = agent.writeFileByNamevec(PRODUCT_INFO_FILENAME, 537, dataArray); if (ret_1>0){ log("write success"+ ret_1); }else { log("write failed"+ ret_1); } } else { Log.e(TAG, "writeData: agent null"); } } catch (Exception e) { Log.e(TAG, "writeData exception:" + e.getLocalizedMessage()); e.printStackTrace(); } } private static byte[] getBytes(int data) { byte[] bytes = new byte[4]; bytes[0] = (byte) (data & 0xff); bytes[1] = (byte) ((data & 0xff00) >> 8); bytes[2] = (byte) ((data & 0xff0000) >> 16); bytes[3] = (byte) ((data & 0xff000000) >> 24); return bytes; } public static int readData() { int targets = 0; try { String buff = null; INvram agent = INvram.getService(); Log.i(TAG, "readData from PRODUCT_INFO_FILENAME"); if (agent != null) { buff = agent.readFileByName(PRODUCT_INFO_FILENAME, 537); } byte[] buffArr = HexDump.hexStringToByteArray(buff.substring(0, buff.length() - 1)); targets = (buffArr[0] & 0xff) | ((buffArr[1] << 8) & 0xff00) | ((buffArr[2] << 24) >>> 8) | (buffArr[3] << 24); Log.i(TAG, "readData: buffArr=" + Arrays.toString(buffArr) + ", targets == " + targets); } catch (Exception e) { Log.e(TAG, "readData exception:" + e.getLocalizedMessage()); e.printStackTrace(); } return targets; } }
vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/rules.mk vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/update vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/include/platform/mt_logo.h vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/mt_logo.c vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/platform.c vendor/mediatek/proprietary/external/libshowlogo/Android.mk vendor/mediatek/proprietary/external/libshowlogo/charging_animation.cpp vendor/mediatek/proprietary/external/libshowlogo/charging_animation.h
2、native 层读取 NVram
+++ b/alps/vendor/mediatek/proprietary/external/libshowlogo/charging_animation.h @@ -110,7 +110,7 @@ void anim_surface_deinit(void); // show logo function void anim_show_logo(int index); - +int nvram_read_index(void); #ifdef __cplusplus }
//cczheng add read kernel logo index from nvram #define MAX_RETRY_COUNT 100 int nvram_read_index(void){ int logo_index = kernel_logo_position; int read_nvram_ready_retry = 0; F_ID fid; int rec_size = 0; int rec_num = 0; int nvinfo_lid = AP_CFG_REEB_PRODUCT_INFO_LID; char *nvdata_result; bool isread = false; char nvram_init_val[128] = {0}; SLOGE("Entry get_barcode_from_nvram"); while (read_nvram_ready_retry < MAX_RETRY_COUNT) { read_nvram_ready_retry++; property_get("service.nvram_init", nvram_init_val, NULL); if (strcmp(nvram_init_val, "Ready") == 0) { break; } else { usleep(500 * 1000); } } if (read_nvram_ready_retry >= MAX_RETRY_COUNT) { SLOGE("Get nvram restore ready failed!"); return logo_index; } nvdata_result = (char *) malloc(1024); if (nvdata_result == NULL) { return logo_index; } fid = NVM_GetFileDesc(nvinfo_lid, &rec_size, &rec_num, isread); if (fid.iFileDesc < 0) { SLOGE("fid.iFileDesc < 0"); free(nvdata_result); return logo_index; } if (rec_size != read(fid.iFileDesc, nvdata_result, rec_size)) { free(nvdata_result); return logo_index; } free(nvdata_result); if (!NVM_CloseFileDesc(fid)) { return logo_index; } SLOGE("nvramstr hex buff[0]%x, buff[1]%x, buff[2]%x, buff[3]%x n", nvdata_result[0],nvdata_result[1],nvdata_result[2],nvdata_result[3]); SLOGE("The size of nvdata_result:%dn", sizeof(nvdata_result)); SLOGE("nvramstr dex buff[0]=%d, buff[1]=%d, buff[2]=%d, buff[3]=%d n", nvdata_result[0],nvdata_result[1],nvdata_result[2],nvdata_result[3]); logo_index = nvdata_result[0]; return logo_index; } /* * Show kernel logo when phone boot up * */ void show_kernel_logo() { if (MTK_LOG_ENABLE == 1) { SLOGD("[libshowlogo: %s %d]show kernel logo, index = 38 n",__FUNCTION__,__LINE__); } if (error_flag == 0) { #if defined(MTK_CARRIEREXPRESS_PACK) anim_show_logo(get_logo_index(false)); SLOGE("[show_kernel_logo: get_logo_index %d", get_logo_index(false)); #else //cczheng add read index from nvram data kernel_logo_position = nvram_read_index(); anim_show_logo(kernel_logo_position); SLOGE("[show_kernel_logo: %d %d]show kernel logo, n",__LINE__, kernel_logo_position); #endif } }
+++ b/alps/vendor/mediatek/proprietary/external/libshowlogo/Android.mk @@ -50,8 +50,8 @@ endif endif endif -LOCAL_SHARED_LIBRARIES := libcutils libutils libc libstdc++ libz libdl liblog libgui libui libsysenv_system libbase - +LOCAL_SHARED_LIBRARIES := libcutils libutils libc libstdc++ libz libdl liblog libgui libui libsysenv_system libbase libnvram_mtk libcustom_nvram_mtk LOCAL_STATIC_LIBRARIES += libfs_mgr LOCAL_C_INCLUDES += $(MTK_PATH_CUSTOM)/lk/include/target @@ -62,6 +62,14 @@ LOCAL_C_INCLUDES += $(TOP)/frameworks/native/libs/nativewindow/include LOCAL_C_INCLUDES += system/core/fs_mgr/include LOCAL_C_INCLUDES += $(TOP)/vendor/mediatek/proprietary/external/libsysenv +LOCAL_C_INCLUDES += vendor/mediatek/proprietary/external/nvram/libnvram + vendor/mediatek/proprietary/custom/ + $(MTK_PATH_SOURCE)/external/nvram/libfile_op + $(MTK_PATH_CUSTOM)/cgen/inc + $(MTK_PATH_CUSTOM)/cgen/cfgfileinc + vendor/mediatek/proprietary/custom/common/cgen/cfgfileinc + vendor/mediatek/proprietary/custom/common/cgen/inc + LOCAL_MODULE := libshowlogo #LOCAL_PROPRIETARY_MODULE := true #LOCAL_MODULE_OWNER := mtk
3、uboot 区域读取 NVram
+++ b/alps/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/include/platform/mt_logo.h @@ -58,7 +58,8 @@ const LOGO_CUST_IF *LOGO_GetCustomIF(void); void mt_disp_enter_charging_state(void); void mt_disp_show_battery_full(void); void mt_disp_show_battery_capacity(UINT32 capacity); -void mt_disp_show_boot_logo(void); +// void mt_disp_show_boot_logo(void); +void mt_disp_show_boot_logo(int logo_index); void mt_disp_show_low_battery(void);
+++ b/alps/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6735/mt_logo.c @@ -266,9 +266,12 @@ void mt_logo_get_custom_if(void) * Show first boot logo when phone boot up * */ -void mt_disp_show_boot_logo(void) -{ - int logo_index = 0; +//cczheng change param void to int +// void mt_disp_show_boot_logo(void) +void mt_disp_show_boot_logo(int logo_index) +{ + //cczheng annotaion + //int logo_index = 0; dprintf(INFO, "[lk logo: %s %d]n",__FUNCTION__,__LINE__); mt_logo_get_custom_if(); if (logo_cust_if->show_boot_logo) { logo_cust_if->show_boot_logo(); } else { ///show_logo(0); init_fb_screen(); fill_animation_logo(logo_index, mt_get_fb_addr(), mt_get_tempfb_addr(), logo_addr, phical_screen); mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); } return; }
//cczheng add uboot read nvram logo index int get_bootlogo_flag(void) { long len, length; u64 start_address; part_t *part; part_dev_t *dev; char *part_name = "proinfo"; dev = mt_part_get_device(); if (!dev) { video_printf(" => !dev is true...n"); return 0; } part = mt_part_get_partition(part_name); if (!part) { video_printf(" => mboot_get_boot_logo_flag--- part = NULLn"); dprintf(INFO, "mboot_get_boot_logo_flag--- part = NULL"); return 0; } dprintf(INFO, "mboot_get_boot_logo_flag--- get_partition 1n"); length = 1024; start_address = (u64)part->start_sect * dev->blkdev->blksz; video_printf(" => start_address=%llun", start_address);//524288 unsigned char *addr; addr = (unsigned char *) malloc(length * sizeof(unsigned char)); int index = partition_get_index(part_name); if (index == -1) { video_printf(" => partition_get_index == -1n"); dprintf(INFO, "mboot_get_boot_logo_flag--- partition_get_index =%dn", index); return 0; } unsigned int part_id = partition_get_region(index); len = dev->read(dev, start_address, (uchar *) addr, length, part_id); if (len < 0) { video_printf(" => dev->read len < 0n"); dprintf(INFO, "mboot_get_boot_logo_flag--- dev->read len=%ldn", len); return 0; } video_printf(" => part_dev->read addr=%sn", addr);//& video_printf("The size of nvdata_result:%dn", sizeof(addr));//4 video_printf("nvramstr dex buff[0]=%d, buff[1]=%d, buff[2]=%d, buff[3]=%d n", addr[0],addr[1],addr[2],addr[3]);//26 int result = addr[0];//boot logo flag dprintf(INFO,"mboot_get_boot_logo_flag addr = %dn",result); video_printf(" => result=%dn", result); return result; } static void lk_display_show_logo(void) { #ifdef LK_PROFILING unsigned int time_show_logo = get_timer(0); #endif // LK_PROFILING #ifndef MACH_FPGA_NO_DISPLAY // mt_disp_show_boot_logo(); //cczheng add read logo index and pass to mt_logo int logo_index = get_bootlogo_flag(); video_printf(" => mt_disp_show_boot_logo==%dn", logo_index); mt_disp_show_boot_logo(logo_index); #endif // MACH_FPGA_NO_DISPLAY logo_lk_t = ((unsigned int)get_timer(boot_time)); #ifdef LK_PROFILING dprintf(CRITICAL, "[PROFILE] show logo takes %d msn", (int)get_timer(time_show_logo)); #endif // LK_PROFILING }
4、预置logo资源打包到rom中
ifeq ($(strip $(SUPPORT_CARRIEREXPRESS_PACK)),yes) RESOURCE_OBJ_LIST += $(BOOT_LOGO_DIR)/$(BASE_LOGO)/$(BASE_LOGO)_kernel.raw else RESOURCE_OBJ_LIST += $(BOOT_LOGO_DIR)/$(BOOT_LOGO)/$(BOOT_LOGO)_kernel.raw endif endif endif +RESOURCE_OBJ_LIST += + $(BOOT_LOGO_DIR)/$(BOOT_LOGO)/$(BOOT_LOGO)_uboot_kernel.raw
+++ b/alps/vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/update @@ -44,6 +44,7 @@ p=$1 ./tool/bmp_to_raw ./temp36.raw ./$p/"${p}_bat_img".bmp ./tool/bmp_to_raw ./temp37.raw ./$p/"${p}_bat_100".bmp ./tool/bmp_to_raw ./boot_logo ./$p/"${p}_kernel".bmp +./tool/bmp_to_raw ./boot_logo ./$p/"${p}_uboot_kernel".bmp ./tool/zpipe -l 9 ./"${p}.raw" temp0.raw temp1.raw temp2.raw temp3.raw temp4.raw temp5.raw temp6.raw temp7.raw temp8.raw temp9.raw temp10.raw temp11.raw temp12.raw temp13.raw temp14.raw temp15.raw temp16.raw temp17.raw temp18.raw temp19.raw temp20.raw temp21.raw temp22.raw temp23.raw temp24.raw temp25.raw temp26.raw temp27.raw temp28.raw temp29.raw temp30.raw temp31.raw temp32.raw temp33.raw temp34.raw temp35.raw temp36.raw temp37.raw rm -rf ./temp0.raw ./temp1.raw ./temp2.raw ./temp3.raw ./temp4.raw ./temp5.raw ./temp6.raw ./temp7.raw ./temp8.raw ./temp9.raw ./temp10.raw ./temp11.raw ./temp12.raw ./temp13.raw ./temp14.raw ./temp15.raw ./temp16.raw ./temp17.raw ./temp18.raw ./temp19.raw ./temp20.raw ./temp21.raw ./temp22.raw ./temp23.raw ./temp24.raw ./temp25.raw ./temp26.raw ./temp27.raw ./temp28.raw ./temp29.raw ./temp30.raw ./temp31.raw ./temp32.raw ./temp33.raw ./temp34.raw ./temp35.raw ./temp36.raw ./temp37.raw ./bootlogo.raw echo "conversion finished"
最终效果
<
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算