Linux向fb0写东西,Linux下FrameBuffer直接写屏

Linux下FrameBuffer直接写屏

yanqin | 2009-04-16 14:28:19    阅读:1478

db6c9df9ccb71c554faea6ec7ad19010.png发布文章

作者:hotfire [文章出自: www.phpx.com]

%A

%A 因为Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里

%A 提供的中断调用来实现直接写屏,故Linux抽象出FrameBuffer这个设备来供用户态

%A 进程实现直接写屏。

%A

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

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

%A 2、由于涉及内核的问题,FrameBuffer是不允许在系统起来后修改显示模式等一系

%A 列操作。(好象很多人都想要这样干,这是不被允许的,当然如果你自己与驱动

%A 的话,是可以实现的)

%A 3、对FrameBuffer的操作,会直接影响到本机的所有控制台的输出,包括XWIN的图

%A 形界面。

%A

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

%A 1、打开一个FrameBuffer设备

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

%A 3、直接写内存。

%A

%A 好象很简单哦~

%A fbtools.h

%A

%A 代码:

%A #ifndef _FBTOOLS_H_

%A #define _FBTOOLS_H_

%A

%A #include

%A

%A //a framebuffer device structure;

%A typedef struct fbdev{

%A int fb;

%A unsigned long fb_mem_offset;

%A unsigned long fb_mem;

%A struct fb_fix_screeninfo fb_fix;

%A struct fb_var_screeninfo fb_var;

%A char dev[20];

%A } FBDEV, *PFBDEV;

%A

%A //open & init a frame buffer

%A //to use this function,

%A //you must set FBDEV.dev=\"/dev/fb0\"

%A //or \"/dev/fbX\"

%A //it\‘s your frame buffer.

%A int fb_open(PFBDEV pFbdev);

%A

%A //close a frame buffer

%A int fb_close(PFBDEV pFbdev);

%A

%A //get display depth

%A int get_display_depth(PFBDEV pFbdev);

%A

%A

%A //full screen clear

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

%A

%A #endif

%A

%A

%A

%A fbtools.c

%A

%A 代码:

%A #include

%A #include

%A #include

%A #include

%A #include

%A #include

%A #include

%A #include

%A

%A #include \"fbtools.h\"

%A

%A #define TRUE 1

%A #define FALSE 0

%A #define MAX(x,y) ((x)>(y)?(x):(y))

%A #define MIN(x,y) ((x)

%A

%A //open & init a frame buffer

%A int fb_open(PFBDEV pFbdev)

%A {

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

%A if(pFbdev->fb < 0)

%A {

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

%A return FALSE;

%A }

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

%A {

%A printf(\"ioctl FBIOGET_VSCREENINFO\\n\");

%A return FALSE;

%A }

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

%A {

%A printf(\"ioctl FBIOGET_FSCREENINFO\\n\");

%A return FALSE;

%A }

%A

%A //map physics address to virtual address

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

%A pFbdev->fb_mem = (unsigned long int)mmap(NULL, pFbdev->fb_fix.smem_len +

%A pFbdev->fb_mem_offset,

%A PROT_READ | PROT_WRITE, MAP_SHARED, pFbdev->fb, 0);

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

%A {

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

%A pFbdev->fb_mem_offset);

%A return FALSE;

%A }

%A

%A return TRUE;

%A }

%A

%A //close frame buffer

%A int fb_close(PFBDEV pFbdev)

%A {

%A close(pFbdev->fb);

%A pFbdev->fb=-1;

%A }

%A

%A //get display depth

%A int get_display_depth(PFBDEV pFbdev);

%A {

%A if(pFbdev->fb<=0)

%A {

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

%A return FALSE;

%A }

%A return pFbdev->fb_var.bits_per_pixel;

%A }

%A

%A //full screen clear

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

%A {

%A memset(addr, c, len);

%A }

%A

%A //use by test

%A #define DEBUG

%A #ifdef DEBUG

%A main()

%A {

%A FBDEV fbdev;

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

%A strcpy(fbdev.dev, \"/dev/fb0\");

%A if(fb_open(&fbdev)==FALSE)

%A {

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

%A return;

%A }

%A

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

%A

%A fb_close(&fbdev);

%A }

%A%A%A

%A

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论

请登录...

登录后参与讨论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值