Linux下FrameBuffer直接写屏 WW.W_PLC※JS_C,OM-PL,C-技.术_网
WWW.PLCJS.COM——可编程控制器技术门户
因为Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里 P.L.C.技.术.网——可编程控制器技术门户
提供的中断调用来实现直接写屏,故Linux抽象出FrameBuffer这个设备来供用户态 WWW_PL※CJS_COM-PLC-技.术_网
进程实现直接写屏。 WWW.PLCJS.COM——可编程控制器技术门户
P.L.C.技.术.网——可编程控制器技术门户
在继续下面的之前,先说明几个背景知识: WW.W_PLC※JS_C,OM-PL,C-技.术_网
1、FrameBuffer主要是根据VESA标准的实现的,所以只能实现最简单的功能。 W1WW_P4LCJS_COM-PLC-技.术_网
2、由于涉及内核的问题,FrameBuffer是不允许在系统起来后修改显示模式等一系 ——可——编——程——控-制-器-技——术——门——户
列操作。(好象很多人都想要这样干,这是不被允许的,当然如果你自己与驱动 ——可——编——程——控-制-器-技——术——门——户
的话,是可以实现的) WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
3、对FrameBuffer的操作,会直接影响到本机的所有控制台的输出,包括XWIN的图 WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
形界面。 ——可——编——程——控-制-器-技——术——门——户
WWW_P※LCJS_COM-PLC-)技.术_网
好,现在可以让我们开始实现直接写屏: WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
1、打开一个FrameBuffer设备 plcjs.技.术_网
2、通过mmap调用把显卡的物理内存空间映射到用户空间 WWW_PLCJS_COM-PLC-技.术_网
3、直接写内存。 plcjs.技.术_网
WWW_P※LCJS_CO※M-PLC-技-.术_网
好象很简单哦~ WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
fbtools.h WWW_PL※CJS_COM-PLC-技.术_网
#ifndef _FBTOOLS_H_ ——可——编——程——控-制-器-技——术——门——户
#define _FBTOOLS_H_ plcjs.技.术_网
P.L.C.技.术.网——可编程控制器技术门户
#include <linux/fb.h> WWW_PLC※JS_COM-PmLC-技.术_网
WW.W_PLC※JS_C,OM-PL,C-技.术_网
//a framebuffer device structure; WWW_PLCJS_COM-PLC-技.术_网
typedef struct fbdev{ ——可——编——程——控-制-器-技——术——门——户
int fb; WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
unsigned long fb_mem_offset; WWW_PLCJS_COM-PLC-技.术_网
unsigned long fb_mem; WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
struct fb_fix_screeninfo fb_fix; WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
struct fb_var_screeninfo fb_var; WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
char dev[20]; WW.W_PLCJS_COM-PLC-技.术_网
} FBDEV, *PFBDEV; WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)
//open & init a frame buffer WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)
//to use this function, P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
//you must set FBDEV.dev="/dev/fb0" WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
//or "/dev/fbX" W1WW_P4LCJS_COM-PLC-技.术_网
//its your frame buffer. WWW_P※LCJS_CO※M-PLC-技-.术_网
int fb_open(PFBDEV pFbdev); ——可——编——程——控-制-器-技——术——门——户
WWW_PLCJS@_COM%-PLC-技.术_网
//close a frame buffer WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
int fb_close(PFBDEV pFbdev); WWW_P※LCJS_CO※M-PLC-技-.术_网
WWW_P※LCJS_COM-PLC-)技.术_网
//get display depth WW.W_PLCJS_COM-PLC-技.术_网
int get_display_depth(PFBDEV pFbdev); WWW_PL※CJS_COM-PLC-技.术_网
WWW_PL※CJS_COM-PLC-技.术_网
WWW_PL※CJS_COM-PLC-技.术_网
//full screen clear W1WW_P4LCJS_COM-PLC-技.术_网
void fb_memset(void *addr, int c, size_t len); WWW.PLCJS.COM——可编程控制器技术门户
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
#endif WWW.PLCJS.COM——可编程控制器技术门户
fbtools.c WWW_PLCJS_COM-PLC-技.术_网
#include <stdio.h> P.L.C.技.术.网——可编程控制器技术门户
#include <stdlib.h> P.L.C.技.术.网——可编程控制器技术门户
#include <fcntl.h> WW.W_PLC※JS_C,OM-PL,C-技.术_网
#include <unistd.h> WWW_PL※CJS_COM-PLC-技.术_网
#include <string.h> WWcW_PLCJS_COM-PLC-技.术_网
#include <sys/ioctl.h> WW.W_PLC※JS_C,OM-PL,C-技.术_网
#include <sys/mman.h> WWW_PLCJS_COM-PLC-技.术_网
#include <asm/page.h> P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户
WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
#include "fbtools.h" WWW_P※LCJS_COM-PLC-)技.术_网
WW.W_PLCJS_COM-PLC-技.术_网
#define TRUE 1 WW.W_PLC※JS_C,OM-PL,C-技.术_网
#define FALSE 0 WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)
#define MAX(x,y) ((x)>(y)?(x):(y)) WW.W_PLCJS_COM-PLC-技.术_网
#define MIN(x,y) ((x)<(y)?(x):(y)) WWW_PLC※JS_COM-PmLC-技.术_网
WWW_P※LCJS_COM-PLC-)技.术_网
//open & init a frame buffer WWW_P※LCJS_CO※M-PLC-技-.术_网
int fb_open(PFBDEV pFbdev) WWW.PLCJS.COM——可编程控制器技术门户
{ WWcW_PLCJS_COM-PLC-技.术_网
pFbdev->fb = open(pFbdev->dev, O_RDWR); WWW.PLCJS.COM——可编程控制器技术门户
if(pFbdev->fb < 0) WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)
{ W1WW_P4LCJS_COM-PLC-技.术_网
printf("Error opening %s: %m. Check kernel config\n", pFbdev->dev); WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
return FALSE; WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)
} WWcW_PLCJS_COM-PLC-技.术_网
if (-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var))) P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户