在Linux操作系统下FrameBuffer直接写屏

文章作者 100test 发表时间 2007:09:06 12:05:50
来源 100Test.Com百考试题网


因为Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,故Linux抽象出FrameBuffer这个设备来供用户态进程实现直接写屏。

在继续下面的之前,先说明几个背景知识:

FrameBuffer主要是根据VESA标准的实现的,所以只能实现最简单的功能。

由于涉及内核的问题,FrameBuffer是不允许在系统起来后修改显示模式等一系列操作。(好象很多人都想要这样干,这是不被允许的,当然如果你自己与驱动的话,是可以实现的)

对FrameBuffer的操作,会直接影响到本机的所有控制台的输出,包括XWIN的图形界面。

好,现在可以让我们开始实现直接写屏:

打开一个FrameBuffer设备

通过mmap调用把显卡的物理内存空间映射到用户空间

直接写内存。

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" */

/* its 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



 





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操作系统下aMule工具配置实用技巧
UbuntuLinux系统上安装IE浏览器的方法
配置D 辅助域名和子域名服务器
嵌入式Linux攻略ACE程序移植过程详细解析
在Linux操作系统下FrameBuffer直接写屏
剖析Linux病毒原型的工作过程和关键环节
通过Linux系统的内核观察_proc_pid_statm
系统学习嵌入式Linux几点非常实用的建议
Linux操作系统的主机名Hostname详细介绍
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛