Linux2.6的LOGO制作与显示
2013-03-08 17:04
459 查看
前不久,因为工作需要更换了液晶屏,分辨率由原来的640*480换成了800*600。
当然首先更改了液晶屏驱动,修改了相应的参数。把开机Logo也进行了更换,分辨率修改为800*600。
但是开机时,Logo无法显示,提示以下错误。
真是扯淡啊,查看源代码,该提示在drvers/video/console/Fbcon.c下,在此截取这段代码。
可以发现是因为logo_lines > vc->vc_bottom引起的。
其中logo_lines = DIV_ROUND_UP(logo_height, vc->vc_font.height); //(DIV_ROUND_UP是向上取整的意思)
而vc->vc_bottom代码读下来为vc->vc_bottom = info->var.yres/ vc->vc_font.height;
其关键就是vc->vc_font.height了,Linux下vc->vc_font.height默认为16,所以当液晶屏和Logo的分辨率都为800*600时,600/16无法整除,故取整logo_lines =38; vc->vc_bottom = 37;提示错误无法显示。
只要把logo的改小一下,改为592,则logo_lines = 592/16=37; vc->vc_bottom = 600/16=37;就可以正常显示了。
在移植linux2.6.24到YC2440的过程中,在logo显示部分遇到问题,终于解决,特此记录。
一、首先说明logo显示相关程序。
(1)在driver/video/console/fbcon.c文件中,函数fncon_init(),为虚拟设备结构体VC赋值,并调用本文件中的fbcon_prepare_logo()函数,为显示logo做准备。
(2)fbcon_prepare_logo(),调用了fb_prepare_logo()函数(此函数在driver/video/fbmem.c中)。
(3)fb_prepare_logo()中调用了fb_find_logo()函数(此函数在driver/video/logo/logo.c中),这个函数会根据配置文件找到相应的logo数据,这个数据就是logo文件夹下logo_xxx_xxx.ppm生成的,我的linux就是logo_linux_clut224.ppm。
(4)fb_prepare_logo()函数获取了照片信息后进行一次判断,看图片高度是否超过屏幕高度,否则,不显示。
(5)fbcon_prepare_logo()函数获取图片数据后,又进一步处理判断,用照片的高度除以字模高度后,于屏高度除以字模高度的值相比较,判断图片可否显示。若过大,则打印显示“fbcon_init:disable boot-logo(boot-logo bigger than screen)”。
二、然后,在以上的基础,说明我的问题,我的屏幕是800*600,移植同等大小图片后不显示,且打印fbcon_init:disable boot-logo(boot-logo bigger than screen)。
不明白为什么同样大小的图片不显示??
仔细阅读源码,定位于fbcon_prepare_logo()函数,发现计算屏幕显示所需行数是计算方法为:
logo_lines=(logo_height+vc->vc_font.height-1)/vc->vc_font.height;
而后来与之相比较的vc->vc_bottom=info->var.yres(屏幕高度)/vc_font.height;
不明白这是为什么??这样算法不公平的啊??
于是,更改为:
logo_lines=(logo_height)/vc->vc_font.height;
编译后,800*600图片显示成功!!
其关键就是vc->vc_font.height了,Linux下vc->vc_font.height默认为16,所以当液晶屏和Logo的分辨率都为800*600时,600/16无法整除,故取整logo_lines =38; vc->vc_bottom = 37;提示错误无法显示。
只要把logo的改小一下,改为592,则logo_lines = 592/16=37; vc->vc_bottom = 600/16=37;就可以正常显示了。
不知道这样有什么隐患。至少现在没发现……
三、最后,说明图片的制作,这个网上一堆资料……哈哈!
首先准备一幅自己喜欢的图片,然后将该图片保存成png格式,例如linuxlogo.png。在Linux下使用下面的命令:
# pngtopnm linuxlogo.png > linuxlogo.pnm
# pnmquant 224 linuxlogo.pnm > linuxlogo224.pnm
# pnmtoplainpnm linuxlogo224.pnm > linuxlogo224.ppm
mv linuxlogo224.ppm logo_linux_clut224.ppm
然后将logo_linux_clut224.ppm替换$WORKSPACE/linux-2.6.8.1/drivers/video/logo文件夹中的logo_linux_clut224.ppm(最好做好备份)
好,结束!O(∩_∩)O哈哈~!
当然首先更改了液晶屏驱动,修改了相应的参数。把开机Logo也进行了更换,分辨率修改为800*600。
但是开机时,Logo无法显示,提示以下错误。
fbcon_init: disable boot-logo (boot-logo bigger than screen).
真是扯淡啊,查看源代码,该提示在drvers/video/console/Fbcon.c下,在此截取这段代码。
static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, int cols, int rows, int new_cols, int new_rows) { /* Need to make room for the logo */ struct fbcon_ops *ops = info->fbcon_par; int cnt, erase = vc->vc_video_erase_char, step; unsigned short *save = NULL, *r, *q; int logo_height; if (info->flags & FBINFO_MODULE) { logo_shown = FBCON_LOGO_DONTSHOW; return; } /* * remove underline attribute from erase character * if black and white framebuffer. */ if (fb_get_color_depth(&info->var, &info->fix) == 1) erase &= ~0x400; logo_height = fb_prepare_logo(info, ops->rotate); //logo_lines在此赋值 logo_lines = DIV_ROUND_UP(logo_height, vc->vc_font.height); q = (unsigned short *) (vc->vc_origin + vc->vc_size_row * rows); step = logo_lines * cols; for (r = q - logo_lines * cols; r < q; r++) if (scr_readw(r) != vc->vc_video_erase_char) break; if (r != q && new_rows >= rows + logo_lines) { save = kmalloc(logo_lines * new_cols * 2, GFP_KERNEL); if (save) { int i = cols < new_cols ? cols : new_cols; scr_memsetw(save, erase, logo_lines * new_cols * 2); r = q - step; for (cnt = 0; cnt < logo_lines; cnt++, r += i) scr_memcpyw(save + cnt * new_cols, r, 2 * i); r = q; } } if (r == q) { /* We can scroll screen down */ r = q - step - cols; for (cnt = rows - logo_lines; cnt > 0; cnt--) { scr_memcpyw(r + step, r, vc->vc_size_row); r -= cols; } if (!save) { int lines; if (vc->vc_y + logo_lines >= rows) lines = rows - vc->vc_y - 1; else lines = logo_lines; vc->vc_y += lines; vc->vc_pos += lines * vc->vc_size_row; } } scr_memsetw((unsigned short *) vc->vc_origin, erase, vc->vc_size_row * logo_lines); if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) { fbcon_clear_margins(vc, 0); update_screen(vc); } if (save) { q = (unsigned short *) (vc->vc_origin + vc->vc_size_row * rows); scr_memcpyw(q, save, logo_lines * new_cols * 2); vc->vc_y += logo_lines; vc->vc_pos += logo_lines * vc->vc_size_row; kfree(save); } //错误提示在此 if (logo_lines > vc->vc_bottom) { logo_shown = FBCON_LOGO_CANSHOW; printk(KERN_INFO "fbcon_init: disable boot-logo (boot-logo bigger than screen).\n"); } else if (logo_shown != FBCON_LOGO_DONTSHOW) { logo_shown = FBCON_LOGO_DRAW; vc->vc_top = logo_lines; } }
可以发现是因为logo_lines > vc->vc_bottom引起的。
其中logo_lines = DIV_ROUND_UP(logo_height, vc->vc_font.height); //(DIV_ROUND_UP是向上取整的意思)
而vc->vc_bottom代码读下来为vc->vc_bottom = info->var.yres/ vc->vc_font.height;
其关键就是vc->vc_font.height了,Linux下vc->vc_font.height默认为16,所以当液晶屏和Logo的分辨率都为800*600时,600/16无法整除,故取整logo_lines =38; vc->vc_bottom = 37;提示错误无法显示。
只要把logo的改小一下,改为592,则logo_lines = 592/16=37; vc->vc_bottom = 600/16=37;就可以正常显示了。
在移植linux2.6.24到YC2440的过程中,在logo显示部分遇到问题,终于解决,特此记录。
一、首先说明logo显示相关程序。
(1)在driver/video/console/fbcon.c文件中,函数fncon_init(),为虚拟设备结构体VC赋值,并调用本文件中的fbcon_prepare_logo()函数,为显示logo做准备。
(2)fbcon_prepare_logo(),调用了fb_prepare_logo()函数(此函数在driver/video/fbmem.c中)。
(3)fb_prepare_logo()中调用了fb_find_logo()函数(此函数在driver/video/logo/logo.c中),这个函数会根据配置文件找到相应的logo数据,这个数据就是logo文件夹下logo_xxx_xxx.ppm生成的,我的linux就是logo_linux_clut224.ppm。
(4)fb_prepare_logo()函数获取了照片信息后进行一次判断,看图片高度是否超过屏幕高度,否则,不显示。
(5)fbcon_prepare_logo()函数获取图片数据后,又进一步处理判断,用照片的高度除以字模高度后,于屏高度除以字模高度的值相比较,判断图片可否显示。若过大,则打印显示“fbcon_init:disable boot-logo(boot-logo bigger than screen)”。
二、然后,在以上的基础,说明我的问题,我的屏幕是800*600,移植同等大小图片后不显示,且打印fbcon_init:disable boot-logo(boot-logo bigger than screen)。
不明白为什么同样大小的图片不显示??
仔细阅读源码,定位于fbcon_prepare_logo()函数,发现计算屏幕显示所需行数是计算方法为:
logo_lines=(logo_height+vc->vc_font.height-1)/vc->vc_font.height;
而后来与之相比较的vc->vc_bottom=info->var.yres(屏幕高度)/vc_font.height;
不明白这是为什么??这样算法不公平的啊??
于是,更改为:
logo_lines=(logo_height)/vc->vc_font.height;
编译后,800*600图片显示成功!!
其关键就是vc->vc_font.height了,Linux下vc->vc_font.height默认为16,所以当液晶屏和Logo的分辨率都为800*600时,600/16无法整除,故取整logo_lines =38; vc->vc_bottom = 37;提示错误无法显示。
只要把logo的改小一下,改为592,则logo_lines = 592/16=37; vc->vc_bottom = 600/16=37;就可以正常显示了。
不知道这样有什么隐患。至少现在没发现……
三、最后,说明图片的制作,这个网上一堆资料……哈哈!
首先准备一幅自己喜欢的图片,然后将该图片保存成png格式,例如linuxlogo.png。在Linux下使用下面的命令:
# pngtopnm linuxlogo.png > linuxlogo.pnm
# pnmquant 224 linuxlogo.pnm > linuxlogo224.pnm
# pnmtoplainpnm linuxlogo224.pnm > linuxlogo224.ppm
mv linuxlogo224.ppm logo_linux_clut224.ppm
然后将logo_linux_clut224.ppm替换$WORKSPACE/linux-2.6.8.1/drivers/video/logo文件夹中的logo_linux_clut224.ppm(最好做好备份)
好,结束!O(∩_∩)O哈哈~!
相关文章推荐
- Linux2.6的LOGO制作与显示
- Linux2.6的LOGO制作与显示
- Linux下制作logo并显示到开发板上 .
- Linux下制作logo并显示到开发板上
- linux logo制作及居中显示
- linux开机logo制作
- 制作Linux内核开机Logo
- Linux Logo制作
- mini2440 linux2.6 内核制作-nfs启动根文件系统
- 制作uboot LCD开机logo 及LCD字符显示错误的解决
- 嵌入式 linux 去掉启动时闪烁的光标 和制作启动LOGO
- mini2440 linux2.6 内核制作--initramfs 启动
- 高通平台android kernel 开机logo显示和传统linux一样
- 嵌入式 linux 去掉启动时闪烁的光标 和制作启动LOGO
- 修改linux内核开机logo并居中全屏显示
- Linux 开机Logo制作
- mini2440 linux2.6 内核制作-根文件系统制作
- linux开机logo制作
- linux开机logo制作
- linux下logo制作相关资料