ºìÁªLinuxÃÅ»§
Linux°ïÖú

FrameBufferµÄÔ­Àí

·¢²¼Ê±¼ä:2007-11-30 09:32:02À´Ô´:ºìÁª×÷Õß:cights
FrameBuffer ÊdzöÏÖÔÚ 2.2.xx Äں˵±ÖеÄÒ»ÖÖÇý¶¯³ÌÐò½Ó¿Ú¡£

LinuxÊǹ¤×÷ÔÚ±£»¤Ä£Ê½Ï£¬ËùÒÔÓû§Ì¬½ø³ÌÊÇÎÞ·¨ÏóDOSÄÇÑùʹÓÃÏÔ¿¨BIOSÀïÌṩµÄÖжϵ÷ÓÃÀ´ÊµÏÖÖ±½ÓдÆÁ£¬Linux³éÏó³öFrameBufferÕâ¸öÉ豸À´¹©Óû§Ì¬½ø³ÌʵÏÖÖ±½ÓдÆÁ¡£Framebuffer»úÖÆÄ£·ÂÏÔ¿¨µÄ¹¦ÄÜ£¬½«ÏÔ¿¨Ó²¼þ½á¹¹³éÏóµô£¬¿ÉÒÔͨ¹ýFramebufferµÄ¶Áдֱ½Ó¶ÔÏÔ´æ½øÐвÙ×÷¡£Óû§¿ÉÒÔ½«Framebuffer¿´³ÉÊÇÏÔʾÄÚ´æµÄÒ»¸öÓ³Ïñ£¬½«ÆäÓ³Éäµ½½ø³ÌµØÖ·¿Õ¼äÖ®ºó£¬¾Í¿ÉÒÔÖ±½Ó½øÐжÁд²Ù×÷£¬¶øд²Ù×÷¿ÉÒÔÁ¢¼´·´Ó¦ÔÚÆÁÄ»ÉÏ¡£ÕâÖÖ²Ù×÷ÊdzéÏóµÄ£¬Í³Ò»µÄ¡£Óû§²»±Ø¹ØÐÄÎïÀíÏÔ´æµÄλÖᢻ»Ò³»úÖƵȵȾßÌåϸ½Ú¡£ÕâЩ¶¼ÊÇÓÉFramebufferÉ豸Çý¶¯À´Íê³ÉµÄ¡£

µ«Framebuffer±¾Éí²»¾ß±¸ÈκÎÔËËãÊý¾ÝµÄÄÜÁ¦,¾ÍÖ»ºÃ±ÈÊÇÒ»¸öÔÝʱ´æ·ÅË®µÄË®³Ø.CPU½«ÔËËãºóµÄ½á¹û·Åµ½Õâ¸öË®³Ø,Ë®³ØÔÙ½«½á¹ûÁ÷µ½ÏÔʾÆ÷.Öм䲻»á¶ÔÊý¾Ý×ö´¦Àí. Ó¦ÓóÌÐòÒ²¿ÉÒÔÖ±½Ó¶ÁдÕâ¸öË®³ØµÄÄÚÈÝ.ÔÚÕâÖÖ»úÖÆÏ£¬¾¡¹ÜFramebufferÐèÒªÕæÕýµÄÏÔ¿¨Çý¶¯µÄÖ§³Ö£¬µ«ËùÓÐÏÔʾÈÎÎñ¶¼ÓÐCPUÍê³É,Òò´ËCPU¸ºµ£ºÜÖØ.

framebufferµÄÉ豸ÎļþÒ»°ãÊÇ /dev/fb0¡¢/dev/fb1 µÈµÈ¡£

¿ÉÒÔÓÃÃüÁî: #dd if=/dev/zero of=/dev/fb Çå¿ÕÆÁÄ».

Èç¹ûÏÔʾģʽÊÇ 1024x768-8 λɫ£¬ÓÃÃüÁ$ dd if=/dev/zero of=/dev/fb0 bs=1024 count=768 Çå¿ÕÆÁÄ»

ÓÃÃüÁî: #dd if=/dev/fb of=fbfile ¿ÉÒÔ½«fbÖеÄÄÚÈݱ£´æÏÂÀ´£»

¿ÉÒÔÖØÐÂд»ØÆÁÄ»: #dd if=fbfile of=/dev/fb

ÔÚʹÓÃFramebufferʱ£¬LinuxÊǽ«ÏÔ¿¨ÖÃÓÚͼÐÎģʽϵģ®

ÔÚÓ¦ÓóÌÐòÖУ¬Ò»°ãͨ¹ý½« FrameBuffer É豸ӳÉäµ½½ø³ÌµØÖ·¿Õ¼äµÄ·½Ê½Ê¹Ó㬱ÈÈçÏÂÃæµÄ³ÌÐò¾Í´ò¿ª /dev/fb0 É豸£¬²¢Í¨¹ý mmap ϵͳµ÷ÓýøÐеØÖ·Ó³É䣬ËæºóÓà memset ½«ÆÁÄ»Çå¿Õ£¨ÕâÀï¼ÙÉèÏÔʾģʽÊÇ 1024x768-8 λɫģʽ£¬ÏßÐÔÄÚ´æģʽ£©£º

int fb;

unsigned char* fb_mem;

fb = open ("/dev/fb0", O_RDWR);

fb_mem = mmap (NULL, 1024*768, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);

memset (fb_mem, 0, 1024*768);

FrameBuffer É豸»¹ÌṩÁËÈô¸É ioctl ÃüÁͨ¹ýÕâЩÃüÁ¿ÉÒÔ»ñµÃÏÔʾÉ豸µÄһЩ¹Ì¶¨ÐÅÏ¢£¨±ÈÈçÏÔʾÄÚ´æ´óС£©¡¢ÓëÏÔʾģʽÏà¹ØµÄ¿É±äÐÅÏ¢£¨±ÈÈç·Ö±æÂÊ¡¢ÏóËؽṹ¡¢Ã¿É¨ÃèÏßµÄ×Ö½Ú¿í¶È£©£¬ÒÔ¼°Î±²Êɫģʽϵĵ÷É«°åÐÅÏ¢µÈµÈ¡£

ͨ¹ý FrameBuffer É豸£¬»¹¿ÉÒÔ»ñµÃµ±Ç°ÄÚºËËùÖ§³ÖµÄ¼ÓËÙÏÔʾ¿¨µÄÀàÐÍ£¨Í¨¹ý¹Ì¶¨ÐÅÏ¢µÃµ½£©£¬ÕâÖÖÀàÐÍͨ³£ÊǺÍÌض¨ÏÔʾоƬÏà¹ØµÄ¡£±ÈÈçÄ¿Ç°×îеÄÄںˣ¨2.4.9£©ÖУ¬¾Í°üº¬ÓÐ¶Ô S3¡¢Matrox¡¢nVidia¡¢3Dfx µÈµÈÁ÷ÐÐÏÔʾоƬµÄ¼ÓËÙÖ§³Ö¡£ÔÚ»ñµÃÁ˼ÓËÙоƬÀàÐÍÖ®ºó£¬Ó¦ÓóÌÐò¾Í¿ÉÒÔ½« PCI É豸µÄÄÚ´æI/O£¨memio£©Ó³Éäµ½½ø³ÌµÄµØÖ·¿Õ¼ä¡£ÕâЩ memio Ò»°ãÊÇÓÃÀ´¿ØÖÆÏÔʾ¿¨µÄ¼Ä´æÆ÷£¬Í¨¹ý¶ÔÕâЩ¼Ä´æÆ÷µÄ²Ù×÷£¬Ó¦ÓóÌÐò¾Í¿ÉÒÔ¿ØÖÆÌض¨ÏÔ¿¨µÄ¼ÓËÙ¹¦ÄÜ¡£

PCI É豸¿ÉÒÔ½«×Ô¼ºµÄ¿ØÖƼĴæÆ÷Ó³Éäµ½ÎïÀíÄÚ´æ¿Õ¼ä£¬¶øºó£¬¶ÔÕâЩ¿ØÖƼĴæÆ÷µÄ·ÃÎÊ£¬¸ø±ä³ÉÁ˶ÔÎïÀíÄÚ´æµÄ·ÃÎÊ¡£Òò´Ë£¬ÕâЩ¼Ä´æÆ÷ÓÖ±»³ÆΪ"memio"¡£Ò»µ©±»Ó³Éäµ½ÎïÀíÄڴ棬Linux µÄÆÕͨ½ø³Ì¾Í¿ÉÒÔͨ¹ý mmap ½«ÕâЩÄÚ´æ I/O Ó³Éäµ½½ø³ÌµØÖ·¿Õ¼ä£¬ÕâÑù¾Í¿ÉÒÔÖ±½Ó·ÃÎÊÕâЩ¼Ä´æÆ÷ÁË¡£

µ±È»£¬ÒòΪ²»Í¬µÄÏÔʾоƬ¾ßÓв»Í¬µÄ¼ÓËÙÄÜÁ¦£¬¶Ômemio µÄʹÓúͶ¨ÒåÒ²¸÷×Ô²»Í¬£¬Õâʱ£¬¾ÍÐèÒªÕë¶Ô¼ÓËÙоƬµÄ²»Í¬ÀàÐÍÀ´±àдʵÏÖ²»Í¬µÄ¼ÓËÙ¹¦ÄÜ¡£±ÈÈç´ó¶àÊýоƬ¶¼ÌṩÁ˶ԾØÐÎÌî³äµÄÓ²¼þ¼ÓËÙÖ§³Ö£¬µ«²»Í¬µÄоƬʵÏÖ·½Ê½²»Í¬£¬Õâʱ£¬¾ÍÐèÒªÕë¶Ô²»Í¬µÄоƬÀàÐͱàд²»Í¬µÄÓÃÀ´Íê³ÉÌî³ä¾ØÐεĺ¯Êý¡£

FrameBuffer Ö»ÊÇÒ»¸öÌṩÏÔʾÄÚ´æºÍÏÔʾоƬ¼Ä´æÆ÷´ÓÎïÀíÄÚ´æÓ³Éäµ½½ø³ÌµØÖ·¿Õ¼äÖеÄÉ豸¡£ËùÒÔ£¬¶ÔÓÚÓ¦ÓóÌÐò¶øÑÔ£¬Èç¹ûÏ£ÍûÔÚ FrameBuffer Ö®ÉϽøÐÐͼÐαà³Ì£¬»¹ÐèÒª×Ô¼º¶¯ÊÖÍê³ÉÆäËûÐí¶à¹¤×÷¡£



¶þ¡¢FrameBufferÔÚLINUXÖÐʵÏֺͻúÖÆ

Framebuffer¶ÔÓ¦µÄÔ´ÎļþÔÚlinux/drivers/video/Ŀ¼Ï¡£×ܵijéÏóÉ豸ÎļþΪfbcon.c£¬ÔÚÕâ¸öĿ¼Ï»¹ÓÐÓë¸÷ÖÖÏÔ¿¨Çý¶¯Ïà¹ØµÄÔ´Îļþ¡£

(Ò»)¡¢·ÖÎöFramebufferÉ豸Çý¶¯

ÐèÒªÌرðÌá³öµÄÊÇÔÚINTELƽ̨ÉÏ£¬ÀÏʽµÄVESA 1.2 ¿¨£¬ÈçCGA/EGA¿¨£¬ÊDz»ÄÜÖ§³ÖFramebufferµÄ£¬ÒòΪFramebufferÒªÇóÏÔ¿¨Ö§³ÖÏßÐÔÖ¡»º³å£¬¼´CPU¿ÉÒÔ·ÃÎÊÏÔ»º³åÖеÄÿһ룬µ«ÊÇVESA 1.2 ¿¨Ö»ÄÜÔÊÐíCPUÒ»´Î·ÃÎÊ64KµÄµØÖ·¿Õ¼ä¡£

FrameBufferÉ豸Çý¶¯»ùÓÚÈçÏÂÁ½¸öÎļþ£º

1) linux/include/linux/fb.h
2) linux/drivers/video/fbmem.c

ÏÂÃæ·ÖÎöÕâÁ½¸öÎļþ¡£

1¡¢fb.h

¼¸ºõÖ÷ÒªµÄ½á¹¹¶¼ÊÇÔÚÕâ¸öÖÐÎļþ¶¨ÒåµÄ¡£ÕâЩ½á¹¹°üÀ¨£º

1£©fb_var_screeninfo

Õâ¸ö½á¹¹ÃèÊöÁËÏÔʾ¿¨µÄÌØÐÔ£º

struct fb_var_screeninfo

{
__u32 xres; /* visible resolution */
__u32 yres;
__u32 xres_virtual; /* virtual resolution */
__u32 yres_virtual;
__u32 xoffset; /* offset from virtual to visible resolution */
__u32 yoffset;

__u32 bits_per_pixel; /* guess what */
__u32 grayscale; /* != 0 Gray levels instead of colors */

struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */

__u32 nonstd; /* != 0 Non standard pixel format */

__u32 activate; /* see FB_ACTIVATE_* */

__u32 height; /* height of picture in mm */
__u32 width; /* width of picture in mm */

__u32 accel_flags; /* acceleration flags (hints) */

/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock; /* pixel clock in ps (pico seconds) */
__u32 left_margin; /* time from sync to picture */
__u32 right_margin; /* time from picture to sync */
__u32 upper_margin; /* time from sync to picture */
__u32 lower_margin;
__u32 hsync_len; /* length of horizontal sync */
__u32 vsync_len; /* length of vertical sync */
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 reserved[6]; /* Reserved for future compatibility */
};

2) fb_fix_screeninfon
Õâ¸ö½á¹¹ÔÚÏÔ¿¨±»É趨ģʽºó´´½¨£¬ËüÃèÊöÏÔʾ¿¨µÄÊôÐÔ£¬²¢ÇÒϵͳÔËÐÐʱ²»Äܱ»Ð޸ģ»±ÈÈçFrameBufferÄÚ´æµÄÆðʼµØÖ·¡£ËüÒÀÀµÓÚ±»É趨µÄģʽ£¬µ±Ò»¸öģʽ±»É趨ºó£¬ÄÚ´æÐÅÏ¢ÓÉÏÔʾ¿¨Ó²¼þ¸ø³ö£¬ÄÚ´æµÄλÖõÈÐÅÏ¢¾Í²»¿ÉÒÔÐ޸ġ£

struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */
unsigned long smem_start; /* Start of frame buffer mem */
/* (physical address) */
__u32 smem_len; /* Length of frame buffer mem */
__u32 type; /* see FB_TYPE_* */
__u32 type_aux; /* Interleave for interleaved Planes */
__u32 visual; /* see FB_VISUAL_* */
__u16 xpanstep; /* zero if no hardware panning */
__u16 ypanstep; /* zero if no hardware panning */
__u16 ywrapstep; /* zero if no hardware ywrap */
__u32 line_length; /* length of a line in bytes */
unsigned long mmio_start; /* Start of Memory Mapped I/O */
/* (physical address) */
__u32 mmio_len; /* Length of Memory Mapped I/O */
__u32 accel; /* Type of acceleration available */
__u16 reserved[3]; /* Reserved for future compatibility */
};

3) fb_cmap
ÃèÊöÉ豸Î޹صÄÑÕÉ«Ó³ÉäÐÅÏ¢¡£¿ÉÒÔͨ¹ýFBIOGETCMAP ºÍ FBIOPUTCMAP ¶ÔÓ¦µÄioctl²Ù×÷É趨»ò»ñÈ¡ÑÕÉ«Ó³ÉäÐÅÏ¢.

struct fb_cmap {
__u32 start; /* First entry */
__u32 len; /* Number of entries */
__u16 *red; /* Red values */
__u16 *green;
__u16 *blue;
__u16 *transp; /* transparency, can be NULL */
};

4) fb_info
¶¨Òåµ±ÏÔ¿¨µÄµ±Ç°×´Ì¬£»fb_info½á¹¹½öÔÚÄÚºËÖпɼû£¬ÔÚÕâ¸ö½á¹¹ÖÐÓÐÒ»¸öfb_opsÖ¸Õ룬 Ö¸ÏòÇý¶¯É豸¹¤×÷ËùÐèµÄº¯Êý¼¯¡£

struct fb_info {
char modename[40]; /* default video mode */
kdev_t node;
int flags;
int open; /* Has this been open already ? */
#define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */
struct fb_var_screeninfo var; /* Current var */
struct fb_fix_screeninfo fix; /* Current fix */
struct fb_monspecs monspecs; /* Current Monitor specs */
struct fb_cmap cmap; /* Current cmap */
struct fb_ops *fbops;
char *screen_base; /* Virtual address */
struct display *disp; /* initial display variable */
struct vc_data *display_fg; /* Console visible on this display */
char fontname[40]; /* default font name */
devfs_handle_t devfs_handle; /* Devfs handle for new name */
devfs_handle_t devfs_lhandle; /* Devfs handle for compat. symlink */
int (*changevar)(int); /* tell console var has changed */
int (*switch_con)(int, struct fb_info*);
/* tell fb to switch consoles */
int (*updatevar)(int, struct fb_info*);
/* tell fb to update the vars */
void (*blank)(int, struct fb_info*); /* tell fb to (un)blank the screen */
/* arg = 0: unblank */
/* arg > 0: VESA level (arg-1) */
void *pseudo_palette; /* Fake palette of 16 colors and
the cursor's color for non
palette mode */
/* From here on everything is device dependent */
void *par;
};

5) struct fb_ops
Óû§Ó¦ÓÿÉÒÔʹÓÃioctl()ϵͳµ÷ÓÃÀ´²Ù×÷É豸£¬Õâ¸ö½á¹¹¾ÍÊÇÓÃÒ»Ö§³Öioctl()µÄÕâЩ²Ù×÷µÄ¡£

struct fb_ops {
/* open/release and usage marking */
struct module *owner;
int (*fb_open)(struct fb_info *info, int user);
int (*fb_release)(struct fb_info *info, int user);
/* get non settable parameters */
int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
/* get settable parameters */
int (*fb_get_var)(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
/* set settable parameters */
int (*fb_set_var)(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
/* get colormap */
int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
/* set colormap */
int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
/* pan display (optional) */
int (*fb_pan_display)(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
/* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg, int con, struct fb_info *info);
/* perform fb specific mmap */
int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
/* switch to/from raster image mode */
int (*fb_rasterimg)(struct fb_info *info, int start);
};

6) structure map
struct fb_info_gen | struct fb_info | fb_var_screeninfo
| | fb_fix_screeninfo
| | fb_cmap
| | modename[40]
| | fb_ops ---|--->ops on var
| | ... | fb_open
| | | fb_release
| | | fb_ioctl
| | | fb_mmap
| struct fbgen_hwswitch -|-> detect
| | encode_fix
| | encode_var
| | decode_fix
| | decode_var
| | get_var
| | set_var
| | getcolreg
| | setcolreg
| | pan_display
| | blank
| | set_disp

[±àÅÅÓеãÀ§ÄÑ£¬µÚÒ»ÐеĵÚÒ»ÌõÊúÏߺÍÏÂÃæµÄµÚÒ»ÁÐÊúÏ߶ÔÆ룬µÚÒ»ÐеĵڶþÌõÊúÏߺÍÏÂÃæµÄµÚ¶þÁÐÊúÏ߶ÔÆë¾Í¿ÉÒÔÁË]
Õâ¸ö½á¹¹ fbgen_hwswitch³éÏóÁËÓ²¼þµÄ²Ù×÷.ËäÈ»Ëü²»ÊDZØÐèµÄ£¬µ«ÓÐʱºòºÜÓÐÓÃ.

2¡¢ fbmem.c
fbmem.c ´¦ÓÚFramebufferÉ豸Çý¶¯¼¼ÊõµÄÖÐÐÄλÖÃ.ËüΪÉϲãÓ¦ÓóÌÐòÌṩϵͳµ÷Óà ҲΪÏÂÒ»²ãµÄÌض¨Ó²¼þÇý¶¯Ìṩ½Ó¿Ú£»ÄÇЩµ×²ãÓ²¼þÇý¶¯ÐèÒªÓõ½Õâ¶ùµÄ½Ó¿ÚÀ´ÏòϵͳÄÚºË×¢²áËüÃÇ×Ô¼º. fbmem.c ΪËùÓÐÖ§³ÖFrameBufferµÄÉ豸Çý¶¯ÌṩÁËͨÓõĽӿڣ¬±ÜÃâÖظ´¹¤×÷.

1) È«¾Ö±äÁ¿

struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;


ÕâÁ½±äÁ¿¼Ç¼ÁËËùÓÐfb_info ½á¹¹µÄʵÀý£¬fb_info ½á¹¹ÃèÊöÏÔ¿¨µÄµ±Ç°×´Ì¬£¬ËùÓÐÉ豸¶ÔÓ¦µÄfb_info ½á¹¹¶¼±£´æÔÚÕâ¸öÊý×éÖУ¬µ±Ò»¸öFrameBufferÉ豸Çý¶¯Ïòϵͳע²á×Ô¼ºÊ±£¬Æä¶ÔÓ¦µÄfb_info ½á¹¹¾Í»áÌí¼Óµ½Õâ¸ö½á¹¹ÖУ¬Í¬Ê±num_registered_fb Ϊ×Ô¶¯¼Ó1.

static struct {
const char *name;
int (*init)(void);
int (*setup)(void);
} fb_drivers[] __initdata= { ....};

Èç¹ûFrameBufferÉ豸±»¾²Ì¬Á´½Óµ½Äںˣ¬Æä¶ÔÓ¦µÄÈë¿Ú¾Í»áÌí¼Óµ½Õâ¸ö±íÖУ»Èç¹ûÊǶ¯Ì¬¼ÓÔصģ¬¼´Ê¹ÓÃinsmod/rmmod,¾Í²»ÐèÒª¹ØÐÄÕâ¸ö±í¡£

static struct file_operations fb_ops ={
owner: THIS_MODULE,
read: fb_read,
write: fb_write,
ioctl: fb_ioctl,
mmap: fb_mmap,
open: fb_open,
release: fb_release
};
ÕâÊÇÒ»¸öÌṩ¸øÓ¦ÓóÌÐòµÄ½Ó¿Ú.

2£©fbmem.c ʵÏÖÁËÈçϺ¯Êý.

register_framebuffer(struct fb_info *fb_info);
unregister_framebuffer(struct fb_info *fb_info);

ÕâÁ½¸öÊÇÌṩ¸øϲãFrameBufferÉ豸Çý¶¯µÄ½Ó¿Ú£¬É豸Çý¶¯Í¨¹ýÕâÁ½º¯ÊýÏòϵͳע²á»ò×¢Ïú×Ô¼º¡£¼¸ºõµ×²ãÉ豸Çý¶¯ËùÒª×öµÄËùÓÐÊÂÇé¾ÍÊÇÌî³äfb_info½á¹¹È»ºóÏòϵͳע²á»ò×¢ÏúËü¡£

£¨¶þ£©Ò»¸öLCDÏÔʾоƬµÄÇý¶¯ÊµÀý

ÒÔSkeleton LCD ¿ØÖÆÆ÷Çý¶¯ÎªÀý£¬ÔÚLINUXÖдæÓÐÒ»¸ö/fb/skeleton.cµÄskeletonµÄFramebufferÇý¶¯³ÌÐò£¬ºÜ¼òµ¥£¬½ö½öÊÇÌî³äÁË fb_info½á¹¹£¬²¢ÇÒ×¢²á/×¢Ïú×Ô¼º¡£É豸Çý¶¯ÊÇÏòÓû§³ÌÐòÌṩϵͳµ÷Óýӿڣ¬ËùÒÔÎÒÃÇÐèҪʵÏֵײãÓ²¼þ²Ù×÷²¢ÇÒ¶¨Òåfile_operations ½á¹¹À´ÏòϵͳÌṩϵͳµ÷Óýӿڣ¬´Ó¶øʵÏÖ¸üÓÐЧµÄLCD¿ØÖÆÆ÷Çý¶¯³ÌÐò¡£

1£©ÔÚϵͳÄÚ´æÖзÖÅäÏÔ´æ
ÔÚfbmem.cÎļþÖпÉÒÔ¿´µ½, file_operations ½á¹¹ÖеÄopen()ºÍrelease()²Ù×÷²»Ðèµ×²ãÖ§³Ö£¬µ«read()¡¢write()ºÍ mmap()²Ù×÷ÐèÒªº¯Êýfb_get_fix()µÄÖ§³Ö.Òò´ËÐèÒªÖØÐÂʵÏÖº¯Êýfb_get_fix()¡£ÁíÍ⻹ÐèÒªÔÚϵͳÄÚ´æÖзÖÅäÏÔ´æ¿Õ¼ä£¬´ó¶àÊý µÄLCD¿ØÖÆÆ÷¶¼Ã»ÓÐ×Ô¼ºµÄÏÔ´æ¿Õ¼ä£¬±»·ÖÅäµÄµØÖ·¿Õ¼äµÄÆðʼµØÖ·Ó볤¶È½«»á±»Ìî³äµ½fb_fix_screeninfo ½á¹¹µÄsmem_start ºÍsmem_len µÄÁ½¸ö±äÁ¿ÖÐ.±»·ÖÅäµÄ¿Õ¼ä±ØÐëÊÇÎïÀíÁ¬ÐøµÄ¡£

2£©ÊµÏÖ fb_ops Öеĺ¯Êý
Óû§Ó¦ÓóÌÐòͨ¹ýioctl()ϵͳµ÷ÓòÙ×÷Ó²¼þ£¬fb_ops Öеĺ¯Êý¾ÍÓÃÓÚÖ§³ÖÕâЩ²Ù×÷¡££¨×¢£º fb_ops½á¹¹Óëfile_operations ½á¹¹²»Í¬£¬fb_opsÊǵײã²Ù×÷µÄ³éÏó,¶øfile_operationsÊÇÌṩ¸øÉϲãϵͳµ÷ÓõĽӿڣ¬¿ÉÒÔÖ±½Óµ÷ÓÃ.
ioctl()ϵͳµ÷ÓÃÔÚÎļþfbmem.cÖÐʵÏÖ£¬Í¨¹ý¹Û²ì¿ÉÒÔ·¢ÏÖioctl()ÃüÁîÓëfb_ops¡¯s Öк¯ÊýµÄ¹Øϵ:
FBIOGET_VSCREENINFO fb_get_var
FBIOPUT_VSCREENINFO fb_set_var
FBIOGET_FSCREENINFO fb_get_fix
FBIOPUTCMAP fb_set_cmap
FBIOGETCMAP fb_get_cmap
FBIOPAN_DISPLAY fb_pan_display


Èç¹ûÎÒÃǶ¨ÒåÁËfb_XXX_XXX ·½·¨£¬Óû§³ÌÐò¾Í¿ÉÒÔʹÓÃFBIOXXXXºêµÄioctl()²Ù×÷À´²Ù×÷Ó²¼þ¡£

Îļþlinux/drivers/video/fbgen.c»òÕßlinux/drivers/videoĿ¼ÏµÄÆäËüÉ豸Çý¶¯ÊDZȽϺõIJο¼×ÊÁÏ¡£ÔÚËùÓеÄÕâЩº¯ÊýÖÐfb_set_var()ÊÇ×îÖØÒªµÄ£¬ËüÓÃÓÚÉ趨ÏÔʾ¿¨µÄģʽºÍÆäËüÊôÐÔ£¬ÏÂÃæÊǺ¯Êýfb_set_var()µÄÖ´Ðв½Ö裺

1)¼ì²âÊÇ·ñ±ØÐëÉ趨ģʽ
2)É趨ģʽ

3)É趨ÑÕÉ«Ó³Éä

4) ¸ù¾ÝÒÔÇ°µÄÉ趨ÖØÐÂÉèÖÃLCD¿ØÖÆÆ÷µÄ¸÷¼Ä´æÆ÷¡£

µÚËIJ½±íÃ÷Á˵ײã²Ù×÷µ½µ×·ÅÖÃÔںδ¦¡£ÔÚϵͳÄÚ´æÖзÖÅäÏÔ´æºó£¬ÏÔ´æµÄÆðʼµØÖ·¼°³¤¶È½«±»É趨µ½LCD¿ØÖÆÆ÷µÄ¸÷¼Ä´æÆ÷ÖУ¨Ò»°ãͨ¹ýfb_set_var() º¯Êý£©£¬ÏÔ´æÖеÄÄÚÈݽ«×Ô¶¯±»LCD¿ØÖÆÆ÷Êä³öµ½ÆÁÄ»ÉÏ¡£ÁíÒ»·½Ã棬Óû§³ÌÐòͨ¹ýº¯Êýmmap()½«ÏÔ´æÓ³Éäµ½Óû§½ø³ÌµØÖ·¿Õ¼äÖУ¬È»ºóÓû§½ø³ÌÏòÓ³Éä¿Õ¼ä·¢Ë͵ÄËùÓÐÊý¾Ý¶¼½«»á±»ÏÔʾµ½LCDÏÔʾÆ÷ÉÏ¡£



Èý¡¢FrameBufferµÄÓ¦ÓÃ

£¨Ò»£©¡¢Ò»¸öʹÓÃFrameBufferµÄÀý×Ó

1¡¢FrameBufferÖ÷ÒªÊǸù¾ÝVESA±ê×¼µÄʵÏֵģ¬ËùÒÔÖ»ÄÜʵÏÖ×î¼òµ¥µÄ¹¦ÄÜ¡£

2¡¢ÓÉÓÚÉæ¼°Äں˵ÄÎÊÌ⣬FrameBufferÊDz»ÔÊÐíÔÚϵͳÆðÀ´ºóÐÞ¸ÄÏÔʾģʽµÈһϵÁвÙ×÷¡££¨ºÃÏóºÜ¶àÈ˶¼ÏëÒªÕâÑù¸É£¬ÕâÊDz»±»ÔÊÐíµÄ£¬µ±È»Èç¹ûÄã×Ô¼ºÐ´Çý¶¯µÄ»°£¬ÊÇ¿ÉÒÔʵÏֵģ©.

3¡¢¶ÔFrameBufferµÄ²Ù×÷£¬»áÖ±½ÓÓ°Ïìµ½±¾»úµÄËùÓпØÖÆ̨µÄÊä³ö£¬°üÀ¨XWINµÄͼÐνçÃæ¡£

ºÃ£¬ÏÖÔÚ¿ÉÒÔÈÃÎÒÃÇ¿ªÊ¼ÊµÏÖÖ±½ÓдÆÁ£º

1¡¢´ò¿ªÒ»¸öFrameBufferÉ豸

2¡¢Í¨¹ýmmapµ÷ÓðÑÏÔ¿¨µÄÎïÀíÄÚ´æ¿Õ¼äÓ³Éäµ½Óû§¿Õ¼ä

3¡¢Ö±½ÓдÄÚ´æ¡£

/********************************

File name : fbtools.h

*/

#ifndef _FBTOOLS_H_

#define _FBTOOLS_H_

#include

//a framebuffer device structure;

typedef struct fbdev{

int fb;

unsigned long fb_mem_offset;

unsigned long fb_mem;

struct fb_fix_screeninfo fb_fix;

struct fb_var_screeninfo fb_var;

char dev[20];

} FBDEV, *PFBDEV;

//open & init a frame buffer

//to use this function,

//you must set FBDEV.dev="/dev/fb0"

//or "/dev/fbX"

//it's your frame buffer.

int fb_open(PFBDEV pFbdev);

//close a frame buffer

int fb_close(PFBDEV pFbdev);

//get display depth

int get_display_depth(PFBDEV pFbdev);

//full screen clear

void fb_memset(void *addr, int c, size_t len);

#endif



/******************

File name : fbtools.c

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include "fbtools.h"

#define TRUE 1

#define FALSE 0

#define MAX(x,y) ((x)>(y)?(x)y))

#define MIN(x,y) ((x)<(y)?(x)y))

//open & init a frame buffer

int fb_open(PFBDEV pFbdev)

{

pFbdev->fb = open(pFbdev->dev, O_RDWR);

if(pFbdev->fb < 0)

{

printf("Error opening %s: %m. Check kernel config\n", pFbdev->dev);

return FALSE;

}

if (-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var)))

{

printf("ioctl FBIOGET_VSCREENINFO\n");

return FALSE;

}

if (-1 == ioctl(pFbdev->fb,FBIOGET_FSCREENINFO,&(pFbdev->fb_fix)))

{

printf("ioctl FBIOGET_FSCREENINFO\n");

return FALSE;

}

//map physics address to virtual address

pFbdev->fb_mem_offset = (unsigned long)(pFbdev->fb_fix.smem_start) & (~PAGE_MASK);

pFbdev->fb_mem = (unsigned long int)mmap(NULL, pFbdev->fb_fix.smem_len + pFbdev->fb_mem_offset, PROT_READ | PROT_WRITE, MAP_SHARED, pFbdev->fb, 0);

if (-1L == (long) pFbdev->fb_mem)

{

printf("mmap error! mem:%d offset:%d\n", pFbdev->fb_mem, pFbdev->fb_mem_offset);

return FALSE;

}

return TRUE;

}

//close frame buffer

int fb_close(PFBDEV pFbdev)

{

close(pFbdev->fb);

pFbdev->fb=-1;

}

//get display depth

int get_display_depth(PFBDEV pFbdev);

{

if(pFbdev->fb<=0)

{

printf("fb device not open, open it first\n");

return FALSE;

}

return pFbdev->fb_var.bits_per_pixel;

}

//full screen clear

void fb_memset (void *addr, int c, size_t len)

{

memset(addr, c, len);

}

//use by test

#define DEBUG

#ifdef DEBUG

main()

{

FBDEV fbdev;

memset(&fbdev, 0, sizeof(FBDEV));

strcpy(fbdev.dev, "/dev/fb0");

if(fb_open(&fbdev)==FALSE)

{

printf("open frame buffer error\n");

return;

}

fb_memset(fbdev.fb_mem + fbdev.fb_mem_offset, 0, fbdev.fb_fix.smem_len);

fb_close(&fbdev);

}

£¨¶þ£©»ùÓÚLinuxºËÐĵĺº×ÖÏÔʾµÄ³¢ÊÔ

ÎÒÃÇÒÔÒ»¸ö¼òµ¥µÄÀý×ÓÀ´ËµÃ÷×Ö·ûÏÔʾµÄ¹ý³Ì¡£ÎÒÃǼÙÉèÊÇÔÚÐéÄâÖÕ¶Ë1£¨/dev/tty1£©ÏÂÔËÐÐÒ»¸öÈçϵļòµ¥³ÌÐò¡£

main ( )

{

puts("hello, world.\n");

}

puts º¯ÊýÏòȱʡÊä³öÎļþ(/dev/tty1)·¢³öдµÄϵͳµ÷ÓÃwrite(2)¡£ÏµÍ³µ÷Óõ½linuxºËÐÄÀïÃæ¶ÔÓ¦µÄºËÐĺ¯ÊýÊÇconsole.cÖÐµÄ con_write()£¬con_write()×îÖÕ»áµ÷ÓÃdo_con_write( )¡£ÔÚdo_con_write( )ÖиºÔð°Ñ"hello, world.\n"Õâ¸ö×Ö·û´®·Åµ½tty1¶ÔÓ¦µÄ»º³åÇøÖÐÈ¥¡£

do_con_write( )»¹¸ºÔð´¦Àí¿ØÖÆ×Ö·ûºÍ¹â±êµÄλÖá£ÈÃÎÒÃÇÀ´¿´Ò»ÏÂdo_con_write()Õâ¸öº¯ÊýµÄÉùÃ÷¡£

static int do_con_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count)

ÆäÖÐttyÊÇÖ¸Ïòtty_struct½á¹¹µÄÖ¸Õ룬Õâ¸ö½á¹¹ÀïÃæ´æ·Å׏ØÓÚÕâ¸öttyµÄËùÓÐÐÅÏ¢£¨Çë²ÎÕÕ linux/include/linux/tty.h£©¡£Tty_struct½á¹¹Öж¨ÒåÁËͨÓ㨻ò¸ß²ã£©ttyµÄÊôÐÔ£¨ÀýÈç¿í¶ÈºÍ¸ß¶ÈµÈ£©¡£ÔÚdo_con_write( )º¯ÊýÖÐÓõ½ÁËtty_struct½á¹¹ÖеÄdriver_data±äÁ¿¡£driver_dataÊÇÒ»¸övt_structÖ¸Õë¡£ÔÚvt_struct½á¹¹Öаüº¬Õâ¸öttyµÄÐòÁкţ¨ÎÒÃÇÕýʹÓÃtty1£¬ËùÒÔÕâ¸öÐòºÅΪ1£©¡£Vt_struct½á¹¹ÖÐÓÐÒ»¸övc½á¹¹µÄÊý×évc_cons£¬Õâ¸öÊý×é¾ÍÊǸ÷ÐéÄâÖն˵Ä˽ÓÐÊý¾Ý¡£

static int do_con_write(struct tty_struct * tty, int from_user,const unsigned char *buf, int count)

{

struct vt_struct *vt = (struct vt_struct *)tty->driver_data;//ÎÒÃÇÓõ½ÁËdriver_data±äÁ¿

. . . . .

currcons = vt->vc_num; file://ÎÒÃÇÔÚÕâÀïµÄvc_nums¾ÍÊÇ1

. . . . .

}

Òª·ÃÎÊÐéÄâÖն˵Ä˽ÓÐÊý¾Ý£¬ÐèʹÓÃvc_cons¡²currcons¡³.dÖ¸Õë¡£Õâ¸öÖ¸ÕëÖ¸ÏòµÄ½á¹¹º¬Óе±Ç°ÐéÄâÖÕ¶ËÉϹâ±êµÄλÖᢻº³åÇøµÄÆðʼµØÖ·¡¢»º³åÇø´óСµÈµÈ¡£

"hello, world.\n"ÖеÄÿһ¸ö×Ö·û¶¼Òª¾­¹ýconv_uni_to_pc( )Õâ¸öº¯Êýת»»³É£¸Î»µÄÏÔʾ×Ö·û¡£ÕâÒª×öµÄÖ÷ҪĿµÄÊÇʹ²»Í¬ÓïÑԵĹú¼ÒÄÜ°Ñ£±£¶Î»µÄUniCodeÂëÓ³Éäµ½8λµÄÏÔʾ×Ö·û¼¯ÉÏ£¬Ä¿Ç°»¹ÊÇÖ÷ÒªÕë¶ÔÅ·ÖÞ¹ú¼ÒµÄÓïÑÔ£¬Ó³Éä½á¹ûΪ8룬²»°üº¬¶ÔË«×Ö½Ú£¨double byte£©µÄ·¶Î§¡£

ÕâÖÖUNICODEµ½ÏÔʾ×Ö·ûµÄÓ³Éä¹Øϵ¿ÉÒÔÓÉÓû§×ÔÐж¨Òå¡£ÔÚȱʡµÄÓ³Éä±íÉÏ£¬»á°ÑÖÐÎĵÄ×Ö·ûÓ³Éäµ½ÆäËûµÄ×Ö·ûÉÏ£¬ÕâÊÇÎÒÃDz»Ï£Íû¿´µ½Ò²ÊDz»ÐèÒªµÄ¡£ËùÒÔÎÒÃÇÓÐÁ½¸öÑ¡Ôñ¡Ã

1²»½øÐÐconv_uni_to_pc( )µÄת»»¡£

2¼ÓÔØ·ûºÏË«×Ö½Ú´¦ÀíµÄÓ³Éä¹Øϵ£¬¼´¶Ô·Ç¿ØÖÆ×Ö·û½øÐÐ1¶Ô1µÄ²»±äÓ³Éä¡£ÎÒÃÇ×Ô¼º¶¨ÖƵķûºÏÕâÖÖÓ³Éä¹ØϵµÄUNICODEÂë±íÊÇdirect.uni¡£ÒªÏë²é¿´/×°Ôص±Ç°ÏµÍ³µÄunicodeÓ³Éä±í£¬¿ÉʹÍⲿÃüÁîloadunimap¡£

¾­¹ýconv_uni_to_pc( )ת»»Ö®ºó£¬"hello, world.\n"ÖеÄ×Ö·û±»Ò»¸öÒ»¸öµØÌîдµ½tty1µÄ»º³åÇøÖС£È»ºódo_con_write( )µ÷ÓÃϲãµÄÇý¶¯£¬°Ñ»º³åÇøÖеÄÄÚÈÝÊä³öµ½ÏÔʾÆ÷ÉÏ£¨Ò²¾ÍÏ൱ÓÚ°Ñ»º³åÇøµÄÄÚÈÝ¿½±´µ½VGAÏÔ´æÖÐÈ¥£©¡£

sw->con_putcs(vc_cons¡²currcons¡³.d, (u16 *)draw_from, (u16*)draw_to-(u16 *)draw_from, y, draw_x);

Ö®ËùÒÔÒªµ÷ÓõײãÇý¶¯£¬ÊÇÒòΪ´æÔÚ²»Í¬µÄÏÔʾÉ豸£¬Æä¶ÔÓ¦VGAÏÔ´æµÄ´æÈ¡·½Ê½Ò²²»Ò»Ñù¡£

ÉÏÃæµÄSw->con_putcs( )¾Í»áµ÷Óõ½fbcon.cÖеÄfbcon_putcs()º¯Êý£¨con_putcsÊÇÒ»¸öº¯ÊýµÄÖ¸Õ룬ÔÚFramebufferģʽÏÂÖ¸Ïò fbcon_putcs()º¯Êý£©¡£Ò²¾ÍÊÇ˵ÔÚdo_con_write( )º¯ÊýÖÐÊÇÖ±½Óµ÷ÓÃÁËfbcon_putcs()º¯ÊýÀ´½øÐÐ×Ö·ûµÄ»æÖÆ¡£±ÈÈç˵ÔÚ256ɫģʽÏ£¬ÕæÕý¸ºÔðÊä³öµÄº¯ÊýÊÇvoid fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,const unsigned short *s, int count, int yy, int xx)

ÏÔʾÖÐÎÄ

±ÈÈç˵ÎÒÃÇÊÔͼÊä³öÒ»¾äÖÐÎÄ¡Ãputcs(ÄãºÃ\n );£¨ÄãºÃµÄÄÚÂëΪ0xc4,0xe3,0xba,0xc3£©¡£Õâʱºò»áÔõôÑùÄØ£¬ÓÐÒ»µã¿ÉÒԿ϶¨£¬£¢ÄãºÃ£¢¿Ï¶¨²»»á³öÏÖÔÚÆÁÄ»ÉÏ£¬¹úΪºËÐÄÖÐûÓкº×Ö×ֿ⣬ÖÐÎÄÏÔʾ¾ÍÊÇÎÞÃ×Ö®´¶ÁË£®

1 ÔÚ¸ºÔð×Ö·ûÏÔʾµÄvoid fbcon_cfb8_putcs( )º¯ÊýÖУ¬Ô­ÓвÙ×÷ÈçÏ¡öÔÓÚÿ¸öÒªÏÔʾµÄ×Ö·û£¬ÒÀ´Î´ÓÐéÄâÖն˻º³åÇøÖÐÒÔWORDΪµ¥Î»¶ÁÈ¡£¨µÍλ×Ö½ÚÊÇASCIIÂ룬¸ß8λÊÇ×Ö·ûµÄÊôÐÔ£©£¬ÓÉÓÚºº×ÖÊÇË«×Ö½Ú±àÂ뷽ʽ£¬ËùÒÔÕâÖÖ²Ù×÷ÊDz»¿ÉÄÜÏÔʾ³öºº×ֵģ¬Ö»ÄÜÏÔʾ³öxxxx_putcs()ÊÇÒ»¸öÒ»¸öVGA×Ö·û£®

Òª½â¾öµÄÎÊÌâ¡Ã

È·±£ÔÚdo_con_write( )ʱuni¡õpcת»»²»»á¸Ä±äÔ­ÓбàÂë¡£Ò»¸öºÜÖ±½ÓµÄʵÏÖ·½Ê½¾ÍÊǼÓÔØÒ»¸öÎÒÃÇ×Ô¼º¶¨ÖƵÄUNICODEÓ³Éä±í£¬loadunimapdirect.uni£¬»òÕßÖ±½Ó°Ñdirect.uniÖÃΪºËÐĵÄȱʡӳÉä±í¡£

Õë¶ÔÈçÉÏÎÊÌ⣬ÎÒÃÇÒª×öµÄµÚÒ»¸ö³¢ÊÔ·½°¸ÊÇÈçÏ¡£

Ê×ÏÈÐèÒªÔÚºËÐÄÖмÓÔغº×Ö×ֿ⣬ȻºóÐÞ¸Äfbcon_cfb8_putcs()º¯Êý£¬ÔÚfbcon_cfb8_putcs( )ÖÐÒ»´Î¶ÁÁ½¸öWORD£¬¼ì²éÕâÁ½¸öWORDµÄµÍλ×Ö½ÚÊÇ·ñÄÜÆ´³ÉÒ»¸öºº×Ö£¬Èç¹û·¢ÏÖÄÜÆ´³ÉÒ»¸öºº×Ö£¬¾ÍËã³öÕâ¸öºº×ÖÔÚºº×Ö×Ö¿âÖеÄÆ«ÒÆ£¬È»ºó°ÑËüµ±³ÉÒ»¸ö16 x 16µÄVGA×Ö·ûÀ´ÏÔʾ¡£

ÊÔÑéµÄ½á¹û±íÃ÷¡Ã

1Äܹ»Êä³öºº×Ö£¬µ«ÈÔÓÐÐí¶à²»ÀíÏëµÄµØ·½£¬±ÈÈç˵£¬Êä³öÒÔ°ë¸öºº×Ö¿ªÊ¼µÄÒ»´®ºº×Ö£¬ÔòÕâ°ë¸öºº×ÖºóÃæµÄºº×Ö¶¼»áÊÇÂÒÂë¡£ÕâÊÇ°ë¸öºº×ÖµÄÎÊÌâ¡£

2¹â±êÒƶ¯»áÆÆ»µºº×ÖµÄÏÔʾ¡£±íÏÖΪ£¬¹â±êÒƶ¯¹ýµÄºº×Ö»á±ä³ÉÂÒÂë¡£ÕâÊÇÒòΪ¹â±êµÄ¸üÐÂÊÇͨ¹ýxxxx_putc( )º¯ÊýÀ´Íê³ÉµÄ¡£

xxxx_putc( )º¯ÊýÓëxxxx_putcs( )º¯ÊýʵÏֵŦÄÜÀàËÆ£¬µ«ÊÇxxxx_putc()º¯ÊýֻˢÐÂÒ»¸ö×Ö·û¶ø²»ÊÇÒ»¸ö×Ö·û´®£¬Òò¶øxxxx_putc()µÄÊäÈë²ÎÊýÊÇÒ»¸öÕûÊý£¬¶ø²»ÊÇÒ»¸ö×Ö·û´®µÄµØÖ·¡£Xxxx_putc( )º¯ÊýµÄÉùÃ÷ÈçÏ¡Ãvoid fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)

ÏÂÒ»¸ö³¢ÊÔ·½°¸¾ÍÊÇͬʱÐÞ¸Äxxxx_putcs( )º¯ÊýºÍxxxx_putc()º¯Êý¡£ÎªÁ˽â¾ö°ë¸öºº×ÖµÄÎÊÌ⣬ÿһ´ÎÊä³ö֮ǰ£¬¶¼´ÓÆÁÄ»µ±Ç°ÐеÄÆðʼλÖÿªÊ¼É¨Ã裬ÒÔÈ·¶¨ÒªÊä³öµÄ×Ö·ûÊÇ·ñÂäÔÚ°ë¸öºº×ÖµÄλÖÃÉÏ¡£Èç¹ûÊÇ°ë¸öºº×ÖµÄλÖã¬Ôò½øÐÐÏàÓ¦µÄµ÷Õû£¬¼´´ÓÏòÇ°Òƶ¯Ò»¸ö×Ö½ÚµÄλÖÿªÊ¼Êä³ö¡£

Õâ¸ö·½°¸ÓÐÒ»¸öÀ§ÄÑ£¬¼´xxxx_putc( )º¯Êý²»Óûº³åÇøµÄµØÖ·£¬¶øÊÇÓÃÒ»¸öÕûÊý×÷Ϊ²ÎÊý¡£ËùÒÔxxxx_putc( )ÎÞ·¨Ö±½ÓÀûÓÃÏàÁÚµÄ×Ö·ûÀ´Åбð¸Ã¶¨·ûÊÇ·ñÊǺº×Ö¡£

½â¾ö·½°¸ÊÇ£¬ÀûÓÃxxxx_putc( )µÄ¹â±êλÖòÎÊý£¨yy, xx£©£¬¿ÉÒÔÄæÍƳö¸Ã×Ö·ûÔÚ»º³åÇøÖеÄλÖᣵ«ÈÔÓÐһЩСÂé·³£¬ÔÚLinuxµÄÐéÄâÖÕ¶ËÏ£¬Óû§¿ÉÄÜ»áÉϾí¸ÃÆÁÄ»£¨shift + pageup£©£¬µ¼Ö¹â±êµÄy×ù±êºÍÏàÓ¦×Ö·ûÔÚ»º³åÇøµÄÐÐÊý²»Ò»Ö¡£ÏàÓ¦µÄ½â¾ö·½°¸ÊÇ£¬ÔÚÄæÍƵĹý³ÌÖУ¬¿¼ÂǾíÆÁµÄ²ÎÁ¿¡£

ÕâÑùÒ»À´£¬ÎÒÃǾÍÓÖ½øÁËÒ»²½£¬µÃµ½ÁËÒ»¸öÏà¶Ô¸üºÃµÄ°æ±¾¡£µ«ÈÔÓÐÎÊÌâûÓнâ¾ö¡£ÇÃÈëturbonetcfg£¬»á·¢Ïֲ˵¥µÄ±ß¿ò×Ö·ûÒ²±»µ±³Éºº×ÖÏÔʾ¡£ÕâÊÇÒòΪ£¬ÕâÖֱ߿ò×Ö·ûÊÇÀ©Õ¹×Ö·û£¬Ò²Ê¹ÓÃÁË×Ö·ûµÄµÚ8룬Òò¶ø±»µ±×÷ºº×ÖÀ´ÏÔʾ¡£ÀýÈ磬µ¥ÏßÒ»µÄÖƱí·ûÄÚÂëΪ0xC4£¬µ±Á¬³ÉÒ»Ìõ³¤Ïß¾ÍÊÇÓÉÒ»Á¬´®0xC4×é³É£¬¶ø0xC4C4Õý ÊǺº×ÖÄÄ¡£ÓÚÊÇˮƽµÄÖƱí·û±»Ò»Á¬´®µÄÄÄ×ÖÌæ´úÁË¡£Òª½â¾öÕâ¸öÎÊÌâ¾Í·Ç³£²»ÈÝÒ×ÁË£¬ÒòΪÖƱí·ûµÄÖÖÀà±È½Ï¶à£¬¶øÇÒ´¹Ö±ÖƱí·ûÓëÆäºóÃæ×Ö·ûµÄ×éºÏÐÍʽÓÖ¶àÖÖ ¶àÑù£¬Òò¶øºÜÄÑÅжϳöÏàӦλÖõÄ×Ö·ûÊDz»ÊÇÖƱí·û£¬´ÓÀíÂÛÉÏ˵£¬ÎÞÂÛ²ÉȡʲôÑùµÄÅųýËã·¨£¬¶¼±ØÈ»´æÔÚÎóÅеÄÇé¿ö£¬ÒòΪ×Ü´æÔÚ¶þÒåÐÔ£¬Ã»Óгä×ãµÄÌõ¼þÀ´ÍÆ ¶Ï³öµ±Ç°×Ö·û¾¿¾¹ÊÇÖƱí·û»¹ÊǺº×Ö¡£

ÎÒÃÇÒ»·½ÃæÑ°ÕÒ¸üºÃµÄÅųý×éºÏËã·¨£¬Ò»·½ÃæÊÔͼѰÕÒÆäËüµÄ½â¾ö·½°¸¡£ÒªÏë´Ó¸ù±¾ÉϽâ¾ö¶¨¸öÎÊÌ⣬±ØÐëÀûÓÃÆäËüµÄ¸¨ÖúÐÅÏ¢£¬½ö½ö´Ó»º³åÇøµÄ×Ö·ûÀ´ÅжÏÊDz»¹»µÄ¡£

¾­¹ýÒ»·¬Å¬Á¦£¬ÎÒÃÇ·¢ÏÖ£¬ÔÚUNIXÖÐʹÓÃÀ©Õ¹×Ö·ûʱ£¬¶¼ÒªÏÈÊä³ö×Ö·ûתÒåÐòÁУ¨Escape sequence£©À´Çл»µ±Ç°×Ö·û¼¯¡£×Ö·ûתÒåÐòÁÐÊÇÒÔ¿ØÖÆ×Ö·ûEscΪÊ׵ĿØÖÆÃüÁÔÚUNIXµÄÐéÄâÖÕ¶ËÖÐÍê³ÉÖն˿ØÖÆÃüÁÕâÖÖÃüÁî°üÀ¨£¬Òƶ¯¹â±ê×ù±ê¡¢¾íÆÁ¡¢É¾³ý¡¢Çл»×Ö·û¼¯µÈµÈ¡£Ò²¾ÍÊÇ˵ÔÚÊä³ö´ú±íÖƱí·ûµÄ×Ö·û´®Ö®Ç°£¬Í¨³£ÊÇÒªÏÈÊä³öÌض¨µÄ×Ö·ûתÒåÐòÁС£ÔÚconsole.cÀÓиù¾Ý×Ö·ûתÒåÐòÁÐÃüÁîÀ´¼Ç¼×Ö·û״̬µÄ±äÁ¿¡£½áºÏ¸Ã±äÁ¿ÌṩµÄÐÅÏ¢£¬¾Í¿ÉÒԷdz£¸É¾»µØ°ÑÖƱí·ûÓ뺺×ÖÇø±ð¿ªÀ´¡£

ÔÚÈçÉÏ˼·µÄÖ¸ÒýÏ£¬ÎÒÃÇÓÖ²úÉúÁËеĽâ¾ö·½°¸¡£¾­¹ý¸Ä¶¯µÃµ½ÁËÁíÒ»¸÷°æ±¾£®

ÔÚÕâ¸öа汾ÉÏ£¬turbonetcfgÔÚ³õ´Î»æÖƵÄʱºò£¬ÖƱí·ûÓ뺺×Ö±»ÇåÎúµØÇø·Ö¿ªÀ´£¬½á¹ûÊǷdz£ÕýÈ·µÄ¡£µ«»¹ÓÐеÄÎÊÌâ´æÔÚ¡Ãturbonetcfg ÔÚÖØ»æµÄʱºò£¨ÈçÇл»ÐéÄâÖն˻òÊÇÒƶ¯Êó±ê¹â±êµÄʱºò£©£¬ÖƱí·û»¹ÊDZä³ÉÁ˺º×Ö£¬ÒòΪÖØ»æÍêÈ«ÒÀÀµÓÚ»º³åÇø£¬¶øÕâʱÓÃÀ´¼Ç¼×Ö·û¼¯×´Ì¬µÄ±äÁ¿²¢²»·´Ó³µ±Ç°×Ö·û¼¯×´Ì¬¡£ÎÊÌ⻹ÊÇûÓÐ×îÖÕ½â¾ö¡£ÎÒÃÇÓֻص½ÁËÆðµã¡£¡Ã( ¿´À´ÎÊÌâµÄ×îÖÕ½â¾öÊֶαØÐëÊÇ°Ñ×Ö·û¼¯µÄ״̬°éËæÿһ¸ö×Ö·û´æÔÚ»º³åÇøÖС£ÈÃÎÒÃÇÀ´Ñо¿Ò»Ï»º³åÇøµÄ½á¹¹¡£Ã¿Ò»¸ö×Ö·ûÕ¼ÓÃ16bitµÄ»º³åÇø£¬µÍ8λÊÇASCIIÖµ£¬ÍêÈ«±»ÀûÓ㬸ß8λ°üº¬Ç°¾°ÑÕÉ«ºÍ±³¾°ÑÕÉ«µÄÊôÐÔ£¬Ò²Ã»ÓжàÓàµÄ¿Õ¼ä¿ÉÒÔÀûÓá£Òò¶øÖ»ÄÜÁíÍ⿪±ÙеĻº³åÇø¡£ÎªÁ˱£³ÖÒ»ÖÂÐÔ£¬ÎÒÃǾö¶¨ÔÚÔ­À´µÄ»º³åÇøºóÃæÌí¼ÓÏàͬ´óСµÄ»º³åÇø£¬ÓÃÀ´´æ·ÅÊÇ·ñÊǺº×ÖµÄÐÅÏ¢¡£

Ò²ÐíÓжÁÕß»áÎÊ£¬ÎÒÃÇÖ»ÐèҪΪÿ¸ö×Ö·ûÌí¼ÓÒ»bitµÄÐÅÏ¢À´±êÖ¾ÊÇ·ñÊǺº×Ö¾Í×ã¹»ÁË£¬ÎªÊ²Ã´»¹Òª¿ª±ÙÓëÔ­»º³åÇø´óСÏàͬµÄË«±¶»º³åÇø£¬ÊDz»ÊÇÌ«ÀË·ÑÄØ£¿ÎÒÃÇÏÈ·ÅÏÂÕâ¸öÎÊÌ⣬ÉÔºóÔÙ×÷»Ø´ð¡£

Æäʵ£¬Èç¹ûÔÙÌí¼ÓÒ»bitÀ´±êÖ¾Êǵ±Ç°×Ö·ûÊǺº×ÖµÄ×ó°ë±ß»¹ÊÇÓÒ°ë±ßµÄ»°£¬¾Í»áʡȥɨÃèÆÁÄ»Éϵ±Ç°ÕûÐÐ×Ö·û´®µÄ¹¤×÷£¬ÕâÑùÒ»À´£¬±à³Ì»á¸ü¼òµ¥¡£µ«ÊÇÓжÁÕß»áÎÊ£¬¼´Ê¹ÊÇÕâÑù£¬Ê¹ÓÃ8bit×ܹ»ÓÃÁË°É£¿ÎªÊ²Ã´»¹ÒªÊ¹ÓÃ16bitÄØ£¿

ÎÒÃǵÄ×÷·¨ÊÇ¡ÃÓõÍ8λÀ´´æ·Åºº×ÖÁíÍâÒ»°ëµÄÄÚÂ룬Óøß8λÖеÄ2 bitÀ´´æ·ÅÉÏÃæËù½²µÄ¸¨ÖúÐÅÏ¢£¬¸ß8λµÄÊ£Óà6λ¿ÉÒÔÓÃÀ´´æ·Åºº×Ö»òÆäËü±àÂ뷽ʽ£¨ÈçBIG5»òÈÕÎÄ¡¢º«ÎÄ£©µÄÐÅÏ¢£¬´Ó¶øʹÎÒÃÇ¿ÉÒÔʵÏÖͬÆÁÏÔʾ¶àÖÖË«×Ö½ÚÓïÑÔµÄ×Ö·û¶ø²»»áÓÐÏ໥¸ÉÈÅ¡£ÁíÍ⣬ÔÚ±à³Ìʱ£¬Ë«±¶»º³åÒ²±È½ÏÈÝÒ×¼ÆËã¡£ÕâÑùÎÒÃǾͻشðÁËÈçÉϵÄÁ½¸öÎÊÌâ¡£

Æù½ñΪֹ£¬ÎÒÃÇÓÐÁËÒ»Ì׳¹µ×½â¾öºº×ÖºÍÖƱí·ûÏ໥¸ÉÈÅ¡¢°ë¸öºº×ÖµÄˢС¢ÖØ»æµÈÎÊÌâµÄ·½°¸¡£Ê£ÏµľÍÊǾßÌå±à³ÌʵÏÖµÄÎÊÌâÁË¡£

µ«ÊÇ£¬ÓÉÓÚFramebufferµÄÇý¶¯ºÜ¶à£¬ÐÞ¸Äÿһ¸öÇý¶¯µÄxxxx_putc()º¯ÊýºÍxxxx_putcs( )º¯Êý»áÊÇÒ»ÏСµÄ¹¤×÷£¬¶øÇÒ£¬¸Ä¶¯Çý¶¯³ÌÐòºó£¬Ã¿ÖÖÇý¶¯µÄ²âÊÔÒ²ÊǺÜÂé·³µÄ£¬ÓÈÆäÊǶÔÓÚÓÐÓ²¼þ¼ÓËÙµÄÏÔ¿¨£¬Ð޸ĺͲâÊÔ»á¸ü²»ÈÝÒס£ÄÇô£¬´æ²»´æÔÚÒ»ÖÖ²»ÐèÒªÐÞ¸ÄÏÔ¿¨Çý¶¯³ÌÐòµÄ·½·¨ÄØ£¿

¾­¹ýŬÁ¦£¬ÎÒÃÇ·¢ÏÖ£¬¿ÉÒÔÔÚµ÷ÓÃxxxx_putcs( )»òxxxx_putc()º¯ÊýÊä³öºº×Ö֮ǰ£¬ÐÞ¸Ävga×Ö¿âµÄÖ¸ÕëʹÆäÖ¸ÏòËùÐèÏÔʾµÄºº×ÖÔÚºº×Ö×Ö¿âÖеÄλÖ㬼´°ÑÒ»¸öºº×Öµ±³ÉÁ½¸övga ASCII×Ö·ûÊä³ö¡£Ò²¾ÍÊÇ˵£¬ÔÚÄÚºËÖдæÔÚÁ½¸ö×ֿ⣬һ¸öÊÇÔ­ÓеÄvga×Ö·û×ֿ⣬ÁíÒ»¸öÊǺº×Ö×ֿ⣬µ±ÎÒÃÇÐèÒªÊä³öºº×ÖµÄʱºò£¬¾Í°Ñvga×Ö¿âµÄÖ¸ÕëÖ¸Ïòºº×Ö×Ö¿âµÄÏàӦλÖ㬺º×ÖÊä³öÍêÖ®ºó£¬ÔٰѸÃÖ¸ÕëÖ¸Ïòvga×Ö¿âµÄÔ­ÓÐλÖá£

ÕâÑùÒ»À´£¬ÎÒÃÇÖ»ÐèÒªÐÞ¸Äfbcon.cºÍconsole.c£¬ÆäÖÐconsole.c¸ºÔðά»¤Ë«±¶»º³åÇø£¬°Ñÿһ¸ö×Ö·ûµÄÐÅÏ¢´æÈ븽¼ÓµÄ»º³åÇø£»¶øfbcon.c¸ºÔðÀûÓÃË«±¶»º³åÇøÖи½¼ÓµÄÐÅÏ¢£¬µ÷Õûvga×Ö¿âµÄÖ¸Õ룬µ÷ÓõײãµÄÏÔʾÇý¶¯³ÌÐò¡£ÕâÀﻹÓм¸¸öÐèҪעÒâµÄµØ·½¡Ã

1£® ÓÉÓÚÆÁÄ»ÖØ»æµÈÔ­Òò£¬µ÷ÓõײãÇý¶¯xxxx_putc( )ºÍxxxx_putcs()µÄµØ·½Óжദ¡£ÎÒÃÇ×÷ÁËÁ½¸öº¯Êý·Ö±ð°ü×°ÕâÁ½¸öµ÷Óã¬Íê³ÉÌæ»»×Ö¿â¡¢µ÷ÓÃxxxx_putcs( )»òxxxx_putc( )¡¢»Ö¸´×Ö¿âµÈ¹¦ÄÜ¡£

2£®ÎªÁËʵÏÖÏòÉϹöÆÁ£¨shift + pageup£©Ê±Ò²ÄÜ¿´µ½ºº×Ö£¬ÎÒÃÇÐèÒª×÷ÁíÍâµÄÐ޸ġ£

Linux ÔÚÉè¼ÆÐéÄâÖն˵Äʱºò£¬ÌṩÁ˻ع˱»¾í³öÆÁÄ»ÒÔÍâµÄÐÅÏ¢µÄ¹¦ÄÜ£¬Õâ¾ÍÊÇÓÃÈȼüÀ´ÏòÉϹöÆÁ£¨shift + pageup£©¡£µ±Ç°±»Ê¹ÓõÄÐéÄâÖÕ¶ËÓµÓÐÒ»¸ö¹«¹²µÄ»º³åÇø£¨soft back£©£¬ ÓÃÀ´´æ·Å±»¹ö³öÆÁÄ»ÒÔÍâµÄÐÅÏ¢¡£µ±Çл»ÐéÄâÖն˵Äʱºò£¬¹«¹²»º³åÇøµÄÄÚÈݻᱻÇå³ý¶ø±»ÐµÄÐéÄâÖÕ¶ËʹÓá£ÏòÉϹöÆÁµÄʱºò£¬ÏÔʾµÄÊǹ«¹²»º³åÇøÖеÄÄÚÈÝ¡£Òò ´Ë£¬Èç¹ûÎÒÃÇÏëÔÚÏòÉϹöÆÁµÄʱºò¿´µ½ºº×Ö£¬¹«¹²»º³åÇøÒ²±ØÐë¼Ó±¶£¬ÒÔÈ·±£Ã»ÓÐÐÅÏ¢¶ªÊ§¡£µ±¹ö³öÆÁÄ»µÄÐÅÏ¢Ïò¹«¹²»º³åÇøÌîдµÄʱºò£¬±ØÐë°ÑÏàÓ¦µÄ¸½¼ÓÐÅÏ¢Ò² Ìîд½ø¹«¹²»º³åÇøµÄ¸½¼ÓÇøÓò¡£Õâ¾ÍÒªÇófbcon.c±ØÐ붮µÃÀûÓù«¹²»º³åÇøµÄ¸½¼ÓÐÅÏ¢¡£

µ±È»£¬ÓÐÁíÍâÒ»ÖÖ͵ÀÁµÄ·½·¨£¬ÄǾÍÊDz»ÔÊÐíÓû§ÏòÉϹöÆÁ£¬´Ó¶ø±ÜÃâ¶Ô¹«Çø»º³åÇøµÄ´¦Àí¡£

3.°Ñ²»Í¬µÄ±àÂ뷽ʽ£¨GB¡¢BIG5¡¢ÈÕÎĺͺ«ÎÄ£©Ð´³É²»Í¬µÄmodule£¬ÒÔʵÏÖ¶¯Ì¬¼ÓÔØ£¬´Ó¶øʹµÃÀ©Õ¹ÐµıàÂ뷽ʽ²»ÐèÒªÖØбàÒëºËÐÄ¡£

²âÊÔ

±¾ÎÄʵÏÖµÄKernel PatchÎļþ£¨patch.kernel.chinese£©¿ÉÒÔ´Óhttp://www.turbolinux.com.cnÏÂÔØ¡£Cd /usr/src/£¨¸ÃĿ¼ÏÂÓ¦ÓÐLinuxºËÐÄÔ´³ÌÐòËùÔÚµÄĿ¼linux/£© patch -p0 -b < patch.kernel.chinese make menuconfig ÇëÑ¡ÔñConsole driversÑ¡ÏîÖеÄ

¡²*¡³ Double Byte Character Display Support(EXPERIMENTAL)

¡²*¡³ Double Byte GB encode (module only)

¡²*¡³ VESA VGA graphics console

<*> Virtual Frame Buffer support (ONLY FOR TESTING!)

<*> 8 bpp packed pixels support

<*> 16 bpp packed pixels support

<*> VGA characters/attributes support

¡²*¡³ Select compiled-in fonts

¡²*¡³VGA 8x8 font

¡²*¡³VGA 8x16 font

make dep

make bzImage

make modules

make install

make modules_install

È»ºóÓÃеĺËÐÄÆô¶¯¡£

Insmod encode-gb.o





ËÄ¡¢ÆäËü

£¨Ò»£© ÉèÖÃFrameBuffer

FrameBuffer£¬¿ÉÒÔÒë×÷"Ö¡»º³å"£¬ÓÐʱ¼ò³ÆΪ fbdrv£¬»ùÓÚfbdrvµÄconsoleÒ²±»³Æ֮Ϊfbcon¡£ÕâÊÇÒ»ÖÖ¶ÀÁ¢ÓÚÓ²¼þµÄ³éÏóͼÐÎÉ豸¡£FrameBufferµÄÓŵãÔÚÓÚÆä¸ß¶ÈµÄ¿ÉÒÆÖ² ÐÔ¡¢Ò×ʹÓÃÐÔ¡¢Îȶ¨ÐÔ¡£Ê¹ÓÃLinuxÄÚºËµÄ FrameBufferÇý¶¯£¨vesafb£©£¬¿ÉÒÔÇáËÉÖ§³Öµ½1024X768X32bppÒÔÉϵķֱçÂÊ¡£¶øÇÒÄ¿Ç°¿ÉµÃµ½µÄ¾ø´ó¶àÊýlinux°æ±¾Ëù·¢ÐÐ µÄÄÚºËÖУ¬ÒѾ­Ô¤±àÒëÁËFrameBufferÖ§³Ö£¬Í¨³£²»ÐèÒªÖØбàÒëÄں˾ͿÉÒÔʹÓá£ËùÒÔFrameBufferÒ²ÊÇzhconÍƼöʹÓõÄÇý¶¯·½Ê½¡£

½øÈëFrameBuffer¿ÉÒÔ¼òµ¥µØÔÚϵͳÆô¶¯Ê±Ïòkernel´«ËÍvga=mode-numberµÄ²ÎÊýÀ´¼¤»îFrameBufferÉ豸£¬È磺
lilo:linux vga=305
½«»áÆô¶¯1024x768x8bppģʽ¡£

640x480 800x600 1024x768 1280x1024

8 bpp 769 771 773 775

16 bpp 785 788 791 794

32 bpp 786 789 792 795



£¨¶þ£© Ҫʹlinuxȱʡ½øÈëFrameBuffer£¬¿ÉÒÔÐÞ¸Ä/etc/lilo.conf£¬¼ÓÈëÒ»ÏÂÓï¾ä£º
vga=0x303
Í˳ö±à¼­£¬Ö´ÐУº
lilo -v
ÖØÐÂÆô¶¯linux£¬¿ÉÒÔʹÆä½øÈë800x600µÄ256ɫģʽ¡£
grubÒ²ÊÇÒ»Ñù£¬ÔÚgrub.confÖеÄkernelÐкóÃæдÉÏvga=xxx¾ÍÐÐÁË£¬Ò²¿ÉÒÔÓÃvga=ask£¬ÈÃϵͳÆô¶¯µÄʱºòѯÎÊÄãÓöà´óµÄ·Ö±æÂÊ

£¨¶þ£©ÎÒ±àÒëÄÚºËʱ£¬Ñ¡Ôñframebufferģʽ£¬Æô¶¯Ê±ÆÁÄ»ÉÏÓÐÒ»Æó¶ìͼƬ£¬²»ÖªÕâÊÇÈçºÎÔì³ÉµÄÕâ¸öͼƬ¿ÉÒÔÈ¥µô»ò¸Ä¶¯Âð£¿

¿ÉÒÔ½«drivers/video/fbcon.c: fbcon_setup()ÖÐif (logo) { } ´úÂëÈ¥µô¡£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 0 ÌõÆÀÂÛ