闲来没事儿,就编译裁剪内核玩玩,这次玩的是PC上的了。在标准配置文件上作了一定到删减,然后加上了Framebuffer和主板JMI368的驱动,另外打上了控制台中文补丁。就开定了。现在内核版本v2.6.32-rc8(git来的,快到release了)。

相关补丁文件如下:

<li>控制台显示中文补丁:<pre lang="diff" colla="-">

diff –git a/drivers/char/selection.c b/drivers/char/selection.c

index f97b9e8..8810628 100644

— a/drivers/char/selection.c

+++ b/drivers/char/selection.c

@@ -59,8 +59,7 @@ static inline void highlight_pointer(const int where)

static u16

sel_pos(int n)

{

  • return inverse_translate(sel_cons, screen_glyph(sel_cons, n),

  •           use_unicode);
    
  • return screen_glyph(sel_cons, n);

}

/* remove the current selection highlight, if any,

@@ -295,6 +294,8 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t

        }

        obp = bp;

    }
  •   if (c > 0x80)
    
  •       i += 2;
    

    }

    sel_buffer_lth = bp - sel_buffer;

    return 0;

diff –git a/drivers/char/vt.c b/drivers/char/vt.c

index 0c80c68..1c0465d 100644

— a/drivers/char/vt.c

+++ b/drivers/char/vt.c

@@ -277,6 +277,19 @@ static inline unsigned short *screenpos(struct vc_data *vc, int offset, int view

return p;

}

+static inline unsigned short *screenpos_utf8(struct vc_data *vc, int offset, int viewed)

+{

  • unsigned short *p;

  • if (!viewed)

  •   p = (unsigned short *)(vc->vc_origin + offset + vc->vc_screenbuf_size);
    
  • else if (!vc->vc_sw->con_screen_pos)

  •   p = (unsigned short *)(vc->vc_visible_origin + offset + vc->vc_screenbuf_size);
    
  • else

  •   p = vc->vc_sw->con_screen_pos(vc, -offset - 1);
    
  • return p;

+}

static inline void scrolldelta(int lines)

{

scrollback_delta += lines;

@@ -303,6 +316,11 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)

scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);

scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char,

        vc->vc_size_row * nr);
  • d += (vc->vc_screenbuf_size » 1);

  • s += (vc->vc_screenbuf_size » 1);

  • scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);

  • scr_memsetw(d + (b - t - nr) * vc->vc_cols, 0,

  •       vc->vc_size_row * nr);
    

}

static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)

@@ -320,6 +338,9 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)

step = vc->vc_cols * nr;

scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row);

scr_memsetw(s, vc->vc_video_erase_char, 2 * step);
  • s += (vc->vc_screenbuf_size » 1);

  • scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row);

  • scr_memsetw(s, 0, 2 * step);

}

static void do_update_region(struct vc_data *vc, unsigned long start, int count)

@@ -487,6 +508,8 @@ void complement_pos(struct vc_data *vc, int offset)

static int old_offset = -1;

static unsigned short old;

static unsigned short oldx, oldy;
  • static unsigned short *p_ext = NULL;

  • static unsigned short old_ext = 0;

    WARN_CONSOLE_UNLOCKED();

@@ -494,7 +517,7 @@ void complement_pos(struct vc_data *vc, int offset)

    old_offset < vc->vc_screenbuf_size) {

    scr_writew(old, screenpos(vc, old_offset, 1));

    if (DO_UPDATE(vc))
  •       vc->vc_sw->con_putc(vc, old, oldy, oldx);
    
  •       vc->vc_sw->con_putc(vc, (old_ext << 16)|old, oldy, oldx);
    

    }

    old_offset = offset;

@@ -504,13 +527,15 @@ void complement_pos(struct vc_data *vc, int offset)

    unsigned short new;

    unsigned short *p;

    p = screenpos(vc, offset, 1);
  •   p_ext = screenpos_utf8(vc, offset, 1);
    
      old = scr_readw(p);
    
  •   old_ext = scr_readw(p_ext);
    
      new = old ^ vc->vc_complement_mask;
    
      scr_writew(new, p);
    
      if (DO_UPDATE(vc)) {
    
          oldx = (offset >> 1) % vc->vc_cols;
    
          oldy = (offset >> 1) / vc->vc_cols;
    
  •       vc->vc_sw->con_putc(vc, new, oldy, oldx);
    
  •       vc->vc_sw->con_putc(vc, (old_ext << 16)|new, oldy, oldx);
    
      }
    

    }

@@ -769,7 +794,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */

    visual_init(vc, currcons, 1);

    if (!*vc->vc_uni_pagedir_loc)

    con_set_default_unimap(vc);
  •   vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
    
  •   vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size * 2, GFP_KERNEL);
    
      if (!vc->vc_screenbuf) {
    
      kfree(vc);
    
      vc_cons[currcons].d = NULL;
    

@@ -846,7 +871,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,

if (new_cols == vc->vc_cols &amp;&amp; new_rows == vc->vc_rows)

    return 0;
  • newscreen = kmalloc(new_screen_size, GFP_USER);
  • newscreen = kmalloc(new_screen_size * 2, GFP_USER);

    if (!newscreen)

    return -ENOMEM;
    

@@ -901,15 +926,23 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,

while (old_origin < end) {

    scr_memcpyw((unsigned short *) new_origin,

            (unsigned short *) old_origin, rlth);
  •   if (rrem)
    
  •   scr_memcpyw((unsigned short *) new_origin + (new_screen_size >> 1),
    
  •           (unsigned short *) old_origin + (old_screen_size >> 1), rlth);
    
  •   if (rrem){
    
          scr_memsetw((void *)(new_origin + rlth),
    
                  vc->vc_video_erase_char, rrem);
    
  •       scr_memsetw((void *)(new_origin + rlth + (new_screen_size)),
    
  •               vc->vc_video_erase_char, rrem);
    
  •   }
    
      old_origin += old_row_size;
    
      new_origin += new_row_size;
    

    }

  • if (new_scr_end > new_origin)
  • if (new_scr_end > new_origin){

    scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
    
            new_scr_end - new_origin);
    
  •   scr_memsetw((void *)new_origin + (new_screen_size), vc->vc_video_erase_char,
    
  •           new_scr_end - new_origin);
    
  • }

    kfree(vc->vc_screenbuf);

    vc->vc_screenbuf = newscreen;

    vc->vc_screenbuf_size = new_screen_size;

@@ -2100,7 +2133,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co

}

#endif

  • int c, tc, ok, n = 0, draw_x = -1;
  • int c, tc, tc_1, ok, n = 0, draw_x = -1;

    unsigned int currcons;

    unsigned long draw_from = 0, draw_to = 0;

    struct vc_data *vc;

@@ -2112,6 +2145,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co

u16 himask, charmask;

const unsigned char *orig_buf = NULL;

int orig_count;
  • int is_utf8 = 0;

    if (in_interrupt())

    return count;
    

@@ -2154,6 +2188,8 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co

    rescan = 0;

    inverse = 0;

    width = 1;
  •   vc->vc_utf = 1;
    
  •   vc->vc_disp_ctrl = 0;
    
    
    
      /* Do no translation at all in control states */
    
      if (vc->vc_state != ESnormal) {
    

@@ -2195,6 +2231,7 @@ rescan_last_byte:

            vc->vc_utf_count = 0;

            c = 0xfffd;

        } else if (c > 0x7f) {
  •           is_utf8 = 1;
    
              /* First byte of a multibyte sequence received */
    
              vc->vc_npar = 0;
    
              if ((c &amp; 0xe0) == 0xc0) {
    

@@ -2220,8 +2257,9 @@ rescan_last_byte:

            /* Still need some bytes */

            continue;

            }
  •       } else {
    
  •           is_utf8 = 0;
    
          }
    
  •       /* Nothing to do if an ASCII byte was received */
    
          }
    
          /* End of UTF-8 decoding. */
    
          /* c is the received character, or U+FFFD for invalid sequences. */
    

@@ -2299,39 +2337,123 @@ rescan_last_byte:

        }



        while (1) {
  •           if (vc->vc_need_wrap || vc->vc_decim)
    
  •               FLUSH
    
  •           if (vc->vc_need_wrap) {
    
  •               cr(vc);
    
  •               lf(vc);
    
  •           }
    
  •           if (vc->vc_decim)
    
  •               insert_char(vc, 1);
    
  •           scr_writew(himask ?
    
  •                    ((vc_attr << 8) &amp; ~himask) + ((tc &amp; 0x100) ? himask : 0) + (tc &amp; 0xff) :
    
  •                    (vc_attr << 8) + tc,
    
  •                  (u16 *) vc->vc_pos);
    
  •           if (DO_UPDATE(vc) &amp;&amp; draw_x < 0) {
    
  •               draw_x = vc->vc_x;
    
  •               draw_from = vc->vc_pos;
    
  •           }
    
  •           if (vc->vc_x == vc->vc_cols - 1) {
    
  •               vc->vc_need_wrap = vc->vc_decawm;
    
  •               draw_to = vc->vc_pos + 2;
    
  •           } else {
    
  •               vc->vc_x++;
    
  •               draw_to = (vc->vc_pos += 2);
    
  •           }
    
  •           if(is_utf8 == 0) {
    
  •               if (vc->vc_need_wrap || vc->vc_decim)
    
  •                   FLUSH
    
  •               if (vc->vc_need_wrap) {
    
  •                   cr(vc);
    
  •                   lf(vc);
    
  •               }
    
  •               if (vc->vc_decim)
    
  •                   insert_char(vc, 1);
    
  •               scr_writew(himask ?
    
  •                        ((vc_attr << 8) &amp; ~himask) + ((tc &amp; 0x100) ? himask : 0) + (tc &amp; 0xff) :
    
  •                        (vc_attr << 8) + tc,
    
  •                      (u16 *) vc->vc_pos);
    
  •               scr_writew(0, (u16 *) vc->vc_pos + (vc->vc_screenbuf_size >> 1));
    
  •               if (DO_UPDATE(vc) &amp;&amp; draw_x < 0) {
    
  •                   draw_x = vc->vc_x;
    
  •                   draw_from = vc->vc_pos;
    
  •               }
    
  •               if (vc->vc_x == vc->vc_cols - 1) {
    
  •                   vc->vc_need_wrap = vc->vc_decawm;
    
  •                   draw_to = vc->vc_pos + 2;
    
  •               } else {
    
  •                   vc->vc_x++;
    
  •                   draw_to = (vc->vc_pos += 2);
    
  •               }
    
  •               if (!--width) break;
    
  •               tc = conv_uni_to_pc(vc, &#39; &#39;); /* A space is printed in the second column */
    
  •               if (tc < 0) tc = &#39; &#39;;
    
  •               notify_write(vc, c);
    
  •               if (inverse) {
    
  •                   FLUSH
    
  •               }
    
  •           if (!--width) break;
    
  •           } else {
    
  •               tc = 0xff;
    
  •               tc_1 = 0xfe;
    
  •               if (vc->vc_need_wrap || vc->vc_decim)
    
  •                   FLUSH
    
  •               if (vc->vc_need_wrap) {
    
  •                   cr(vc);
    
  •                   lf(vc);
    
  •               }
    
  •               if (vc->vc_decim)
    
  •                   insert_char(vc, 1);
    
  •               scr_writew(himask ?
    
  •                        ((vc_attr << 8) &amp; ~himask) + ((tc &amp; 0x100) ? himask : 0) + (tc &amp; 0xff) :
    
  •                        (vc_attr << 8) + tc,
    
  •                      (u16 *) vc->vc_pos);
    
  •               scr_writew(c,
    
  •                      (u16 *) vc->vc_pos + (vc->vc_screenbuf_size >> 1));
    
  •               if (DO_UPDATE(vc) &amp;&amp; draw_x < 0) {
    
  •                   draw_x = vc->vc_x;
    
  •                   draw_from = vc->vc_pos;
    
  •               }
    
  •               if (vc->vc_x == vc->vc_cols - 1) {
    
  •                   vc->vc_need_wrap = vc->vc_decawm;
    
  •                   draw_to = vc->vc_pos + 2;
    
  •               } else {
    
  •                   vc->vc_x++;
    
  •                   draw_to = (vc->vc_pos += 2);
    
  •               }
    
  •               if (!--width) break;
    
  •               tc = conv_uni_to_pc(vc, &#39; &#39;); /* A space is printed in the second column */
    
  •               if (tc < 0) tc = &#39; &#39;;
    
  •               notify_write(vc, c);
    
  •               if (inverse) {
    
  •                   FLUSH
    
  •               }
    
  •               if (vc->vc_need_wrap || vc->vc_decim)
    
  •                   FLUSH
    
  •               if (vc->vc_need_wrap) {
    
  •                   cr(vc);
    
  •                   lf(vc);
    
  •               }
    
  •               if (vc->vc_decim)
    
  •                   insert_char(vc, 1);
    
  •               scr_writew(himask ?
    
  •                        ((vc_attr << 8) &amp; ~himask) + ((tc_1 &amp; 0x100) ? himask : 0) + (tc_1 &amp; 0xff) :
    
  •                        (vc_attr << 8) + tc_1,
    
  •                      (u16 *) vc->vc_pos);
    
  •               scr_writew(c,
    
  •                      (u16 *) vc->vc_pos + (vc->vc_screenbuf_size >> 1));
    
  •               if (DO_UPDATE(vc) &amp;&amp; draw_x < 0) {
    
  •                   draw_x = vc->vc_x;
    
  •                   draw_from = vc->vc_pos;
    
  •               }
    
  •               if (vc->vc_x == vc->vc_cols - 1) {
    
  •                   vc->vc_need_wrap = vc->vc_decawm;
    
  •                   draw_to = vc->vc_pos + 2;
    
  •               } else {
    
  •                   vc->vc_x++;
    
  •                   draw_to = (vc->vc_pos += 2);
    
  •               }
    
  •               if (!--width) break;
    
  •               tc = conv_uni_to_pc(vc, &#39; &#39;); /* A space is printed in the second column */
    
  •               if (tc < 0) tc = &#39; &#39;;
    
  •           tc = conv_uni_to_pc(vc, &#39; &#39;); /* A space is printed in the second column */
    
  •           if (tc < 0) tc = &#39; &#39;;
    
  •       }
    
  •       notify_write(vc, c);
    
  •               notify_write(vc, c);
    
  •       if (inverse) {
    
  •           FLUSH
    
  •               if (inverse) {
    
  •                   FLUSH
    
  •               }
    
  •           }
    
          }
    
    
    
          if (rescan) {
    

@@ -2871,7 +2993,7 @@ static int __init con_init(void)

    vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);

    INIT_WORK(&amp;vc_cons[currcons].SAK_work, vc_SAK);

    visual_init(vc, currcons, 1);
  •   vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
    
  •   vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size * 2, GFP_NOWAIT);
    
      vc_init(vc, vc->vc_rows, vc->vc_cols,
    
          currcons || !vc->vc_sw->con_save_screen);
    

    }

@@ -4022,9 +4144,15 @@ u16 screen_glyph(struct vc_data *vc, int offset)

u16 w = scr_readw(screenpos(vc, offset, 1));

u16 c = w &amp; 0xff;
  • if (w & vc->vc_hi_font_mask)

  •   c |= 0x100;
    
  • return c;

  • u16 c_utf8 = scr_readw(screenpos_utf8(vc, offset, 1));

  • if ( (c == 0xff || c == 0xfe) && c_utf8 != 0){

  •   return c_utf8;
    
  • }else{

  •   if (w &amp; vc->vc_hi_font_mask)
    
  •       c |= 0x100;
    
  •   return c;
    
  • }

}

EXPORT_SYMBOL_GPL(screen_glyph);

diff –git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c

index 6b7c8fb..9f041a9 100644

— a/drivers/video/console/bitblit.c

+++ b/drivers/video/console/bitblit.c

@@ -10,6 +10,8 @@

  • more details.

*/

+#include <linux/font.h>

+#include “fonts_utf8.h”

#include <linux/module.h>

#include <linux/string.h>

#include <linux/fb.h>

@@ -42,6 +44,25 @@ static inline void update_attr(u8 *dst, u8 *src, int attribute,

}

}

+static int fbcon_softback_size = 32768;

+extern int fbcon_is_softback(const unsigned short *str);

+u16 utf8_pos(struct vc_data *vc, const unsigned short *utf8)

+{

  • unsigned long p = (long)utf8;

  • if (p >= vc->vc_origin && p < vc->vc_scr_end) {

  •   return scr_readw((unsigned short *)(p + vc->vc_screenbuf_size));
    
  • } else if (vc->vc_num == fg_console && fbcon_is_softback(utf8)){

  •   return scr_readw((unsigned short *)(p + fbcon_softback_size));
    
  • } else {

  •   u16 extra_c;
    
  •   int c = *(int*)utf8;
    
  •   extra_c = (c >> 16 ) &amp; 0x0000ffff;
    
  •   return extra_c;
    
  • }

+}

static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,

          int sx, int dy, int dx, int height, int width)

{

@@ -82,14 +103,24 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,

u32 idx = vc->vc_font.width >> 3;

u8 *src;
  • int utf8_c = 0;

    while (cnt–) {

  •   src = vc->vc_font.data + (scr_readw(s++)&amp;
    
  •                 charmask)*cellsize;
    
  •   utf8_c = utf8_pos(vc, s);
    
  •   if(((scr_readw(s) &amp; charmask) == 0xff || (scr_readw(s) &amp; charmask) == 0xfe ) &amp;&amp;  utf8_c != 0){
    
  •       if((scr_readw(s) &amp; charmask) == 0xff){
    
  •           src = font_utf8 + (utf8_c * 32);
    
  •       }else{
    
  •           src = font_utf8 + (utf8_c * 32 + 16);
    
  •       }
    
  •   }else{
    
  •       src = vc->vc_font.data + (scr_readw(s) &amp;
    
  •                     charmask) * cellsize;
    
  •   }
    
      if (attr) {
    
          update_attr(buf, src, attr, vc);
    
          src = buf;
    
      }
    
  •   s++;
    
    
    
      if (likely(idx == 1))
    
          __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
    

@@ -117,14 +148,24 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,

u32 idx = vc->vc_font.width >> 3;

u8 *src;
  • int utf8_c = 0;

    while (cnt–) {

  •   src = vc->vc_font.data + (scr_readw(s++)&amp;
    
  •                 charmask)*cellsize;
    
  •   utf8_c = utf8_pos(vc, s);
    
  •   if(((scr_readw(s) &amp; charmask) == 0xff || (scr_readw(s) &amp; charmask) == 0xfe ) &amp;&amp; utf8_c != 0){
    
  •       if((scr_readw(s) &amp; charmask) == 0xff){
    
  •           src = font_utf8 + (utf8_c * 32);
    
  •       }else{
    
  •           src = font_utf8 + (utf8_c * 32 + 16);
    
  •       }
    
  •   }else{
    
  •       src = vc->vc_font.data + (scr_readw(s) &amp;
    
  •                     charmask) * cellsize;
    
  •   }
    
      if (attr) {
    
          update_attr(buf, src, attr, vc);
    
          src = buf;
    
      }
    
  •   s++;
    
    
    
      fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
    
                  image->height, shift_high,
    

@@ -240,6 +281,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,

struct fbcon_ops *ops = info->fbcon_par;

unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;

int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
  • int c_extra;

    int y = real_y(ops->p, vc->vc_y);

    int attribute, use_sw = (vc->vc_cursor_type & 0x10);

    int err = 1;

@@ -257,8 +299,17 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,

}



c = scr_readw((u16 *) vc->vc_pos);
  • c_extra = utf8_pos(vc, (u16 *) vc->vc_pos);

    attribute = get_attribute(info, c);

  • src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
  • if(((c&charmask) == 0xff || (c & charmask) == 0xfe) && c_extra != 0){

  •   if((c &amp; charmask) == 0xff){
    
  •       src = (char *) (font_utf8 + (c_extra * 32));
    
  •   }else{
    
  •       src = (char *) (font_utf8 + (c_extra * 32 + 16));
    
  •   }
    
  • }else{

  •   src = vc->vc_font.data + ((c &amp; charmask) * (w * vc->vc_font.height));
    
  • }

    if (ops->cursor_state.image.data != src ||

    ops->cursor_reset) {
    

diff –git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c

index 3681c6a..07f8636 100644

— a/drivers/video/console/fbcon.c

+++ b/drivers/video/console/fbcon.c

@@ -196,6 +196,14 @@ static void fbcon_start(void);

static void fbcon_exit(void);

static struct device *fbcon_device;

+int fbcon_is_softback(const unsigned short *str)

+{

  • unsigned long p = (long)str;

  • if(p >= softback_buf && p <softback_end)

  •   return 1;
    
  • return 0;

+}

#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION

static inline void fbcon_set_rotation(struct fb_info *info)

{

@@ -964,7 +972,7 @@ static const char *fbcon_startup(void)

        if (!softback_buf) {

            softback_buf =

                (unsigned long)
  •               kmalloc(fbcon_softback_size,
    
  •               kmalloc(fbcon_softback_size * 2,
    
                      GFP_KERNEL);
    
              if (!softback_buf) {
    
                  fbcon_softback_size = 0;
    

@@ -1266,10 +1274,7 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,

static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)

{

  • unsigned short chr;

  • scr_writew(c, &chr);

  • fbcon_putcs(vc, &chr, 1, ypos, xpos);

  • fbcon_putcs(vc, (unsigned short *)&c, 1, ypos, xpos);

}

static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)

@@ -1520,6 +1525,7 @@ static inline void ypan_down_redraw(struct vc_data *vc, int t, int count)

static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,

              long delta)

{

  • u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;

    int count = vc->vc_rows;

    unsigned short *d, *s;

    unsigned long n;

@@ -1582,7 +1588,9 @@ static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,

                start = s;

            }

        }
  •       if (c == scr_readw(d)) {
    
  •       if( ((scr_readw(s) &amp; charmask) == 0xff || (scr_readw(s) &amp; charmask) == 0xfe) &amp;&amp; scr_readw(s + (vc->vc_screenbuf_size >> 1)) != 0){
    
  •       }else{
    
  •           if (c == scr_readw(d)) {
    
              if (s > start) {
    
                  fbcon_putcs(vc, start, s - start,
    
                          line, x);
    

@@ -1593,6 +1601,7 @@ static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,

                start++;

            }

        }
  •       }
    
          s++;
    
          d++;
    
      } while (s < le);
    

@@ -1675,6 +1684,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,

        }



        scr_writew(c, d);
  •       scr_writew(scr_readw(s + (vc->vc_screenbuf_size >> 1)), d + (vc->vc_screenbuf_size >> 1));
    
          console_conditional_schedule();
    
          s++;
    
          d++;
    

@@ -1697,6 +1707,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,

static void fbcon_redraw(struct vc_data *vc, struct display *p,

         int line, int count, int offset)

{

  • u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;

    unsigned short *d = (unsigned short *)

    (vc->vc_origin + vc->vc_size_row * line);
    

    unsigned short *s = d + offset;

@@ -1719,18 +1730,22 @@ static void fbcon_redraw(struct vc_data *vc, struct display *p,

                start = s;

            }

        }
  •       if (c == scr_readw(d)) {
    
  •           if (s > start) {
    
  •               fbcon_putcs(vc, start, s - start,
    
  •                        line, x);
    
  •               x += s - start + 1;
    
  •               start = s + 1;
    
  •           } else {
    
  •               x++;
    
  •               start++;
    
  •       if( ((scr_readw(s) &amp; charmask) == 0xff || (scr_readw(s) &amp; charmask) == 0xfe) &amp;&amp; scr_readw(s + (vc->vc_screenbuf_size >> 1)) != 0){
    
  •       }else{
    
  •           if (c == scr_readw(d)) {
    
  •               if (s > start) {
    
  •                   fbcon_putcs(vc, start, s - start,
    
  •                            line, x);
    
  •                   x += s - start + 1;
    
  •                   start = s + 1;
    
  •               } else {
    
  •                   x++;
    
  •                   start++;
    
  •               }
    
              }
    
          }
    
          scr_writew(c, d);
    
  •       scr_writew(scr_readw(s + (vc->vc_screenbuf_size >> 1)), d + (vc->vc_screenbuf_size >> 1));
    
          console_conditional_schedule();
    
          s++;
    
          d++;
    

@@ -1760,6 +1775,7 @@ static inline void fbcon_softback_note(struct vc_data *vc, int t,

while (count) {

    scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row);
  •   scr_memcpyw((u16 *) softback_in + (fbcon_softback_size >> 1), p + (vc->vc_screenbuf_size >> 1), vc->vc_size_row);
    
      count--;
    
      p = advance_row(p, 1);
    
      softback_in += vc->vc_size_row;
    

@@ -2645,7 +2661,20 @@ static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)

{

unsigned long p;

int line;
  • if (offset < 0) {

  •   offset = -offset - 1;
    
  •   if (vc->vc_num != fg_console || !softback_lines)
    
  •       return (u16 *)(vc->vc_origin + offset + (vc->vc_screenbuf_size));
    
  •   line = offset / vc->vc_size_row;
    
  •   if (line >= softback_lines)
    
  •       return (u16 *) (vc->vc_origin + offset - softback_lines * vc->vc_size_row + (vc->vc_screenbuf_size));
    
  •   p = softback_curr + offset;
    
  •   if (p >= softback_end)
    
  •       p += softback_buf - softback_end;
    
  •   return (u16 *) (p + (fbcon_softback_size));
    
  • }

  • if (vc->vc_num != fg_console || !softback_lines)

      return (u16 *) (vc->vc_origin + offset);
    

    line = offset / vc->vc_size_row;

@@ -2753,6 +2782,9 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)

                q -= vc->vc_size_row;

                scr_memcpyw((u16 *) q, (u16 *) p,

                        vc->vc_size_row);
  •               scr_memcpyw((u16 *) (q + (vc->vc_screenbuf_size >> 1)), (u16 *) (p + (fbcon_softback_size >> 1)),
    
  •                       vc->vc_size_row);
    
  •           }
    
              softback_in = softback_curr = p;
    
              update_region(vc, vc->vc_origin,
    

diff –git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c

index bdf913e..d342c1d 100644

— a/drivers/video/console/fbcon_ccw.c

+++ b/drivers/video/console/fbcon_ccw.c

@@ -16,6 +16,9 @@

#include <asm/types.h>

#include “fbcon.h”

#include “fbcon_rotate.h”

+#include “fonts_utf8.h”

+extern u16 utf8_pos(struct vc_data *vc, const unsigned short *utf8);

/*

  • Rotation 270 degrees

@@ -104,13 +107,28 @@ static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,

u32 idx = (vc->vc_font.height + 7) >> 3;

u8 *src;
  • int utf8_c = 0;

    while (cnt–) {

  •   src = ops->fontbuffer + (scr_readw(s--) &amp; charmask)*cellsize;
    
  •   utf8_c = utf8_pos(vc, s);
    
  •   if(((scr_readw(s) &amp; charmask) == 0xff || (scr_readw(s) &amp; charmask) == 0xfe ) &amp;&amp;  utf8_c != 0){
    
  •       char dst[16];
    
  •       if((scr_readw(s) &amp; charmask) == 0xff){
    
  •           src = font_utf8 + (utf8_c * 32);
    
  •       }else{
    
  •           src = font_utf8 + (utf8_c * 32 + 16);
    
  •       }
    
  •       memset(dst, 0, 16);
    
  •       rotate_ccw(src, dst, vc->vc_font.width,
    
  •             vc->vc_font.height);
    
  •       src = dst;
    
  •   }else{
    
  •       src = ops->fontbuffer + (scr_readw(s) &amp; charmask)*cellsize;
    
  •   }
    
      if (attr) {
    
          ccw_update_attr(buf, src, attr, vc);
    
          src = buf;
    
      }
    
  •   s--;
    
    
    
      if (likely(idx == 1))
    
          __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
    

@@ -224,6 +242,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,

struct fb_cursor cursor;

struct fbcon_ops *ops = info->fbcon_par;

unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
  • int c_extra;

    int w = (vc->vc_font.height + 7) » 3, c;

    int y = real_y(ops->p, vc->vc_y);

    int attribute, use_sw = (vc->vc_cursor_type & 0x10);

@@ -246,8 +265,22 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,

}



c = scr_readw((u16 *) vc->vc_pos);
  • c_extra = utf8_pos(vc, (u16 *) vc->vc_pos);

    attribute = get_attribute(info, c);

  • src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
  • if(((c&charmask) == 0xff || (c & charmask) == 0xfe) && c_extra != 0){

  •   char dst[16];
    
  •   if((c &amp; charmask) == 0xff){
    
  •       src = font_utf8 + (c_extra * 32);
    
  •   }else{
    
  •       src = font_utf8 + (c_extra * 32 + 16);
    
  •   }
    
  •   memset(dst, 0, 16);
    
  •   rotate_ccw(src, dst, vc->vc_font.width,
    
  •         vc->vc_font.height);
    
  •   src = dst;
    
  • }else{

  •   src = ops->fontbuffer + ((c &amp; charmask) * (w * vc->vc_font.width));
    
  • }

    if (ops->cursor_state.image.data != src ||

    ops->cursor_reset) {
    

diff –git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c

index a6819b9..904f4e0 100644

— a/drivers/video/console/fbcon_cw.c

+++ b/drivers/video/console/fbcon_cw.c

@@ -16,6 +16,9 @@

#include <asm/types.h>

#include “fbcon.h”

#include “fbcon_rotate.h”

+#include “fonts_utf8.h”

+extern u16 utf8_pos(struct vc_data *vc, const unsigned short *utf8);

/*

  • Rotation 90 degrees

@@ -90,13 +93,28 @@ static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,

u32 idx = (vc->vc_font.height + 7) >> 3;

u8 *src;
  • int utf8_c = 0;

    while (cnt–) {

  •   src = ops->fontbuffer + (scr_readw(s++) &amp; charmask)*cellsize;
    
  •   utf8_c = utf8_pos(vc, s);
    
  •   if(((scr_readw(s) &amp; charmask) == 0xff || (scr_readw(s) &amp; charmask) == 0xfe ) &amp;&amp;  utf8_c != 0){
    
  •       char dst[16];
    
  •       if((scr_readw(s) &amp; charmask) == 0xff){
    
  •           src = font_utf8 + (utf8_c * 32);
    
  •       }else{
    
  •           src = font_utf8 + (utf8_c * 32 + 16);
    
  •       }
    
  •       memset(dst, 0, 16);
    
  •       rotate_cw(src, dst, vc->vc_font.width,
    
  •             vc->vc_font.height);
    
  •       src = dst;
    
  •   }else{
    
  •       src = ops->fontbuffer + (scr_readw(s) &amp; charmask)*cellsize;
    
  •   }
    
      if (attr) {
    
          cw_update_attr(buf, src, attr, vc);
    
          src = buf;
    
      }
    
  •   s++;
    
    
    
      if (likely(idx == 1))
    
          __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
    

@@ -208,6 +226,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,

struct fb_cursor cursor;

struct fbcon_ops *ops = info->fbcon_par;

unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
  • int c_extra;

    int w = (vc->vc_font.height + 7) » 3, c;

    int y = real_y(ops->p, vc->vc_y);

    int attribute, use_sw = (vc->vc_cursor_type & 0x10);

@@ -230,8 +249,22 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,

}



c = scr_readw((u16 *) vc->vc_pos);
  • c_extra = utf8_pos(vc, (u16 *) vc->vc_pos);

    attribute = get_attribute(info, c);

  • src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
  • if(((c&charmask) == 0xff || (c & charmask) == 0xfe) && c_extra != 0){

  •   char dst[16];
    
  •   if((c &amp; charmask) == 0xff){
    
  •       src = font_utf8 + (c_extra * 32);
    
  •   }else{
    
  •       src = font_utf8 + (c_extra * 32 + 16);
    
  •   }
    
  •   memset(dst, 0, 16);
    
  •   rotate_cw(src, dst, vc->vc_font.width,
    
  •         vc->vc_font.height);
    
  •   src = dst;
    
  • }else{

  •   src = ops->fontbuffer + ((c &amp; charmask) * (w * vc->vc_font.width));
    
  • }

    if (ops->cursor_state.image.data != src ||

    ops->cursor_reset) {
    

diff –git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c

index d9b5d6e..e529594 100644

— a/drivers/video/console/fbcon_ud.c

+++ b/drivers/video/console/fbcon_ud.c

@@ -17,6 +17,10 @@

#include “fbcon.h”

#include “fbcon_rotate.h”

+#include “fonts_utf8.h”

+extern u16 utf8_pos(struct vc_data *vc, const unsigned short *utf8);

/*

  • Rotation 180 degrees

*/

@@ -91,13 +95,29 @@ static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,

u32 idx = vc->vc_font.width >> 3;

u8 *src;
  • int utf8_c = 0;

    while (cnt–) {

  •   src = ops->fontbuffer + (scr_readw(s--) &amp; charmask)*cellsize;
    
  •   utf8_c = utf8_pos(vc, s);
    
  •   if(((scr_readw(s) &amp; charmask) == 0xff || (scr_readw(s) &amp; charmask) == 0xfe ) &amp;&amp;  utf8_c != 0){
    
  •       char dst[16];
    
  •       if((scr_readw(s) &amp; charmask) == 0xff){
    
  •           src = font_utf8 + (utf8_c * 32);
    
  •       }else{
    
  •           src = font_utf8 + (utf8_c * 32 + 16);
    
  •       }
    
  •       memset(dst, 0, 16);
    
  •       rotate_ud(src, dst, vc->vc_font.width,
    
  •             vc->vc_font.height);
    
  •       src = dst;
    
  •   }else{
    
  •       src = ops->fontbuffer + (scr_readw(s) &amp; charmask)*cellsize;
    
  •   }
    
    
    
      if (attr) {
    
          ud_update_attr(buf, src, attr, vc);
    
          src = buf;
    
      }
    
  •   s--;
    
    
    
      if (likely(idx == 1))
    
          __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
    

@@ -126,13 +146,29 @@ static inline void ud_putcs_unaligned(struct vc_data *vc,

u32 idx = vc->vc_font.width >> 3;

u8 *src;
  • int utf8_c = 0;

    while (cnt–) {

  •   src = ops->fontbuffer + (scr_readw(s--) &amp; charmask)*cellsize;
    
  •   utf8_c = utf8_pos(vc, s);
    
  •   if(((scr_readw(s) &amp; charmask) == 0xff || (scr_readw(s) &amp; charmask) == 0xfe ) &amp;&amp;  utf8_c != 0){
    
  •       char dst[16];
    
  •       if((scr_readw(s) &amp; charmask) == 0xff){
    
  •           src = font_utf8 + (utf8_c * 32);
    
  •       }else{
    
  •           src = font_utf8 + (utf8_c * 32 + 16);
    
  •       }
    
  •       memset(dst, 0, 16);
    
  •       rotate_ud(src, dst, vc->vc_font.width,
    
  •             vc->vc_font.height);
    
  •       src = dst;
    
  •   }else{
    
  •       src = ops->fontbuffer + (scr_readw(s) &amp; charmask)*cellsize;
    
  •   }
    
    
    
      if (attr) {
    
          ud_update_attr(buf, src, attr, vc);
    
          src = buf;
    
      }
    
  •   s--;
    
    
    
      fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
    
                  image->height, shift_high,
    

@@ -254,6 +290,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,

struct fb_cursor cursor;

struct fbcon_ops *ops = info->fbcon_par;

unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
  • int c_extra;

    int w = (vc->vc_font.width + 7) » 3, c;

    int y = real_y(ops->p, vc->vc_y);

    int attribute, use_sw = (vc->vc_cursor_type & 0x10);

@@ -277,8 +314,22 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,

}



c = scr_readw((u16 *) vc->vc_pos);
  • c_extra = utf8_pos(vc, (u16 *) vc->vc_pos);

    attribute = get_attribute(info, c);

  • src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
  • if(((c&charmask) == 0xff || (c & charmask) == 0xfe) && c_extra != 0){

  •   char dst[16];
    
  •   if((c &amp; charmask) == 0xff){
    
  •       src = font_utf8 + (c_extra * 32);
    
  •   }else{
    
  •       src = font_utf8 + (c_extra * 32 + 16);
    
  •   }
    
  •   memset(dst, 0, 16);
    
  •   rotate_ud(src, dst, vc->vc_font.width,
    
  •         vc->vc_font.height);
    
  •   src = dst;
    
  • }else{

  •   src = ops->fontbuffer + ((c &amp; charmask) * (w * vc->vc_font.height));
    
  • }

    if (ops->cursor_state.image.data != src ||

    ops->cursor_reset) {
    

<li>内核.config文件