前不久,因為工作需要更換了液晶屏,分辨率由原來的640*480換成了800*600。
當然首先更改了液晶屏驅動,修改了相應的參數。把開機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;就可以正常顯示了。