Linux开机LOGO更换以及附带问题
应用层更换Linux机器开机启动LOGO
平台开机Logo默认是编译进内核的,更换起来很不方便,通过改写内核源码,可以实现应用层直接更换内核Logo。
1.uboot相关修改
网上教程一般会这么改
"loadlogo=mmc read 0x15000000 0x5800 0x2800;\0" \
"run loadlogo; " \
核心代码是
mmc read 0x15000000 0x5800 0x2800;
这个命令的作用是从MMC或SD卡的第22528(0x5800)个扇区开始,读取10240(0x2800)个扇区的数据,并将这些数据存储到内存地址0x15000000处。这种操作通常用于将存储设备上的数据加载到内存中,以便进行进一步的处理或执行。
目的是将图片文件放到0x15000000处,用于后面logo.c文件中使用
。
但经过实践发现,这么改会存在
"run loadlogo; "
未执行的情况,从而导致LOGO更换不上。
故选择将最后一段改成:
"else run netboot; fi; mmc read 0x15000000 0x5800 0x2800;"
解决。(可能还需要手动进uboot命令行,将bootcmd重置成默认)
2.kernel内核文件修改
修改drivers/video/logo/Kconfig文件
在最后新加一个LOGO_LINUX_CUSTOM_CLUT224的配置选项:
/* 在如下配置 */
config LOGO_LINUX_CUSTOM_CLUT224
bool "Custom 224-color linux logo"
default y
endif # LOGO
修改drivers/video/logo/logo.c文件
到这一步可以有两种修改办法,这取决于后续LOGO图片是怎么处理的
首先在头部增加如下代码
/* logo's are marked __initdata. Use __init_refok to tell
* modpost that it is intended that this function uses data
* marked __initdata.
*/
#ifdef CONFIG_LOGO_LINUX_CUSTOM_CLUT224 //新增
#define IMAGE_HEAD_SIZE 54
#define IMAGE_MAX_PIXEL 2048000
#define IMAGE_MAX_SIZE (IMAGE_HEAD_SIZE+IMAGE_MAX_PIXEL+1024)
#define COLOR_MAX_NUM 224 /* linux logo just support 224 colors */
#define IMAGE_MTD_NUM 4 /* the logo saved in MTD4 */
#define IMAGE_OFFSET 0x0 /* the logo's offset int the mtd area */
volatile static unsigned char* remapped_area;
static unsigned char logo_flash_clut224_data[IMAGE_MAX_PIXEL] __initdata = {0};
static unsigned char logo_flash_clut224_clut[COLOR_MAX_NUM * 3] __initdata = {0};
static struct linux_logo logo_flash_clut224 __initdata =
{
.type = LINUX_LOGO_CLUT224,
.width = 0,
.height = 0,
.clutsize = 0,
.clut = logo_flash_clut224_clut,
.data = logo_flash_clut224_data,
};
#endif
const struct linux_logo * __init_refok fb_find_logo(int depth)
{
const struct linux_logo *logo = NULL;
if (nologo)...
后续分成:
LINUX上处理图片
和
WINDOWS上处理图片
如果图片在
Linux
上处理,在
if (depth >= 8)
做如下修改:
if (depth >= 8)
{
#ifdef CONFIG_LOGO_LINUX_CUSTOM_CLUT224
unsigned char head[60] = {0};
unsigned char *image = NULL;
unsigned char *clut = NULL;
unsigned char *data = NULL;
int clutsize = 0;
int size = 0;
int offset = 0;
int width = 0;
int height = 0;
int count = 0;
int compress = 0;
int sizeimage = 0;
int clrused = 0;
int i = 0;
int j = 0;
int fi = 0;
int li = 0;
unsigned int real_width = 0;
unsigned int logo_index = 0;
remapped_area = __phys_to_virt(0x15000000);
memcpy(head, remapped_area, 58);
printk("image head:%c%c\n", head[0], head[1]);
if(head[0] == 'K' && head[1] == 'I'&& head[2] == 'K')
{
printk("right ppm image head");
memcpy( &logo_flash_clut224.width, remapped_area+3, 4);
memcpy( &logo_flash_clut224.height, remapped_area + 4+3, 4);
memcpy( &logo_flash_clut224.clutsize, remapped_area + 8+3, 4);
memcpy( logo_flash_clut224.data, remapped_area + 15, logo_flash_clut224.width * logo_flash_clut224.height);
memcpy( logo_flash_clut224.clut, remapped_area + 15 + (logo_flash_clut224.width * logo_flash_clut224.height), logo_flash_clut224.clutsize * 3);
logo=&logo_flash_clut224;
}
else
{
#ifdef CONFIG_LOGO_LINUX_CLUT224
printk("LINUX_clut224\n");
logo = &logo_linux_clut224;
#endif
}
#endif
如果选择在
Windows
上处理LOGO图片,代码改成
#ifdef CONFIG_LOGO_LINUX_CUSTOM_CLUT224
unsigned char head[60] = {0};
unsigned char *image = NULL;
unsigned char *clut = NULL;
unsigned char *data = NULL;
int clutsize = 0;
int size = 0;
int offset = 0;
int width = 0;
int height = 0;
int count = 0;
int compress = 0;
int sizeimage = 0;
int clrused = 0;
int i = 0;
int j = 0;
int fi = 0;
int li = 0;
unsigned int real_width = 0;
unsigned int logo_index = 0;
remapped_area = __phys_to_virt(0x15000000);
memcpy(head, remapped_area, 58);
printk(" %s-%d:right image head:%c%c\n", __FILE__, __LINE__, head[0], head[1]);
if(1)
{
printk("right ppm image head");
memcpy( &logo_flash_clut224.width, remapped_area+4, 4);
memcpy( &logo_flash_clut224.height, remapped_area + 8, 4);
memcpy( &logo_flash_clut224.clutsize, remapped_area + 12, 4);
memcpy( logo_flash_clut224.data, remapped_area + 16, logo_flash_clut224.width * logo_flash_clut224.height);
memcpy( logo_flash_clut224.clut, remapped_area + 16 + (logo_flash_clut224.width * logo_flash_clut224.height), logo_flash_clut224.clutsize * 3);
logo=&logo_flash_clut224;
}
else
{
#ifdef CONFIG_LOGO_LINUX_CLUT224
printk("LINUX_clut224\n");
logo = &logo_linux_clut224;
#endif
}
#endif
没错,就是因为后续图片格式会有所不一样,读取图片信息的方式也不同。
之后在然后重新编译内核。配置内核时,需要去掉logo路径下的其它选项,只保留Custom 224-color linux logo这一个选项。
3.LOGO图片修改
因为Logo图片中所使用的颜色数不能超过224种,如果超过将无法正常显示,因此我们需要制作符合要求的图像。
Linux
环境下制作:
先下载附件
res
Windows环境
下制作:方法是我自己寻找制作的,因为有这种需求,安装包放在云盘中
链接:
https://pan.baidu.com/s/1Yn7BtTh4GtVqoS-cc2nU8Q?pwd=1234
提取码:1234
按照文件中readme.txt一步步执行即可
两者都是为了把图片制作成mylogo.bin提供给logo.c解读,使LOGO修改生效
你用哪种方式,上述logo.c就改成哪种就行。
4.去除linux的开机光标
光标会导致LOGO图片显示时,左上角有黑块,方法如下:
在内核的当前目录进入到drivers/video/console/fbcon.c文件
将static void fb_flashcursor(void *private) 和 static void fbcon_cursor(struct vc_data *vc, int mode) 里的内容注释掉,使之变成空函数
我的建议是在这两个函数开头直接return;就行