|
From: Gaster, B. <ben...@su...> - 2002-06-19 08:17:39
|
Hi Again,
I have worked out that I was not selecting a valid set of flags which
was causing the call to mmap to fail with -EINVAL, i.e, invalid
argument. The user call now looks like:
pOvl =3D mmap(0, (OW*OH) + ((OH*OW)/2), PROT_READ | PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, fd, 0);
On completion of the call the pOvl is set to the address:
0x29557000
but the problem is now that the mmap function for the overlay device is
never being called and so although pOvl seems to be a valid address it
is not the one I was expecting? I would have thought that as the file
descriptor for the overlay device is being passed into mmap then
overlay_mmap would be called by mmap and thus allow the correct address
to be mapped for the overlay surface.
Any ideas?
Ben.
-----Original Message-----
From: Gaster, Benedict=20
Sent: 18 June 2002 16:44
To: Stuart Menefy
Cc: lin...@li...
Subject: RE: [linuxsh-shmedia-dev] Mapping a PCI address into user space
Hi Stuart,
So I've had a go at implementing a simple overlay character device on
top of the FB driver which is very straightforward but does support an
implementation of mmap. However, there is a problem when I make the mmap
system call to the device.
A small section of the driver code is as follows:
...
static int overlay_mmap(struct file * file, struct vm_area_struct * vma)
{
unsigned long off, start;
u32 len;
off =3D vma->vm_pgoff << PAGE_SHIFT;
start =3D (unsigned long) kyro_dev_physical_overlay_ptr();
len =3D PAGE_ALIGN(start & ~PAGE_MASK) +=20
((ol_create.ulWidth * ol_create.ulHeight) +
((ol_create.ulWidth * ol_create.ulHeight) / 2));
start &=3D PAGE_MASK;
if ((vma->vm_end - vma->vm_start + off) > len)
{
return -EINVAL;
}
=20
off +=3D start;
vma->vm_pgoff =3D off >> PAGE_SHIFT;
/*
* Don't alter the page protection flags; we want to keep the area
* cached for better performance. This does mean that we may miss
* some updates to the screen occasionally, but process switches
* should cause the caches and buffers to be flushed often enough.
*/
if (io_remap_page_range(vma->vm_start, off,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
{
return -EAGAIN;
} =20
=20
return 0;
}=20
struct file_operations overlay_fops =3D
{
owner: THIS_MODULE,
open: overlay_open,
read: overlay_read,
write: overlay_write,
ioctl: overlay_ioctl,
release: overlay_release,
mmap: overlay_mmap,
};
and then the user code looks like:
if ((fd =3D open("/dev/overlay", O_RDWR)) =3D=3D ENOENT)
{
err_message("failed to open /dev/fb0\n");
} =20
=20
if (ioctl(fd, OVERLAY_IOCTL_STRIDE, &ovlStride) =3D=3D -EINVAL)
{
err_message("failed to get stride\n");
}
pOvl =3D mmap(0, (OW*OH) + ((OH*OW)/2), PROT_WRITE, 0, fd, 0);
where the device is called "overlay", the ioctl call is just requesting
the stride value, and the final line requesting the current over surface
to be memory mapped. If we run the user code strace outputs the
following:
/home/benedict # /myprogs/bin/strace ./yuv
execve("./yuv", ["./yuv"], [/* 5 vars */]) =3D 0
fcntl(0, F_GETFD) =3D 0
fcntl(1, F_GETFD) =3D 0
fcntl(2, F_GETFD) =3D 0
uname({sys=3D"Linux", node=3D"sunday-pci", ...}) =3D 0
semop(4784052, 0x2d, 4194303) =3D 0
SYS_199(0, 0x3fffff, 0x20413, 0x2d, 0x7bfffd99) =3D 0
semget(IPC_PRIVATE, 4194303, IPC_EXCL|0x20013|022) =3D 0
getgid() =3D 0
brk(0) =3D 0x490450
brk(0x490470) =3D 0x490470
brk(0x491000) =3D 0x491000
brk(0x492000) =3D 0x492000
getpid() =3D 13
open("/dev/overlay", O_RDWR) =3D 3
ioctl(3, 0x6f00, 0x7bfffde4) =3D 0
old_mmap(NULL, 152064, PROT_WRITE, MAP_FILE, 3, 0) =3D -1 EINVAL =
(Invalid
argument)
fstat64(1, {st_mode=3DS_IFCHR|0664, st_rdev=3Dmakedev(5, 1), ...}) =3D 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) =3D 0x29556000
ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) =3D 0
write(1, "pOvl =3D 0xffffffff\n", 18pOvl =3D 0xffffffff
) =3D 18
open("spider0.Y", O_RDONLY) =3D 4
write(1, "Filling Y-data\n", 15Filling Y-data
) =3D 15
fstat64(4, {st_mode=3DS_IFREG|0444, st_size=3D101376, ...}) =3D 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) =3D 0x29557000
read(4, "\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20"...,
4096) =3D 4096
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++
It seems to imply that the call to mmap is failing due to an invalid
argument; can you spot what might be wrong?
Ben.
-----Original Message-----
From: Stuart Menefy [mailto:stu...@st...]=20
Sent: 18 June 2002 14:05
To: Gaster, Benedict
Cc: lin...@li...
Subject: Re: [linuxsh-shmedia-dev] Mapping a PCI address into user space
Hi Ben
On Tue, 18 Jun 2002 11:05:54 +0100
ben...@su... wrote:
> Hello!
> =20
> I have modified the bitkeeper Kyro framebuffer driver to provide
> additional ioctl calls for the creation of overlay surfaces (to handle
> YUV to RGB colour conversion). Currently two calls are required for
> creation of an overlay surface and a creation of viewport (a scaling
> window mapping the overlay surface on to the RGB output) which returns
a
> pointer to the viewport surface. Currently the pointer returned can
only
> be written to in Kernel space which I assume is due to the pointer
into
> the PCI address space is mapped only in kernel space and not in user
> space.
You don't say how you're doing it, but this sounds likly.
> I presume that it is possible to map the pages to be written
by a
> particular user process but I not sure how to do this and weather it
is
> the best approach.=20
Its pretty simple. Just have a look at how the existing frame buffer
code
does it (fb_mmap).
> I suppose it would be possible to extend the framebuffer driver to
> provide an additional driver interface for overlay surfaces and thus
use
> mmap to create a memory mapped region but this seems like over kill
for
> the functionally that I'm after.
It depends what functionally you're after!
Assuming you simply want to display data from a user application
which generates YUV data, then mapping the overlay into user space is
almost certainly the easiest way to do it.
Whether you do this as a new device or an extension of the existing one
is pretty much up to you. Mapping the fb device is probably the easiest
(simply use the offset parameter to mmap to decice what to map), but is
somewhat non-standard.
A better way might to to implement a subset of Video for Linux (V4L),
which already has an API which supports overlays, allowing you to
position them, change the format, etc.=20
Stuart
--=20
Stuart Menefy
stu...@st...
STMicroelectronics Ltd ST Intranet:
mo.bri.st.com
Bristol, UK Rest of the World:
www.linuxsh.st.com
------------------------------------------------------------------------
----
Bringing you mounds of caffeinated joy
>>> http://thinkgeek.com/sf <<<
_______________________________________________
Linuxsh-shmedia-dev mailing list
Lin...@li...
https://lists.sourceforge.net/lists/listinfo/linuxsh-shmedia-dev
|