seg fault problem with MCF5485EVB running recently released 2.6.25 Linux kernel

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

seg fault problem with MCF5485EVB running recently released 2.6.25 Linux kernel

1,471 Views
jkimble
Contributor III
I'm running the latest kernel released (2.6.25) on a board that is a mod of the MCF5485EVB board (more flash and more RAM) with an Epson (S1D13A04) video chip. I had this hardware working (nano-X GUI with touchscreen, the works) with the old kernel release (2.6.10) and though the drivers for the two kernels are different they're not that different.

The driver for the device loads, the screen is initialized (I've even been able to have a logo drawn on the screen from the driver) and the frame buffer device (fb0) can be opened. However any attempt to write to a device register or the devices video memory results in a seg fault. For about a week I've been going round and round looking at the driver and trying to see where I'm going wrong. Even to the extent of going to the Linux frame buffer news group and getting some expert input.

What I see is that I can work with the registers and video memory from kernel space with no problem. However when I open the device file to work in user space writing to the device results in a seg fault. Can anyone knowledgeable about how the new kernel handles memory think of a reason that the new kernel might show this behaviour where the old kernel didn't? This is the same hardward and the same user space applications. The driver is slightly different but not by much.

I've been hung on this for days and it makes no sense to me. I've tried moving the memory around (setting the CS to another address in U-Boot) but it makes no difference in the behaviour.

I'd REALLY appreciate ANY ideas or thoughts.




Labels (1)
0 Kudos
4 Replies

481 Views
kmahan
Contributor I
Without going and digging into the kernel I'll take a guess that the memory is being mapped as supervisor-only.  So any attempt to write to it from userspace is causing an access exception.
0 Kudos

481 Views
jkimble
Contributor III

I've got a new symptom. I compiled GDB into the kernel so I could more easily examine what's what in my application space programs. In my simple test program (see below) I can step through until I get to the point that I use the mmap call. The call returns successfully but when I look at the pointer it returned I get:

 $4 = 0x80126000 <Address 0x80126000 out of bounds>

finfo and vinfo look fine. Why would I get an out of bounds memory address from mmap? I tried putting a valid address in the call to mmap (rather than 0 to let the system pick) but then the thing just crashes the OS.

Stranger and stranger.... What would cause mmap to return and invalid address?

Code:
#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <linux/fb.h>#include <sys/mman.h>#include <sys/stat.h>#include <sys/types.h>typedef unsigned char S1D_INDEX;typedef unsigned long S1D_VALUE;char *fbp;struct stat my_stat;int main(){    int i=0, fbfd, x, y, err;    long int location=0;    unsigned long reg;    unsigned short *regptr;    size_t screensize;    struct fb_var_screeninfo vinfo;    struct fb_fix_screeninfo finfo;    off_t PageOffset, PageAddress, PhysAddr;    printf ("sizeof(unsigned char): %d\n", sizeof(unsigned char));    printf ("sizeof(unsigned long): %d\n", sizeof(unsigned long));    /* Open the file for reading and writing */    fbfd = open("/dev/fb0", O_RDWR|O_NONBLOCK);    if (!fbfd)    {         printf("Error: cannot open framebuffer device.\n");         exit(1);    }    printf("The framebuffer device was opened successfully.\n");    err = fstat(fbfd, &my_stat);    printf ("mode = %o\n", my_stat.st_mode);    /* Get fixed screen information */    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo))    {         perror ("ioctl");         printf("Error reading fixed information.\n");         exit(2);    }    /* Get variable screen information */    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))    {         printf("Error reading variable information.\n");         exit(3);    }    /* Figure out the size of the screen in bytes */    screensize = (vinfo.xres * vinfo.yres * vinfo.bits_per_pixel) / 8;    printf ("vinfo.xres = %d\n", vinfo.xres);    printf ("vinfo.yres = %d\n", vinfo.yres);    printf ("vinfo.bits_per_pixel = %d\n", vinfo.bits_per_pixel);    printf ("screensize = 0x%x\n", screensize);    printf ("PageSize (getpagesize):    0x%x\n", getpagesize());    /* Map the device to memory */    fbp = mmap(0, screensize, PROT_READ|PROT_WRITE, MAP_SHARED, fbfd, 0);    if ((int)fbp == -1)    {        perror("mmap");        printf("\nError: failed to map framebuffer device to memory.\n");        exit(4);    }    printf("The framebuffer device was mapped to memory successfully.\n");    printf("Mapped to: 0x%x\n", fbp);    *(fbp + 0x10) &= 0xff7fffff;    // Enable    printf("Enable\n");    *(fbp + 0x10) |= 0x00800000;    // Clear    printf("Clear\n");    printf("Start drawing\n");    for (i=0; i < 100; i++)    {        //printf ("location: %d\n", location);        /* Where we are going to put the pixel */        //x = 100;         //y = 100;          x = i;        y = i;        /* Figure out where in memory to put the pixel */        location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                   (y+vinfo.yoffset) * finfo.line_length;        //printf ("finfo.line_length: %d\n", finfo.line_length);        //printf ("location: %d\n", location);        *(fbp + location) = 150;        /* Some blue       */        *(fbp + location + 1) = 115;     /* A little green  */        *(fbp + location + 2) = 150;    /* A lot of red    */        *(fbp + location + 3) = 0;      /* No transparency */    }    *(fbp + 0x10) &= 0xff7fffff;    // Enable    printf("Done drawing\n");    munmap(fbp, screensize);    printf("Unmapped\n");    close(fbfd);    return 0;}

 

0 Kudos

481 Views
jkimble
Contributor III

Can you give me any further suggestion?

After days of looking at this, trying a completely different driver, talking to the folks on the Linux frame buffer news group, I'm still getting nowhere. Obviously the memory is either not being allocated properly or I'm accessing it in an illegal way. The access is done from the user space program nano-X that has worked fine in the older kernel (2.6.10). That leaves the mapping that I've listed above. Again, this is also being done exactly as it was done in the previous kernel.

I'm really hitting a wall here. Any suggestions or ideas of where I might be going wrong would be very helpful.

Thanks,

0 Kudos

481 Views
jkimble
Contributor III
 
Well, maybe so but I don't know how I'm doing that. I'm allocating memory in the driver in exactly the same way I did with the 2.6.10 kernel. First doing a request_mem_region and then an ioremap. As in:
 
Code:
if (!request_mem_region(S1D_PHYSICAL_REG_ADDR,      S1D_PHYSICAL_REG_SIZE,"S1D13706 registers")){    printk(KERN_ERR "s1d13706fb: unable to reserve registers at 0x%0lx\n",           S1D_PHYSICAL_REG_ADDR);    rc = -EBUSY;    goto bail;}default_par->RegAddr = (u8 *) ioremap(S1D_PHYSICAL_REG_ADDR,                                      S1D_PHYSICAL_REG_SIZE);if (!default_par->RegAddr){    printk(KERN_ERR "s1d13706fb: unable to map registers\n");    rc = -ENOMEM;    goto bail;}

 
These calls complete successfully.
 
How would I map the memory for supervisor-only access? Maybe this is happening somewhere in the initialization I don't know about.
 
Thanks for your help.
0 Kudos