Framebuffer的配置及应用——先转载留着,以后一定要弄懂
# apt-get install fbset 下載完畢后,配置文件/etc/fb.modes隨之產生。
比較簡單的作法是用萬能的vesafb,如果它被編譯進了內核,如:
Device Drivers -> Graphics support ->
- VESA VGA graphics support
那么在grub內核引導那一行的后面加上vga=791 它的含義是VESA framebuffer console @ 1024x768x64k,進入系統后可以直接使用framebuffer,看一下這種情況下的各項數據:
# fbset -s
mode "1024x768-76"
? ? # D: 78.653 MHz, H: 59.949 kHz, V: 75.694 Hz
? ? geometry 1024 768 1024 768 16
? ? timings 12714 128 32 16 4 128 4
? ? rgba 5/11,6/5,5/0,0/0
endmode
用具體顯卡的framebuffer驅動是另一種選擇,拿Nvidia顯卡為例,Nvidia顯卡的xorg驅動模塊與其framebuffer的驅動模塊是互相排斥的,如果要用一個就必須清除另一個:
# rmmod nvidia
裝載nvidia的framebuffer驅動:
# modprobe nvidiafb
裝載成功的時候,會產生/dev/fb0設備,console屏幕上的字體會有變化。
看一下當前的配置:
# fbset -s
mode "1024x768-85"
? ? # D: 94.500 MHz, H: 68.677 kHz, V: 84.997 Hz
? ? geometry 1024 768 1024 32767 8
? ? timings 10582 208 48 36 1 96 3
? ? hsync high
? ? vsync high
? ? accel true
? ? rgba 8/0,8/0,8/0,0/0
endmode
需要改變一下geometry及色深:
# fbset -g 1024 768 1024 768 32
# fbset -s
mode "1024x768-85"
? ? # D: 94.500 MHz, H: 68.677 kHz, V: 84.997 Hz
? ? geometry 1024 768 1024 768 32
? ? timings 10582 208 48 36 1 96 3
? ? hsync high
? ? vsync high
? ? accel true
? ? rgba 8/16,8/8,8/0,8/24
endmode
我們把它與使用VESA ramebuffer后的數據比較一下,顯然,根據具體的顯卡來驅動framebuffer可以在顏色上達到最佳值,好,現在我們在console下面能夠作的事情:
一、視頻播放,可以用mplayer 或者 fbxine:
# mplayer -vo fbdev -vf scale=1024:768 video_file.avi
-vo fbdev 是告訴mplayer用framebuffer作視頻驅動.
-vf scale=1024:768 是全屏的方法,可按屏幕的具體情況作調整
用fbxine的話需要下載:
# apt-get install xine-console
二、圖片文件與pdf文件瀏覽:
# apt-get install fbi
用這個軟件包里的fbi可以瀏覽圖片,fbgs可以觀看pdf文件:
# fbi -a *jpg
# fbgs -c *pdf
三、中文顯示:
# apt-get install jfbterm
# jfbterm
中文顯示的效果完美。
文章出處:飛諾網(http://www.diybl.com/course/6_system/linux/Linuxjs/2008721/133651.html)
------------------------------------------------------------------------
在內核Documentation/fb/vesafb.txt文件中,有如下vesa-framebuffer的說明
Switching modes is done using the vga=... boot parameter. Read
Documentation/svga.txt for details.
You should compile in both vgacon (for text mode) and vesafb (for
graphics mode). Which of them takes over the console depends on
whenever the specified mode is text or graphics.
The graphic modes are NOT in the list which you get if you boot with
vga=ask and hit return. The mode you wish to use is derived from the
VESA mode number. Here are those VESA mode numbers:
| 640x480 800x600 1024x768 1280x1024
----+-------------------------------------
256 | 0x101 0x103 0x105 0x107 8位色
32k | 0x110 0x113 0x116 0x119 15位色
64k | 0x111 0x114 0x117 0x11A 16位色
16M | 0x112 0x115 0x118 0x11B 24位色
The video mode number of the Linux kernel is the VESA mode number plus
0x200.
Linux_kernel_mode_number = VESA_mode_number + 0x200
So the table for the Kernel mode numbers are:
| 640x480 800x600 1024x768 1280x1024
----+-------------------------------------
256 | 0x301 0x303 0x305 0x307 8位色
32k | 0x310 0x313 0x316 0x319 15位色
64k | 0x311 0x314 0x317 0x31A 16位色
16M | 0x312 0x315 0x318 0x31B 24位色
To enable one of those modes you have to specify "vga=ask" in the
lilo.conf file and rerun LILO. Then you can type in the desired
mode at the "vga=ask" prompt. For example if you like to use?
1024x768x256 colors you have to say "305" at this prompt.
If this does not work, this might be because your BIOS does not support
linear framebuffers or because it does not support this mode at all.
Even if your board does, it might be the BIOS which does not. VESA BIOS
Extensions v2.0 are required, 1.2 is NOT sufficient. You will get a
"bad mode number" message if something goes wrong.
1. Note: LILO cannot handle hex, for booting directly with?
"vga=mode-number" you have to transform the numbers to decimal.
2. Note: Some newer versions of LILO appear to work with those hex values,
if you set the 0x in front of the numbers.
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/songbohr/archive/2010/03/25/5415637.aspx -
這兩天拾起以前做過的Framebuffer,不相同的是以前在嵌入式上做的,現在在自己電腦上Debian上進行測試,不過都類似罷了,嵌入式里要初始化很多東西。下面具體列一下步驟。至于Framebuffer的原理,就我的理解是比較簡單的,無非往mmap好的fb上填寫顯示數據罷了,不對這些數據進行處理,FrameBuffer?只是一個提供顯示內存和顯示芯片寄存器從物理內存映射到進程地址空間中的設備,它需要真正的顯卡驅動的支持。在這次測試中,我用了默認就安裝的vesafb,好像又被稱為萬能Fb驅動。
?
1、? ?首先在系統Grub啟動時按e進入命令啟動行的編輯模式,改為:kernel /boot/vmlinuz-2.6.18-5-686 root=/dev/sda6 ro vga=791(vga=791表示fb用1024 * 768 * 16bpp,其他模式的參數可以上網查查);
?
2、? ?進入系統的命令行模式,編譯fb測試例子:gcc fb_test.c;
?
3、? ?允許測試例子:sudo ./a.out >> fb.txt(必須要用超級用戶權限,>>將屏幕打印寫到fb.txt中),效果如下:
?
打印如下:
?
?
Fixed screen info:
? ? id:?VESA VGA
? ? smem_start:?0xf0000000
? ? smem_len:?3145728
? ??type:?0
? ? type_aux:?0
? ? visual:?2
? ? xpanstep:?0
? ? ypanstep:?0
? ? ywrapstep:?0
? ? line_length:?2048
? ? mmio_start:?0x0
? ? mmio_len:?0
? ? accel:?0
Variable screen info:
? ? xres:?1024
? ? yres:?768
? ? xres_virtual:?1024
? ? yres_virtual:?768
? ? yoffset:?0
? ? xoffset:?0
? ? bits_per_pixel:?16
? ? grayscale:?0
? ? red:?offset:?11,?length:?5,?msb_right:?0
? ? green:?offset:?5,?length:?6,?msb_right:?0
? ? blue:?offset:?0,?length:?5,?msb_right:?0
? ? transp:?offset:?0,?length:?0,?msb_right:?0
? ? nonstd:?0
? ? activate:?0
? ? height:?-1
? ??width:?-1
? ? accel_flags:?0x0
? ? pixclock:?12714
? ? left_margin:?128
? ? right_margin:?32
? ? upper_margin:?16
? ? lower_margin:?4
? ? hsync_len:?128
? ? vsync_len:?4
? ? sync:?0
? ? vmode:?0
Frame Buffer Performance?test...
? ?? ???Average:?2508 usecs
? ?? ???Bandwidth:?1196.172 MByte/Sec
? ?? ???Max.?FPS:?398.724 fps?
?
4、還可以通過fb在命令行模式下看視頻,如:sudo?mplayer –vo fbdev ./air_nessesity.mpg。
- #include <stdlib.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <linux/fb.h>
- #include <linux/kd.h>
- #include <sys/mman.h>
- #include <sys/ioctl.h>
- #include <sys/time.h>
- #include <string.h>
- #include <errno.h>
- struct fb_var_screeninfo vinfo;
- struct fb_fix_screeninfo finfo;
- char *frameBuffer = 0;
- //打印fb驅動中fix結構信息,注:在fb驅動加載后,fix結構不可被修改。
- void
- printFixedInfo ()
- {
- ? ? printf ("Fixed screen info:\n"
- ? ?? ?? ?? ?"\tid: %s\n"
- ? ?? ?? ?? ?"\tsmem_start: 0x%lx\n"
- ? ?? ?? ?? ?"\tsmem_len: %d\n"
- ? ?? ?? ?? ?"\ttype: %d\n"
- ? ?? ?? ?? ?"\ttype_aux: %d\n"
- ? ?? ?? ?? ?"\tvisual: %d\n"
- ? ?? ?? ?? ?"\txpanstep: %d\n"
- ? ?? ?? ?? ?"\typanstep: %d\n"
- ? ?? ?? ?? ?"\tywrapstep: %d\n"
- ? ?? ?? ?? ?"\tline_length: %d\n"
- ? ?? ?? ?? ?"\tmmio_start: 0x%lx\n"
- ? ?? ?? ?? ?"\tmmio_len: %d\n"
- ? ?? ?? ?? ?"\taccel: %d\n"
- ? ?? ?? ?? ?"\n",
- ? ?? ?? ?? ?finfo.id, finfo.smem_start, finfo.smem_len, finfo.type,
- ? ?? ?? ?? ?finfo.type_aux, finfo.visual, finfo.xpanstep, finfo.ypanstep,
- ? ?? ?? ?? ?finfo.ywrapstep, finfo.line_length, finfo.mmio_start,
- ? ?? ?? ?? ?finfo.mmio_len, finfo.accel);
- }
- //打印fb驅動中var結構信息,注:fb驅動加載后,var結構可根據實際需要被重置
- void
- printVariableInfo ()
- {
- ? ? printf ("Variable screen info:\n"
- ? ?? ?? ?? ?"\txres: %d\n"
- ? ?? ?? ?? ?"\tyres: %d\n"
- ? ?? ?? ?? ?"\txres_virtual: %d\n"
- ? ?? ?? ?? ?"\tyres_virtual: %d\n"
- ? ?? ?? ?? ?"\tyoffset: %d\n"
- ? ?? ?? ?? ?"\txoffset: %d\n"
- ? ?? ?? ?? ?"\tbits_per_pixel: %d\n"
- ? ?? ?? ?? ?"\tgrayscale: %d\n"
- ? ?? ?? ?? ?"\tred: offset: %2d, length: %2d, msb_right: %2d\n"
- ? ?? ?? ?? ?"\tgreen: offset: %2d, length: %2d, msb_right: %2d\n"
- ? ?? ?? ?? ?"\tblue: offset: %2d, length: %2d, msb_right: %2d\n"
- ? ?? ?? ?? ?"\ttransp: offset: %2d, length: %2d, msb_right: %2d\n"
- ? ?? ?? ?? ?"\tnonstd: %d\n"
- ? ?? ?? ?? ?"\tactivate: %d\n"
- ? ?? ?? ?? ?"\theight: %d\n"
- ? ?? ?? ?? ?"\twidth: %d\n"
- ? ?? ?? ?? ?"\taccel_flags: 0x%x\n"
- ? ?? ?? ?? ?"\tpixclock: %d\n"
- ? ?? ?? ?? ?"\tleft_margin: %d\n"
- ? ?? ?? ?? ?"\tright_margin: %d\n"
- ? ?? ?? ?? ?"\tupper_margin: %d\n"
- ? ?? ?? ?? ?"\tlower_margin: %d\n"
- ? ?? ?? ?? ?"\thsync_len: %d\n"
- ? ?? ?? ?? ?"\tvsync_len: %d\n"
- ? ?? ?? ?? ?"\tsync: %d\n"
- ? ?? ?? ?? ?"\tvmode: %d\n"
- ? ?? ?? ?? ?"\n",
- ? ?? ?? ?? ?vinfo.xres, vinfo.yres, vinfo.xres_virtual, vinfo.yres_virtual,
- ? ?? ?? ?? ?vinfo.xoffset, vinfo.yoffset, vinfo.bits_per_pixel,
- ? ?? ?? ?? ?vinfo.grayscale, vinfo.red.offset, vinfo.red.length,
- ? ?? ?? ?? ?vinfo.red.msb_right, vinfo.green.offset, vinfo.green.length,
- ? ?? ?? ?? ?vinfo.green.msb_right, vinfo.blue.offset, vinfo.blue.length,
- ? ?? ?? ?? ?vinfo.blue.msb_right, vinfo.transp.offset, vinfo.transp.length,
- ? ?? ?? ?? ?vinfo.transp.msb_right, vinfo.nonstd, vinfo.activate,
- ? ?? ?? ?? ?vinfo.height, vinfo.width, vinfo.accel_flags, vinfo.pixclock,
- ? ?? ?? ?? ?vinfo.left_margin, vinfo.right_margin, vinfo.upper_margin,
- ? ?? ?? ?? ?vinfo.lower_margin, vinfo.hsync_len, vinfo.vsync_len,
- ? ?? ?? ?? ?vinfo.sync, vinfo.vmode);
- }
- //畫大小為width*height的同色矩陣,8alpha+8reds+8greens+8blues
- void
- drawRect_rgb32 (int x0, int y0, int width, int height, int color)
- {
- ? ? const int bytesPerPixel = 4;
- ? ? const int stride = finfo.line_length / bytesPerPixel;
- ? ? int *dest = (int *) (frameBuffer)
- ? ?? ???+ (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
- ? ? int x, y;
- ? ? for (y = 0; y < height; ++y)
- ? ? {
- ? ?? ???for (x = 0; x < width; ++x)
- ? ?? ???{
- ? ?? ?? ?? ?dest[x] = color;
- ? ?? ???}
- ? ?? ???dest += stride;
- ? ? }
- }
- //畫大小為width*height的同色矩陣,5reds+6greens+5blues
- void
- drawRect_rgb16 (int x0, int y0, int width, int height, int color)
- {
- ? ? const int bytesPerPixel = 2;
- ? ? const int stride = finfo.line_length / bytesPerPixel;
- ? ? const int red = (color & 0xff0000) >> (16 + 3);
- ? ? const int green = (color & 0xff00) >> (8 + 2);
- ? ? const int blue = (color & 0xff) >> 3;
- ? ? const short color16 = blue | (green << 5) | (red << (5 + 6));
- ? ? short *dest = (short *) (frameBuffer)
- ? ?? ???+ (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
- ? ? int x, y;
- ? ? for (y = 0; y < height; ++y)
- ? ? {
- ? ?? ???for (x = 0; x < width; ++x)
- ? ?? ???{
- ? ?? ?? ?? ?dest[x] = color16;
- ? ?? ???}
- ? ?? ???dest += stride;
- ? ? }
- }
- //畫大小為width*height的同色矩陣,5reds+5greens+5blues
- void
- drawRect_rgb15 (int x0, int y0, int width, int height, int color)
- {
- ? ? const int bytesPerPixel = 2;
- ? ? const int stride = finfo.line_length / bytesPerPixel;
- ? ? const int red = (color & 0xff0000) >> (16 + 3);
- ? ? const int green = (color & 0xff00) >> (8 + 3);
- ? ? const int blue = (color & 0xff) >> 3;
- ? ? const short color15 = blue | (green << 5) | (red << (5 + 5)) | 0x8000;
- ? ? short *dest = (short *) (frameBuffer)
- ? ?? ???+ (y0 + vinfo.yoffset) * stride + (x0 + vinfo.xoffset);
- ? ? int x, y;
- ? ? for (y = 0; y < height; ++y)
- ? ? {
- ? ?? ???for (x = 0; x < width; ++x)
- ? ?? ???{
- ? ?? ?? ?? ?dest[x] = color15;
- ? ?? ???}
- ? ?? ???dest += stride;
- ? ? }
- }
- void
- drawRect (int x0, int y0, int width, int height, int color)
- {
- ? ? switch (vinfo.bits_per_pixel)
- ? ? {
- ? ? case 32:
- ? ?? ???drawRect_rgb32 (x0, y0, width, height, color);
- ? ?? ???break;
- ? ? case 16:
- ? ?? ???drawRect_rgb16 (x0, y0, width, height, color);
- ? ?? ???break;
- ? ? case 15:
- ? ?? ???drawRect_rgb15 (x0, y0, width, height, color);
- ? ?? ???break;
- ? ? default:
- ? ?? ???printf ("Warning: drawRect() not implemented for color depth %i\n",
- ? ?? ?? ?? ?? ? vinfo.bits_per_pixel);
- ? ?? ???break;
- ? ? }
- }
- #define PERFORMANCE_RUN_COUNT 5
- void
- performSpeedTest (void *fb, int fbSize)
- {
- ? ? int i, j, run;
- ? ? struct timeval startTime, endTime;
- ? ? unsigned long long results[PERFORMANCE_RUN_COUNT];
- ? ? unsigned long long average;
- ? ? unsigned int *testImage;
- ? ? unsigned int randData[17] = {
- ? ?? ???0x3A428472, 0x724B84D3, 0x26B898AB, 0x7D980E3C, 0x5345A084,
- ? ?? ???0x6779B66B, 0x791EE4B4, 0x6E8EE3CC, 0x63AF504A, 0x18A21B33,
- ? ?? ???0x0E26EB73, 0x022F708E, 0x1740F3B0, 0x7E2C699D, 0x0E8A570B,
- ? ?? ???0x5F2C22FB, 0x6A742130
- ? ? };
- ? ? printf ("Frame Buffer Performance test...\n");
- ? ? for (run = 0; run < PERFORMANCE_RUN_COUNT; ++run)
- ? ? {
- ? ?? ???/* Generate test image with random(ish) data: */
- ? ?? ???testImage = (unsigned int *) malloc (fbSize);
- ? ?? ???j = run;
- ? ?? ???for (i = 0; i < (int) (fbSize / sizeof (int)); ++i)
- ? ?? ???{
- ? ?? ?? ?? ?testImage[i] = randData[j];
- ? ?? ?? ?? ?j++;
- ? ?? ?? ?? ?if (j >= 17)
- ? ?? ?? ?? ?? ? j = 0;
- ? ?? ???}
- ? ?? ???gettimeofday (&startTime, NULL);
- ? ?? ???memcpy (fb, testImage, fbSize);
- ? ?? ???gettimeofday (&endTime, NULL);
- ? ?? ???long secsDiff = endTime.tv_sec - startTime.tv_sec;
- ? ?? ???results[run] =
- ? ?? ?? ?? ?secsDiff * 1000000 + (endTime.tv_usec - startTime.tv_usec);
- ? ?? ???free (testImage);
- ? ? }
- ? ? average = 0;
- ? ? for (i = 0; i < PERFORMANCE_RUN_COUNT; ++i)
- ? ?? ???average += results[i];
- ? ? average = average / PERFORMANCE_RUN_COUNT;
- ? ? printf (" Average: %llu usecs\n", average);
- ? ? printf (" Bandwidth: %.03f MByte/Sec\n",
- ? ?? ?? ?? ?(fbSize / 1048576.0) / ((double) average / 1000000.0));
- ? ? printf (" Max. FPS: %.03f fps\n\n",
- ? ?? ?? ?? ?1000000.0 / (double) average);
- ? ? /* Clear the framebuffer back to black again: */
- ? ? memset (fb, 0, fbSize);
- }
- int
- main (int argc, char **argv)
- {
- ? ? const char *devfile = "/dev/fb0";
- ? ? long int screensize = 0;
- ? ? int fbFd = 0;
- ? ? /* Open the file for reading and writing */
- ? ? fbFd = open (devfile, O_RDWR);
- ? ? if (fbFd == -1)
- ? ? {
- ? ?? ???perror ("Error: cannot open framebuffer device");
- ? ?? ???exit (1);
- ? ? }
- ? ? //獲取finfo信息并顯示
- ? ? if (ioctl (fbFd, FBIOGET_FSCREENINFO, &finfo) == -1)
- ? ? {
- ? ?? ???perror ("Error reading fixed information");
- ? ?? ???exit (2);
- ? ? }
- ? ? printFixedInfo ();
- ? ? //獲取vinfo信息并顯示
- ? ? if (ioctl (fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1)
- ? ? {
- ? ?? ???perror ("Error reading variable information");
- ? ?? ???exit (3);
- ? ? }
- ? ? printVariableInfo ();
- ? ? /* Figure out the size of the screen in bytes */
- ? ? screensize = finfo.smem_len;
- ? ? /* Map the device to memory */
- ? ? frameBuffer =
- ? ?? ???(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
- ? ?? ?? ?? ?? ?? ?? ?fbFd, 0);
- ? ? if (frameBuffer == MAP_FAILED)
- ? ? {
- ? ?? ???perror ("Error: Failed to map framebuffer device to memory");
- ? ?? ???exit (4);
- ? ? }
- ? ? //測試virt fb的性能
- ? ? performSpeedTest (frameBuffer, screensize);
- ? ? printf ("Will draw 3 rectangles on the screen,\n"
- ? ?? ?? ?? ?"they should be colored red, green and blue (in that order).\n");
- ? ? drawRect (vinfo.xres / 8, vinfo.yres / 8,
- ? ?? ?? ?? ? vinfo.xres / 4, vinfo.yres / 4, 0xffff0000);
- ? ? drawRect (vinfo.xres * 3 / 8, vinfo.yres * 3 / 8,
- ? ?? ?? ?? ? vinfo.xres / 4, vinfo.yres / 4, 0xff00ff00);
- ? ? drawRect (vinfo.xres * 5 / 8, vinfo.yres * 5 / 8,
- ? ?? ?? ?? ? vinfo.xres / 4, vinfo.yres / 4, 0xff0000ff);
- ? ? sleep (5);
- ? ? printf (" Done.\n");
- ? ? munmap (frameBuffer, screensize);? ? //解除內存映射,與mmap對應
- ? ? close (fbFd);
- ? ? return 0;
- } 復制代碼
轉載于:https://www.cnblogs.com/senior-engineer/p/6232241.html
總結
以上是生活随笔為你收集整理的Framebuffer的配置及应用——先转载留着,以后一定要弄懂的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: test 2016-12-28
- 下一篇: NYOJ 975