Subject: help with mmaping kernel memory
To: None <tech-kern@netbsd.org>
From: Bucky Katz <bucky@picovex.com>
List: tech-kern
Date: 09/02/2006 15:34:47
I've got a funky lcd device that sits on an isa bus on an evbarm board
and has a pio interface. I've written a working driver for it with
wsdisplay mode and have it supporting framebuffer mode.

Since the device has no mappable framebuffer, I've been faking that by
malloc-ing a buffer in the kernel and using an ioctl to copy the user
buffer to the kernel buffer and then write it to the lcd under pio.
This works fine.

But, I'd like to avoid the extra copy by setting up the kernel buffer
as mmapable and replacing the ioctl with one that simply tells the
driver when to copy the buffer to the device.

On one platform, the bus supports dma, so we allocate dma buffers and
the mmap works fine.  On the other platform, the bus doesn't, so the
bus driver doesn't support dma tags and I can't use dma maps.  So i
tried something roughly like

static int
dilcd_alloc_screen(void *d, const struct wsscreen_descr * b,
		   void **cp, int *xp, int *yp, long *f)
{
        ...
	scr->sc_fb = malloc(size, M_DEVBUF, M_WAITOK);
        ...
}

static paddr_t
dilcd_mmap(void * d, void * ds, off_t offset, int prot)
{
        ...
	paddr_t pa;
	pa = vtophys(((vaddr_t)screen->sc_fb)+offset);
	printf("dilcd: returning phys addr = 0x%x\n",
	       (unsigned int)pa);
	return pa;
        ...
}

Nothing complains, and the user mmap returns.  But, eventually, when
trying to write to the mmapped buffer, i segfault because only the
first 32kb are being mapped in the kernel.  (dilcd_mmap is only being
called to map that many pages.)

Could someone point me at a good example of how to do this?

Thanks,

Bucky