相关代码与修改飞思卡尔/恩智浦的开机logo相关,并且参考了原版显示开机logo的代码,首先请确保你的板子烧写的是飞思卡尔提供的u-boot,保证lcd驱动正常并且启动时能显示NXP字样
1,找到工程中logo图像的位置并替换
6UL一般是通过Makefile将git/tools/logos文件夹下的bmp图像文件链接进程序中,再由bmp_logo.c文件转换成数组形式再进行显示的,首先需要保证bmp文件是256色BMP格式,不然程序转换会导致图片显示出错。
如图,freescale.bmp就是我们要找的文件
这时候如果我们将我们想要的bmp文件重命名成freescale.bmp后再放入文件夹中进行替换之后,重新将u-boot编译并烧写至板子中即可看到NXP已经被修改了。
2,分析git/drivers/video/cfb_console.c文件
在此文件中我们看到了关于bmp_logo_data.h的相关引用
#ifdef CONFIG_VIDEO_LOGO #ifdef CONFIG_VIDEO_BMP_LOGO #include <bmp_logo.h> #include <bmp_logo_data.h> #define VIDEO_LOGO_WIDTH BMP_LOGO_WIDTH #define VIDEO_LOGO_HEIGHT BMP_LOGO_HEIGHT #define VIDEO_LOGO_LUT_OFFSET BMP_LOGO_OFFSET #define VIDEO_LOGO_COLORS BMP_LOGO_COLORS
找到函数*video_logo
static void *video_logo(void) { char info[128]; int space, len; __maybe_unused int y_off = 0; __maybe_unused ulong addr; __maybe_unused char *s; splash_get_pos(&video_logo_xpos, &video_logo_ypos); #ifdef CONFIG_SPLASH_SCREEN s = getenv("splashimage"); if (s != NULL) { splash_screen_prepare(); addr = simple_strtoul(s, NULL, 16); if (video_display_bitmap(addr, video_logo_xpos, video_logo_ypos) == 0) { video_logo_height = 0; return ((void *) (video_fb_address)); } } #endif /* CONFIG_SPLASH_SCREEN */ logo_plot(video_fb_address, video_logo_xpos, video_logo_ypos); #ifdef CONFIG_SPLASH_SCREEN_ALIGN /* * when using splashpos for video_logo, skip any info * output on video console if the logo is not at 0,0 */ if (video_logo_xpos || video_logo_ypos) { /* * video_logo_height is used in text and cursor offset * calculations. Since the console is below the logo, * we need to adjust the logo height */ if (video_logo_ypos == BMP_ALIGN_CENTER) video_logo_height += max(0, (int)(VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT) / 2); else if (video_logo_ypos > 0) video_logo_height += video_logo_ypos; return video_fb_address + video_logo_height * VIDEO_LINE_LEN; } #endif if (board_cfb_skip()) return 0; sprintf(info, " %s", version_string); space = (VIDEO_COLS - VIDEO_INFO_X) / VIDEO_FONT_WIDTH; len = strlen(info); if (len > space) { int xx = VIDEO_INFO_X, yy = VIDEO_INFO_Y; uchar *p = (uchar *) info; while (len) { if (len > space) { video_drawchars(xx, yy, p, space); len -= space; p = (uchar *) p + space; if (!y_off) { xx += VIDEO_FONT_WIDTH; space--; } yy += VIDEO_FONT_HEIGHT; y_off++; } else { video_drawchars(xx, yy, p, len); len = 0; } } } else video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *) info); #ifdef CONFIG_CONSOLE_EXTRA_INFO { int i, n = ((video_logo_height - VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT); for (i = 1; i < n; i++) { video_get_info_str(i, info); if (!*info) continue; len = strlen(info); if (len > space) { video_drawchars(VIDEO_INFO_X, VIDEO_INFO_Y + (i + y_off) * VIDEO_FONT_HEIGHT, (uchar *) info, space); y_off++; video_drawchars(VIDEO_INFO_X + VIDEO_FONT_WIDTH, VIDEO_INFO_Y + (i + y_off) * VIDEO_FONT_HEIGHT, (uchar *) info + space, len - space); } else { video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y + (i + y_off) * VIDEO_FONT_HEIGHT, (uchar *) info); } } } #endif return (video_fb_address + video_logo_height * VIDEO_LINE_LEN); }
此函数就是I.MX6ULL用于显示LOGO的函数,只需要更改此函数即可达到修改LOGO的目的,首先Makefile在自动生成logo_bmp相关的信息时会生成此LOGO的相关定义头文件bmp_logo.h,如下是默认logo文件生成的头文件
/* * Automatically generated by "tools/bmp_logo" * * DO NOT EDIT * */ #ifndef __BMP_LOGO_H__ #define __BMP_LOGO_H__ #define BMP_LOGO_WIDTH 364 #define BMP_LOGO_HEIGHT 128 #define BMP_LOGO_COLORS 240 #define BMP_LOGO_OFFSET 16 extern unsigned short bmp_logo_palette[]; extern unsigned char bmp_logo_bitmap[]; #endif /* __BMP_LOGO_H__ */
其中有包含logo长度与宽度的宏定义,我们可以利用这些宏定义来进行代码的编写。
接下来我们进行对*video_logo函数的修改,在函数的定义变量后加入以下的语句
char info[128]; int space, len; __maybe_unused int y_off = 0; __maybe_unused ulong addr; __maybe_unused char *s; if(video_logo_xpos == 0 && video_logo_ypos == 0) { video_logo_xpos = (VIDEO_VISIBLE_COLS - BMP_LOGO_WIDTH ) >> 1; video_logo_ypos = (VIDEO_VISIBLE_ROWS - BMP_LOGO_HEIGHT) >> 1; }
将video_logo_xpos与video_logo_ypos分别设置为(屏幕长度-图片长度)的一半
//将数据左移1就是除2。
即将图片完整的显示在中间(如果直接使用屏幕的一半的话会超过中间显示,可以自己去试)
接下来将U-boot烧进板子,可以看到LOGO图片已经显示在中间了。
非常完美的LOGO!
3,修改宏定义CONFIG_SPLASH_SCREEN_ALIGN字段
以下是*video_logo函数中对于宏定义CONFIG_SPLASH_SCREEN_ALIGN汇编定义中的一段代码
#ifdef CONFIG_SPLASH_SCREEN_ALIGN /* * when using splashpos for video_logo, skip any info * output on video console if the logo is not at 0,0 */ if (video_logo_xpos || video_logo_ypos) { /* * video_logo_height is used in text and cursor offset * calculations. Since the console is below the logo, * we need to adjust the logo height */ if (video_logo_ypos == BMP_ALIGN_CENTER) video_logo_height += max(0, (int)(VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT) / 2); else if (video_logo_ypos > 0) video_logo_height += video_logo_ypos; return video_fb_address + video_logo_height * VIDEO_LINE_LEN; } #endif
看着注释我们就知道了这段代码的作用就是如果logo的显示位置不在(0,0)点就不显示info消息,但是如果我们依旧需要显示一些需要的信息,就不能定义这个宏了。
取消这段代码很简单,随便修改宏定义或者直接改成0,还有就是在mu6ullevk.h中注释掉这段宏定义。
甚至可以直接删光
#define CONFIG_SYS_CONSOLE_IS_IN_ENV #define CONFIG_SPLASH_SCREEN //#define CONFIG_SPLASH_SCREEN_ALIGN #define CONFIG_CMD_BMP #define CONFIG_BMP_16BPP
我们知道默认在屏幕上输出的信息是宏定义U_BOOT_VERSION_STRING,这是此宏定义在/include/version.h中的定义
#define U_BOOT_VERSION_STRING U_BOOT_VERSION " (" U_BOOT_DATE " - " \ U_BOOT_TIME " " U_BOOT_TZ ")" CONFIG_IDENT_STRING
就是uboot相关的一些编译信息,但是我们有些时候想显示一点自定义字段怎么办。
4,修改video_drawstring函数
通过观察*video_logo函数可以找到如下语句
sprintf(info, " %s", version_string); ··· else video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *) info);
可以看出先通过sprintf函数将version_string[]中的字段提取到info中,看一下version_string的定义。
const char __weak version_string[] = U_BOOT_VERSION_STRING;
很明显就是宏定义U_BOOT_VERSION_STRING,那么如果我们要修改打印的字段只需要修改else后面的video_drawstring就可以了。
将原来的注释掉,并且写上新的,三个参数分别代表(左上角为零点)(x轴距离,y轴距离,字符串指针),所以在写最后的字符串时先写字符串再强制类型转换为uchar *型就行了。
5,想使用自己的logo名,不想重命名
修改git/tools/下的Makefile在200行左右关于LOGO_BMP的定义
在第三个endif后加入以下定义
LOGO_BMP= $(srctree)/$(src)/logos/“你的文件名”.bmp
即可完成logo文件名的更换(一定要256色的bmp文件!),之后Makefile会将指定的bmp文件转换成bmp_logo.h&bmp_logo_data.h
重新编译烧写之后就会发现logo正下方出现自定义信息了