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;
}