歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux2.6的LOGO制作與顯示

前不久,因為工作需要更換了液晶屏,分辨率由原來的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;就可以正常顯示了。

Copyright © Linux教程網 All Rights Reserved