Go to previous topic
Go to next topic
Last Post 03 Feb 2006 10:17 AM by  peter.barada@logicpd.com
AMD Geode LX DB800 Linux framebuffer
 2 Replies
Author Messages
alberto
New Member
New Member
Posts:


--
16 Nov 2005 01:40 AM
    hello,
    i have a problem with an AMD Geode LX DB800 card when trying to activate the linux framebuffer...

    i applied a patch i've found on AMD web site to kernel 2.6.11.12 (the patch file name is Patches_Linux2.6.11_Common_02.00.0100.patch) and recompiled it.
    at first sight it seems to work, 'cos at system startup the kernel displays the penguin on the top-left corner of the screen, but if i try to test the framebuffer with the program i've found her, i have an error when it tries to mmap the device.
    i slightly modified the program, to add a perror call and the error given is: "Invalid argument".
    if i add MAP_ANONYMOUS flag, mmap returns succesfully (but, of course, nothing is displayed on the screen) so it looks like the file descriptor is not valid...

    can you give me some hints to solve this problem??
    thanks a lot!!

    #include <unistd.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <linux/fb.h>
    #include <sys/mman.h>
    #include <errno.h>
    #include <stdlib.h>

    extern int errno;

    int main() {
    int fbfd = 0;
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    long int screensize = 0;
    char *fbp = 0;
    int x = 0, y = 0;
    long int location = 0;

    // Open the file for reading and writing
    fbfd = open("/dev/fb0", O_RDWR);
    if (!fbfd) {
    printf("Error: cannot open framebuffer device.\n");
    exit(1);
    }
    printf("The framebuffer device was opened successfully.\n");

    // Get fixed screen information
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
    printf("Error reading fixed information.\n");
    switch (errno) {
    case EBADF:
    printf("Bad file descriptor.\n");
    break;
    case EFAULT:
    printf("Inaccessible memory area.\n");
    break;
    case ENOTTY:
    printf("File descriptor is not associated with a valid device.\n");
    break;
    case EINVAL:
    printf("Request not valid.\n");
    break;
    }
    exit(2);
    }

    // Get variable screen information
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
    printf("Error reading variable information.\n");
    switch (errno) {
    case EBADF:
    printf("Bad file descriptor.\n");
    break;
    case EFAULT:
    printf("Inaccessible memory area.\n");
    break;
    case ENOTTY:
    printf("File descriptor is not associated with a valid device.\n");
    break;
    case EINVAL:
    printf("Request not valid.\n");
    break;
    }
    exit(3);
    }

    printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );

    // Figure out the size of the screen in bytes
    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

    // Map the device to memory
    //fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, fbfd, 0);
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
    if ((int)fbp == -1) {
    printf("Error: failed to map framebuffer device to memory.\n");
    perror("Linux error is");
    exit(4);
    }
    printf("The framebuffer device was mapped to memory successfully.\n");

    x = 100; y = 100; // Where we are going to put the pixel

    // Figure out where in memory to put the pixel
    for ( y = 100; y < 300; y++ )
    for ( x = 100; x < 300; x++ ) {

    location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y+vinfo.yoffset) * finfo.line_length;

    if ( vinfo.bits_per_pixel == 32 ) {
    *(fbp + location) = 100; // Some blue
    *(fbp + location + 1) = 15+(x-100)/2; // A little green
    *(fbp + location + 2) = 200-(y-100)/5; // A lot of red
    *(fbp + location + 3) = 0; // No transparency
    } else { //assume 16bpp
    int b = 10;
    int g = (x-100)/6; // A little green
    int r = 31-(y-100)/16; // A lot of red
    unsigned short int t = r<<11 | g << 5 | b;
    *((unsigned short int*)(fbp + location)) = t;
    }

    }
    munmap(fbp, screensize);
    close(fbfd);
    return 0;
    }
    asoneofus@nm.ru
    New Member
    New Member
    Posts:


    --
    05 Jan 2006 05:55 AM
    You can try file interface of linux framebuffer(using /dev/fb0, file seeking and writing)
    If it works, than it seems framebuffer driver incorrectly mmaps framebuffer memory to userspace
    peter.barada@logicpd.com
    New Member
    New Member
    Posts:72


    --
    03 Feb 2006 10:17 AM
    What is the screensize that the program calculates? Perhaps the mmap call is being handed an unrealistic screensize that causes mmap to fail due to asking to mmap more memory than the video framebuffer has...


    ---