应用层更换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;就行

参考连接:
如何修改 ARM Linux 系统的启动画面
去除linux的开机光标
应用层更换内核启动logo

标签: none

添加新评论