Bug? Sparc mmap() or fbdev?

Greg Ingram (ingram@symsys.com)
Mon, 27 Dec 1999 15:18:35 -0600 (EST)


Gentlemen,

I've been fiddling with the framebuffer device and have discovered an
inconsistency in using it on different architectures. The test program
that follows opens the framebuffer device, mmap's it, sets a palette
entry, and clears the screen.

Linux/x86 (Red Hat 6.0, kernel 2.2.13) and Linux/m68k (Mac IIci, Debian
2.1, kernel 2.2.6) act as expected: the background turns red, the
foreground is erased, the program exits and a new prompt is displayed.
With Linux/Sparc (Red Hat 6.1, kernel 2.2.12-42) the foreground is never
erased. In fact, is seems I can't write _anything_ to the mmap'd buffer.

Any suggestions?

- Greg

--- cut ---

/*
* fbtest.c
*
* build: gcc fbtest.c -o fbtest
*/

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

int init(void);
void clear(void);
int setrgb(int, int, int, int);

unsigned char *vmem;
int fd = -1;
int buffer_size;

static u_int16_t red[256], blue[256], green[256], transp[256];

static struct fb_cmap pal;

int init(void)
{
struct fb_var_screeninfo info;

if ((fd = open("/dev/fb0", O_RDWR)) == -1)
{
fprintf(stderr, "cannot open framebuffer device (%s)\n",
strerror(errno));
return -1;
}

if (ioctl(fd, FBIOGET_VSCREENINFO, &info))
{
fprintf(stderr, "ioctl failed on framebuffer device (%s)\n",
strerror(errno));
close(fd);
return -1;
}

/* we're only going to try 8-bit pixels: */

if (info.bits_per_pixel == 8)
buffer_size = info.xres * info.yres;
else
{
fprintf(stderr, "we don't do % bits per pixel mode\n",
info.bits_per_pixel);
close(fd);
return -1;
}

if ((vmem = mmap(NULL, buffer_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0)) == MAP_FAILED)
{
fprintf(stderr, "cannot mmap() framebuffer device (%s)\n",
strerror(errno));
close(fd);
return -1;
}

pal.start = 0;
pal.len = 256;
pal.red = red;
pal.green = green;
pal.blue = blue;
pal.transp = transp;

if (ioctl(fd, FBIOGETCMAP, &pal))
{
fprintf(stderr, "couldn't get cmap\n");
close(fd);
return -1;
}

return 0;
}

void clear(void)
{
memset(vmem, 0, buffer_size);
}

int setrgb(int n, int r, int g, int b)
{
pal.red[n] = r << 8;
pal.green[n] = g << 8;
pal.blue[n] = b << 8;
pal.transp[n] = 0;

return ioctl(fd, FBIOPUTCMAP, &pal);
}

int main(int argc, char **argv)
{
if (!init())
{
setrgb(0, 255, 0, 0);
clear();
}

return 0;
}

--- cut ---

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/