1.不同平台或存储介质的不同处理方案

对于AM3354平台需要增加logo分区,对于STM32MP15平台只需要把最终的bin文件放在bootfs分区即可。

nand分区如下(EMMC同理):

2.修改linux源码kernel/drivers/video/logo/logo.c

#define WIDTH_LEN    4
#define HEIGHT_LEN  4
#define CLUTSIZE_LEN    4const struct linux_logo * __init_refok fb_find_logo(int depth)
{struct linux_logo *logo = NULL;int i = 0, k = 0;//struct linux_logo *logo_buf = NULL;unsigned char *clut = NULL, *data = NULL;volatile void *mapped_area = NULL;unsigned int height = 0, width = 0, pixsize = 0;if (nologo)return NULL;mapped_area = __va(0x84000000);//记住该地址,很重要,配置uboot环境变量需要用到logo = kmalloc(sizeof(struct linux_logo), GFP_KERNEL);if(!logo){printk("kmalloc error!\n");return NULL;}logo->type = 3;logo->width = 800;logo->height = 480;logo->clutsize = 224;width = (*(unsigned char*)(mapped_area)<<24) | (*(unsigned char*)(mapped_area+1)<<16) \| (*(unsigned char *)(mapped_area+2)<<8) | (*(unsigned char*)(mapped_area+3));height = (*(unsigned char*)(mapped_area+4)<<24) | (*(unsigned char*)(mapped_area+5)<<16) \| (*(unsigned char *)(mapped_area+6)<<8) | (*(unsigned char*)(mapped_area+7));logo->width = width;logo->height = height;pixsize = width*height;printk("Logo parameter width:%d height:%d ", width, height);data = kmalloc(pixsize, GFP_KERNEL);if(!data){printk("kmalloc data error!\n");kfree(logo);return NULL;}for(i = 0; i < pixsize; i++){data[i] = *(unsigned char *)(mapped_area+8+i);}logo->clutsize = (*(unsigned char *)(mapped_area+8+pixsize)<<24) | (*(unsigned char *)(mapped_area+8+pixsize+1)<<16) \| (*(unsigned char *)(mapped_area+8+pixsize+2)<<8) | (*(unsigned char *)(mapped_area+8+pixsize+3));printk("clutsize:%d\n", logo->clutsize);clut = kmalloc(logo->clutsize*3, GFP_KERNEL);if(!clut){printk("kmalloc clut error!\n");kfree(data);kfree(logo);return NULL;}for(i = 0, k = 0; i < logo->clutsize; k+=3, i++){clut[k] = *(unsigned char *)(mapped_area+8+pixsize+4+k);clut[k+1] = *(unsigned char *)(mapped_area+8+pixsize+4+k+1);clut[k+2] = *(unsigned char *)(mapped_area+8+pixsize+4+k+2);}logo->clut = clut;logo->data = data;return logo;
}

2.制作logo.bin文件

  1. 准备一张 png 格式的 logo 图片,其中分辨率应跟内核配置的 lcd 参数一致(显示屏有关)。
  2. 在 ubuntu 系统下将 png 图片转换为 ppm 文件,命令过程如下:
    pngtopnm linux_logo.png > linux_logo.pnm
    pnmquant 224 linux_logo.pnm > logo_clut224.pnm
    pnmtoplainpnm logo_clut224.pnm > logo_clut224.ppm
  3. 将生成 ppm 文件生成最后的 logo 图片数据文件。命令如下所示:
    ppmtobin logo_clut224.ppm -t clut224 -o logo.bin

3.烧写logo.bin文件

am335x:
flash_erase /dev/mtd4 0 0
nandwrite -p /dev/mtd4 logo.bin

stm32MP15平台将logo.bin拷贝到bootfs

4.设置u-boot环境变量

am335x:

nandboot=echo Booting from nand ...; run nandargs; nand read ${loadaddr} ${nandsrcaddr} ${nandimgsize}; bootm ${loadaddr} nandimgsize=0x500000

loadaddr: 0x84000000 logo.c映射的地址
nandsrcaddr:logo分区的起始地址
nandimgsize:logo分区的大小
stm32mp15:

setenv bootcmd "ext4load mmc 1:2 $splashimage logo.bin; run bootcmd_stm32mp"

ppmtobin源码如下:


/**  Convert a logo in ASCII PNM format to C source suitable for inclusion in*  the Linux kernel**  (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org>* *  --------------------------------------------------------------------------**  This file is subject to the terms and conditions of the GNU General Public*  License. See the file COPYING in the main directory of the Linux*  distribution for more details.*/#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>static const char *programname;
static const char *filename;
static const char *logoname = "linux_logo";
static const char *outputname;
static FILE *out;#define LINUX_LOGO_MONO        1   /* monochrome black/white */
#define LINUX_LOGO_VGA16    2   /* 16 colors VGA text palette */
#define LINUX_LOGO_CLUT224  3   /* 224 colors */
#define LINUX_LOGO_GRAY256  4   /* 256 levels grayscale */static const char *logo_types[LINUX_LOGO_GRAY256+1] = {[LINUX_LOGO_MONO] = "LINUX_LOGO_MONO",[LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16",[LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224",[LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256"
};#define MAX_LINUX_LOGO_COLORS 224struct color {unsigned char red;unsigned char green;unsigned char blue;
};static const struct color clut_vga16[16] = {{ 0x00, 0x00, 0x00 },{ 0x00, 0x00, 0xaa },{ 0x00, 0xaa, 0x00 },{ 0x00, 0xaa, 0xaa },{ 0xaa, 0x00, 0x00 },{ 0xaa, 0x00, 0xaa },{ 0xaa, 0x55, 0x00 },{ 0xaa, 0xaa, 0xaa },{ 0x55, 0x55, 0x55 },{ 0x55, 0x55, 0xff },{ 0x55, 0xff, 0x55 },{ 0x55, 0xff, 0xff },{ 0xff, 0x55, 0x55 },{ 0xff, 0x55, 0xff },{ 0xff, 0xff, 0x55 },{ 0xff, 0xff, 0xff },
};static int logo_type = LINUX_LOGO_CLUT224;
static unsigned int logo_width;
static unsigned int logo_height;
static struct color **logo_data;
static struct color logo_clut[MAX_LINUX_LOGO_COLORS];
static unsigned int logo_clutsize;static void die(const char *fmt, ...)__attribute__ ((noreturn)) __attribute ((format (printf, 1, 2)));
static void usage(void) __attribute ((noreturn));static unsigned int get_number(FILE *fp)
{int c, val;/* Skip leading whitespace */do {c = fgetc(fp);if (c == EOF)die("%s: end of file\n", filename);if (c == '#') {/* Ignore comments 'till end of line */do {c = fgetc(fp);if (c == EOF)die("%s: end of file\n", filename);} while (c != '\n');}} while (isspace(c));/* Parse decimal number */val = 0;while (isdigit(c)) {val = 10*val+c-'0';c = fgetc(fp);if (c == EOF)die("%s: end of file\n", filename);}return val;
}static unsigned int get_number255(FILE *fp, unsigned int maxval)
{unsigned int val = get_number(fp);return (255*val+maxval/2)/maxval;
}static void read_image(void)
{FILE *fp;unsigned int i, j;int magic;unsigned int maxval;/* open image file */fp = fopen(filename, "r");if (!fp)die("Cannot open file %s: %s\n", filename, strerror(errno));/* check file type and read file header */magic = fgetc(fp);if (magic != 'P')die("%s is not a PNM file\n", filename);magic = fgetc(fp);switch (magic) {case '1':case '2':case '3':/* Plain PBM/PGM/PPM */break;case '4':case '5':case '6':/* Binary PBM/PGM/PPM */die("%s: Binary PNM is not supported\n""Use pnmnoraw(1) to convert it to ASCII PNM\n", filename);default:die("%s is not a PNM file\n", filename);}logo_width = get_number(fp);logo_height = get_number(fp);/* allocate image data */logo_data = (struct color **)malloc(logo_height*sizeof(struct color *));if (!logo_data)die("%s\n", strerror(errno));for (i = 0; i < logo_height; i++) {logo_data[i] = malloc(logo_width*sizeof(struct color));if (!logo_data[i])die("%s\n", strerror(errno));}/* read image data */switch (magic) {case '1':/* Plain PBM */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++)logo_data[i][j].red = logo_data[i][j].green =logo_data[i][j].blue = 255*(1-get_number(fp));break;case '2':/* Plain PGM */maxval = get_number(fp);for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++)logo_data[i][j].red = logo_data[i][j].green =logo_data[i][j].blue = get_number255(fp, maxval);break;case '3':/* Plain PPM */maxval = get_number(fp);for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++) {logo_data[i][j].red = get_number255(fp, maxval);logo_data[i][j].green = get_number255(fp, maxval);logo_data[i][j].blue = get_number255(fp, maxval);}break;}/* close file */fclose(fp);
}static inline int is_black(struct color c)
{return c.red == 0 && c.green == 0 && c.blue == 0;
}static inline int is_white(struct color c)
{return c.red == 255 && c.green == 255 && c.blue == 255;
}static inline int is_gray(struct color c)
{return c.red == c.green && c.red == c.blue;
}static inline int is_equal(struct color c1, struct color c2)
{return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue;
}static void write_header(void)
{/* open logo file */if (outputname) {out = fopen(outputname, "w");if (!out)die("Cannot create file %s: %s\n", outputname, strerror(errno));} else {out = stdout;}fputs("/*\n", out);fputs(" *  DO NOT EDIT THIS FILE!\n", out);fputs(" *\n", out);fprintf(out, " *  It was automatically generated from %s\n", filename);fputs(" *\n", out);fprintf(out, " *  Linux logo %s\n", logoname);fputs(" */\n\n", out);fputs("#include <linux/linux_logo.h>\n\n", out);fprintf(out, "static unsigned char %s_data[] __initdata = {\n",logoname);
}static void write_footer(void)
{fputs("\n};\n\n", out);fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname);fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]);fprintf(out, "\t.width\t\t= %d,\n", logo_width);fprintf(out, "\t.height\t\t= %d,\n", logo_height);if (logo_type == LINUX_LOGO_CLUT224) {fprintf(out, "\t.clutsize\t= %d,\n", logo_clutsize);fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname);}fprintf(out, "\t.data\t\t= %s_data\n", logoname);fputs("};\n\n", out);/* close logo file */if (outputname)fclose(out);
}static int write_hex_cnt;static void write_hex(unsigned char byte)
{if (write_hex_cnt % 12)fprintf(out, ", 0x%02x", byte);else if (write_hex_cnt)fprintf(out, ",\n\t0x%02x", byte);elsefprintf(out, "\t0x%02x", byte);write_hex_cnt++;
}static void write_logo_mono(void)
{unsigned int i, j;unsigned char val, bit;/* validate image */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++)if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))die("Image must be monochrome\n");/* write file header */write_header();/* write logo data */for (i = 0; i < logo_height; i++) {for (j = 0; j < logo_width;) {for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1)if (logo_data[i][j].red)val |= bit;write_hex(val);}}/* write logo structure and file footer */write_footer();
}static void write_logo_vga16(void)
{unsigned int i, j, k;unsigned char val;/* validate image */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++) {for (k = 0; k < 16; k++)if (is_equal(logo_data[i][j], clut_vga16[k]))break;if (k == 16)die("Image must use the 16 console colors only\n""Use ppmquant(1) -map clut_vga16.ppm to reduce the number ""of colors\n");}/* write file header */write_header();/* write logo data */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++) {for (k = 0; k < 16; k++)if (is_equal(logo_data[i][j], clut_vga16[k]))break;val = k<<4;if (++j < logo_width) {for (k = 0; k < 16; k++)if (is_equal(logo_data[i][j], clut_vga16[k]))break;val |= k;}write_hex(val);}/* write logo structure and file footer */write_footer();
}#if 0
static void write_logo_clut224(void)
{unsigned int i, j, k;/* validate image */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++) {for (k = 0; k < logo_clutsize; k++)if (is_equal(logo_data[i][j], logo_clut[k]))break;if (k == logo_clutsize) {if (logo_clutsize == MAX_LINUX_LOGO_COLORS)die("Image has more than %d colors\n""Use ppmquant(1) to reduce the number of colors\n",MAX_LINUX_LOGO_COLORS);logo_clut[logo_clutsize++] = logo_data[i][j];}}/* write file header */write_header();/* write logo data */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++) {for (k = 0; k < logo_clutsize; k++)if (is_equal(logo_data[i][j], logo_clut[k]))break;write_hex(k+32);}fputs("\n};\n\n", out);/* write logo clut */fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",logoname);write_hex_cnt = 0;for (i = 0; i < logo_clutsize; i++) {write_hex(logo_clut[i].red);write_hex(logo_clut[i].green);write_hex(logo_clut[i].blue);}/* write logo structure and file footer */write_footer();
}
#else
static void write_logo_clut224(void)
{unsigned int i, j, k;unsigned char *clut224_data = NULL;unsigned char clutsize_array[4] = {0};unsigned char x[4] = {0}, y[4] = {0};FILE* fp = NULL;int fd = 0, ret = -1;//size_t ret = 0;/* validate image */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++) {for (k = 0; k < logo_clutsize; k++)if (is_equal(logo_data[i][j], logo_clut[k]))break;if (k == logo_clutsize) {if (logo_clutsize == MAX_LINUX_LOGO_COLORS)die("Image has more than %d colors\n""Use ppmquant(1) to reduce the number of colors\n",MAX_LINUX_LOGO_COLORS);logo_clut[logo_clutsize++] = logo_data[i][j];}}clut224_data = (unsigned char *)malloc(logo_height*logo_width);if(!clut224_data){//fprintf(stderr, "clut224 data malloc error!\n");printf("clut224 data malloc error!\n");exit(1);}printf("logo width:%d, height:%d, clutsize:%d\n", logo_width, logo_height, logo_clutsize);   /* write logo data */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++) {for (k = 0; k < logo_clutsize; k++)if (is_equal(logo_data[i][j], logo_clut[k]))break;//write_hex(k+32);clut224_data[i*logo_width+j] = k+32;}//fp = fopen(outputname, "w");//if(!fp){fd = open(outputname, O_WRONLY | O_CREAT, 0644);if(fd < 0 ){fprintf(stderr, "open the output file error!\n");exit(1);}/* write width to output file */x[0] = (logo_width>>24)&0xff;x[1] = (logo_width>>16)&0xff;x[2] = (logo_width>>8)&0xff;x[3] = logo_width&0xff;ret = write(fd, x, 4);if(ret != 4){printf("write logo width error!\n");free(clut224_data);close(fd);exit(1);}/* write height to output file */y[0] = (logo_height>>24)&0xff;y[1] = (logo_height>>16)&0xff;y[2] = (logo_height>>8)&0xff;y[3] = logo_height&0xff;ret = write(fd, y, 4);if(ret != 4){printf("write logo height error!\n");free(clut224_data);close(fd);exit(1);}/* write index struct to the output file *///ret = fwrite(clut224_data, sizeof(unsigned char), logo_height*logo_width, fp);ret = write(fd, clut224_data, logo_width*logo_height);if(ret != logo_height*logo_width){printf("write clut index error!\n");free(clut224_data);close(fd);exit(1);}/* write logo_clutsize to output file */clutsize_array[0] = (logo_clutsize>>24)&0xff;clutsize_array[1] = (logo_clutsize>>16)&0xff;clutsize_array[2] = (logo_clutsize>>8)&0xff;clutsize_array[3] = logo_clutsize&0xff;//ret = fwrite(clutsize_array, sizeof(unsigned char), sizeof(int), fp);ret = write(fd, clutsize_array, 4);if(ret != 4){printf("write clutsize error!\n");free(clut224_data);close(fd);exit(1);}/* write logo clut */write_hex_cnt = 0;for (i = 0; i < logo_clutsize; i++) {//write_hex(logo_clut[i].red);//write_hex(logo_clut[i].green);//write_hex(logo_clut[i].blue);write(fd, &logo_clut[i].red, 1);write(fd, &logo_clut[i].green, 1);write(fd, &logo_clut[i].blue, 1);}free(clut224_data);close(fd);}
#endifstatic void write_logo_gray256(void)
{unsigned int i, j;/* validate image */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++)if (!is_gray(logo_data[i][j]))die("Image must be grayscale\n");/* write file header */write_header();/* write logo data */for (i = 0; i < logo_height; i++)for (j = 0; j < logo_width; j++)write_hex(logo_data[i][j].red);/* write logo structure and file footer */write_footer();
}static void die(const char *fmt, ...)
{va_list ap;va_start(ap, fmt);vfprintf(stderr, fmt, ap);va_end(ap);exit(1);
}static void usage(void)
{die("\n""Usage: %s [options] <filename>\n""\n""Valid options:\n""    -h          : display this usage information\n""    -n <name>   : specify logo name (default: linux_logo)\n""    -o <output> : output to file <output> instead of stdout\n""    -t <type>   : specify logo type, one of\n""                      mono    : monochrome black/white\n""                      vga16   : 16 colors VGA text palette\n""                      clut224 : 224 colors (default)\n""                      gray256 : 256 levels grayscale\n""\n", programname);
}int main(int argc, char *argv[])
{int opt;programname = argv[0];opterr = 0;while (1) {opt = getopt(argc, argv, "hn:o:t:");if (opt == -1)break;switch (opt) {case 'h':usage();break;case 'n':logoname = optarg;break;case 'o':outputname = optarg;break;case 't':if (!strcmp(optarg, "mono"))logo_type = LINUX_LOGO_MONO;else if (!strcmp(optarg, "vga16"))logo_type = LINUX_LOGO_VGA16;else if (!strcmp(optarg, "clut224"))logo_type = LINUX_LOGO_CLUT224;else if (!strcmp(optarg, "gray256"))logo_type = LINUX_LOGO_GRAY256;elseusage();break;default:usage();break;}}if (optind != argc-1)usage();filename = argv[optind];read_image();switch (logo_type) {case LINUX_LOGO_MONO://write_logo_mono();fprintf(stderr, "This type is not support!\n");break;case LINUX_LOGO_VGA16://write_logo_vga16();fprintf(stderr, "This type is not support!\n");break;case LINUX_LOGO_CLUT224:write_logo_clut224();break;case LINUX_LOGO_GRAY256://write_logo_gray256();fprintf(stderr, "This type is not support!\n");break;}exit(0);
}

自定义Linxu启动logo(从其他分区加载logo)相关推荐

  1. Android 自定义WaveProgressView满足你所有水波纹加载需求

    自定义WaveProgressView满足你所有水波纹加载需求

  2. Nginx 内置 命令启动,停止和重新加载Nginx

    使用Nginx命令启动,停止和重新加载NginxNginx具有一组内置工具,用于管理可以使用Nginx命令访问的服务. Nginx 启动 要启动Nginx和相关进程,请输入以下内容: sudo /et ...

  3. 删除Windows启动管理器下的加载项

    删除Windows启动管理器下的加载项 环境:Windows7操作系统 工具:cmd命令行工具 操作: > msconfig 系统配置工具 > bededit 启动菜单编辑器,命令行工具 ...

  4. 【SCADA】启动KingSCADA运行系统,提示加载报警库服务失败?

    大家好,我是雷工! 今天启动KingSCADA时,发现无法运行,提示"加载 报警库服务 失败",现将问题排查及解决问题的过程记录如下. 一.问题描述: 1.提示如下图: 2.信息窗 ...

  5. Flink程序加载数据源(3)自定义数据源(2)从Mysql 加载数据源

    Flink程序加载数据源(3)自定义数据源(2)从Mysql 加载数据源 ​ 上文引出了Flink程序自定义数据源的方法,我们来再次回顾下. ​ Flink还提供了数据源接口(抽象类),我们实现该接口 ...

  6. nginx重新加载php,如何使用nginx启动、停止和重新加载

    要启动nginx,请运行可执行文件. 当nginx启动后,可以通过使用-s参数调用可执行文件来控制它. 使用以下语法: ( 推荐学习:nginx使用 )nginx -s signal 信号(signa ...

  7. java加载自己写的类_java 自定义类加载器从磁盘或网络加载类

    一.编写自定义类加载器类 package com.mybatis.entity; import java.io.ByteArrayOutputStream; import java.io.File; ...

  8. java引入resource下的模板_Beetl自定义ResourceLoader,实现特殊的模板加载需求

    一直以来,有个目标是:使用Beetl的时候,如果web root 里有模板文件,则beetl从web root里加载.如果没有,则从jar里加载,或者从Db里加载. 这样,工程里大量相同的模板模板可以 ...

  9. 你所不知道的SQL Server数据库启动过程(用户数据库加载过程的疑难杂症)

    转http://www.cnblogs.com/zhijianliutang/p/4100103.html 前言 本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的 ...

最新文章

  1. 基于复杂方案OWSAP CsrfGuard的CSRF安全解决方案(适配nginx + DWR)
  2. 使用node.js作为简单的Web服务器
  3. JavaScriptjQuery 基本使用
  4. QT的QDesignerFormWindowInterface类的使用
  5. 【数据结构与算法】之深入解析“买卖股票的最好时机含手续费”的求解思路与算法示例
  6. android 5.0新增 ui 控件,android3.0新增ui控件示例说明.doc
  7. maven配置之:<distributionManagement>snapshot快照库和release发布库
  8. 用婴儿拍的视频训练自监督模型,学到了高级视觉表征
  9. Eclipse小技巧:收起outline的头文件
  10. Qt使用MSVC编译器关闭“warning: C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失”警告的方法
  11. 一个常见的下拉框(css)
  12. [BZOJ4523]路由表
  13. David Pozar 微波工程读书笔记(二)
  14. php环境配置PHPWAMP
  15. 国产UOS系统之——安装N卡驱动(多屏显示)
  16. html input限制输入小数,限制input输入小数只能到3位或者只能输入正整数(兼容ios)...
  17. 色彩nbsp;标准卡大全及配色方案
  18. 项目选题-口罩识别检测系统
  19. STI解读A:STI测量方法
  20. pg批量插入_postgresql大批量数据导入方法

热门文章

  1. 这样学Redis,才能技高一筹!
  2. 获取淘宝商品实时销量2022年最新算法
  3. ThinkPhp 表单提交数据
  4. js 继承的是什么?如何实现继承?
  5. 凤凰卫视、迪士尼、百度、圣戈班、万豪、汇丰等公司高管变动
  6. 微软的技术,直接颠覆了我对听书这件事的看法
  7. 2017.12退役贴
  8. 币须知道 |币安要做联盟计划,首期1000个名额,平台币运作模式 ,ADA创始人:华尔街准备“下一波监管”之后投资“数万亿美元”...
  9. OpenWrt 4G路由器DIY
  10. 【verbs】ibv_get_async_event()