1.menuconfig config 设置framebuffer console framebuffer && support bootup logo .
2.将要显示的logo通过以下命令生成目标格式。
pngtopnm logo.png > logo.pnm
pnmquant 224 logo.pnm > logo_224.pnm
pnmnoraw logo_224.pnm > logo_224.ppm
3.用logo_224.ppm替换\drivers\video\logo\logo_linux_clut224.ppm,删除logo_linux_clut224.c logo_linux_clut224.o.
4.\drivers\fbdev\core\fbmem.c
int fb_show_logo(struct fb_info *info, int rotate)
{
int y;
y = fb_show_logo_line(info, rotate, fb_logo.logo, 0,1);//只显示1张
//num_online_cpus());
//y = fb_show_extra_logos(info, y, rotate);
return y;
}
fb_show_logo_line函数里设置logo显示位置
image.dx = 1;
image.dy = y+1;
image.width = logo->width;
image.height = logo->height;
5,重新编译烧录就可以正常显示logo.
6,但是logo与kernel文件绑定,每次更换logo就需要重新编译kernel文件。可以将logo数据保存在文件中,uboot启动时加载logo数据到特定内存地址(物理地址),运行到kernel时到将特定内存地址转换为虚拟地址,然后取出logo数据就可以正常显示。
8,uboot 下添加 env logofile logo.dat, ext4load mmc 2:2 0x38000000 logo.dat,
kernel dts 预留一段内存
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
linux,logo {
compatible = "yk-logo";
reusable;
reg = <0x38000000 0x1e00000>;
};
}
9,\drivers\video\logo\logo.c里面构造struct linux_logo yk_logo;
struct linux_logo {
int type; /* one of LINUX_LOGO_* */
unsigned int width;
unsigned int height;
unsigned int clutsize; /* LINUX_LOGO_CLUT224 only */
const unsigned char *clut; /* LINUX_LOGO_CLUT224 only */
const unsigned char *data;
};
为了减少修改,我们用linux_logo结构体前16个字节来存储data_size(数据data长度) width(图片宽) height(图片高) clut_size(数据clut长度),
我们的数据构成 : (16byte)type width height clutsize + (clut长度byte) clut + (data长度byte) data.
fb_find_logo(int depth)函数里添加
phys_addr_t logo_addr = (phys_addr_t)(0x38000000);//物理地址
char *vir_logo_addr=phys_to_virt(logo_addr);//物理地址转换虚拟地址
memcpy(&yk_logo,vir_logo_addr,16);//复制我们要的16byte
if((yk_logo.clutsize == 663) && (yk_logo.width < 1918) && (yk_logo.height < 1078))//根据需求,简单的判断一下
{
yk_logo.type = LINUX_LOGO_CLUT224 ;
yk_logo.clutsize=yk_logo.clutsize/3;
yk_logo.clut = vir_logo_addr + 16;
yk_logo.data = vir_logo_addr + 16 + yk_logo.clutsize;
logo = &yk_logo;//给我们的yk_logo赋值完成后,就可以给了。
}
10,logo.dat借用kernel产生的logo_linux_clut224.c来产生。
编译完成kernel后会产生logo_linux_clut224.c,我们把它简单胡改造一下,
struct linux_logo{
int type;
unsigned int width;
unsigned int height;
unsigned int clutsize;
};
static unsigned char logo_linux_clut224_data[]= {//主要是要这个数组,它是我们的logo数据。
};
static unsigned char logo_linux_clut224_clut[] = {//主要是要这个数组,它是我们的logo数据。
};
struct linux_logo logo_linux_clut224;
int main(int argc, char **argv)
{
logo_linux_clut224.width = 1918;
logo_linux_clut224.height = 1078;
logo_linux_clut224.clutsize = sizeof(logo_linux_clut224_clut);
logo_linux_clut224.type = sizeof(logo_linux_clut224_data);
printf("width:%d\n",logo_linux_clut224.width);
printf("height:%d\n",logo_linux_clut224.height);
printf("clutsize:%d\n",logo_linux_clut224.clutsize);
printf("type:%d\n",logo_linux_clut224.type);
FILE* fp = fopen("logo.dat","w");
int len = 0;
int write_len = 0;
len = fwrite(&logo_linux_clut224,1,sizeof(logo_linux_clut224),fp);
printf("len = %d\n",len);
len = fwrite(&logo_linux_clut224_clut,1,sizeof(logo_linux_clut224_clut),fp);
printf("len = %d\n",len);
len = fwrite(&logo_linux_clut224_data,1,sizeof(logo_linux_clut224_data),fp);
printf("len = %d\n",len);
fclose(fp);
return 0;
}
这样logo.dat就产生好了,把它写入nand或者mmc,那么我们就可以直接就改logo数据来更换logo了。