嵌入式Linux是直接在FrameBuffer的基础上。直接显示一个ppm格式的图象,它由kernel/drivers/video/fbcon.c中的fbcon_show_logo()完成,最大颜色支持224色而不常见的255色。默认的logo文件是 drivers/video/logo/logo_linux_clut224.ppm.
由于linux内核默认的开机logo是从内核文件(如zImage)中读取的,因此要想实现应用层修改内核开机logo就必须要将logo放在内核文件外引导。
1.首先修改driver/video/logo下的Kconfig文件,添加如下代码
config LOGO_LINUX_CUSTOM_CLUT224
bool "Custom 224-color Linux logo"
default y
内核源码路径下make menuconfig,将其他logo选项去掉。
2.修改driver/video/logo/logo.c,添加如下代码
#ifdef CONFIG_LOGO_LINUX_CUSTOM_CLUT224
volatile static unsigned char* remapped_area;
static unsigned char clut[224*3];
static unsigned char data[800*480];
struct linux_logo logo_buf = {
.type = LINUX_LOGO_CLUT224, //LINUX_LOGO_CLUT224,
.width = 800,
.height = 480,
.clutsize = 224,
.clut = clut,
.data = data
};
#endif // CONFIG_LOGO_LINUX_CUSTOM_CLUT224
在函数const struct linux_logo * __init_refok fb_find_logo(int depth)中添加如下代码
#ifdef CONFIG_LOGO_LINUX_CUSTOM_CLUT224
logo = &logo_buf;
remapped_area = __phys_to_virt(0x85800000);
memcpy( &logo->width, remapped_area, 4);
memcpy( &logo->height, remapped_area + 4, 4);
memcpy( &logo->clutsize, remapped_area + 8, 4);
memcpy( logo->clut, remapped_area + 12, logo->clutsize * 3);
memcpy( logo->data, remapped_area + 12 + logo->clutsize * 3, logo->width * logo->height);
#endif // CONFIG_LOGO_LINUX_CUSTOM_CLUT224
这样就实现了内核logo数据不再从内核中文件中读取数据,而是读取内存中固定地址位置数据;其中remapped_area = __phys_to_virt(0x85800000);中的地址0x85800000对应于uboot中的
#define ENV_LOGO \
"loadlogo=nand read.e ${splashimage} logo\0" \
"splashimage=0x85800000\0" \
"splashpos=m,m\0"
可见在这里uboot把logo分区读写到ram地址0x85800000中,因此在内核中才能使用__phys_to_virt将这段保存了内核logo数据的地址映射出来,用于显示。(最好能给logo数据保存的内存一个独立的分区)。
3.重新编译内核
4.制作logo数据文件,首先得到一张与开发板LCD分辨率差不多大小的bmp或者png格式的图片,使用如下命令制作内核logo数据文件:
bmptopnm linux_logo.bmp > linux_logo.pnm/pngtopnm logo_linux.png > logo_linux.pnm
pnmquant 224 logo_linux.pnm > logo_linux_clut224.pnm
pnmtoplainpnm logo_linux_clut224.pnm > logo_linux_clut224.ppm
scripts/pnmtologo -t clut224 -n logo_linux_clut224 -o logo.dat logo_linux_clut224.ppm
其中若出现命令找到不的情况可以使用 apt-get install netpbm安装,pnmtologo是由内核目录下scripts/pnmtologo.c编译而成,经过本人修改用于生成能直接烧录进内存并且做logo显示的logo.dat文件。在linux内核源码中,driver/video/logo的Makefile中,相关代码如下:
obj-$(CONFIG_LOGO) += logo.o
obj-$(CONFIG_LOGO_LINUX_CLUT224) += logo_linux_clut224.o
# 224 Logos
extra-y += $(call logo-cfiles,_clut224,ppm)
pnmtologo := scripts/pnmtologo
quiet_cmd_logo = LOGO $@
cmd_logo = $(pnmtologo) \
-t $(patsubst $*_%,%,$(notdir $(basename $<))) \
-n $(notdir $(basename $s<)) -o $@ $<
$(obj)/%_clut224.c: $(src)/%_clut224.ppm $(pnmtologo) FORCE
$(call if_changed,logo)
5.将logo.dat烧录进logo分区,在应用层可使用
flash_eraseall /dev/mtd7
nandwrite -pn /dev/mtd7 logo.dat
也可以在uboot阶段将logo.dat烧录进logo分区,具体看uboot有没有这个接口,没有可以自己实现,也不难。参考链接如下:
https://blog.csdn.net/langdao04/article/details/78614430