View topic - porting mmap file operation
porting mmap file operation
8 posts
• Page 1 of 1
porting mmap file operation
Hi.
I am trying to port linux device driver to QNX 6.3.
xx_control_mmap is the original linux file_operations "method". In QNX there is also mmap function used to handle an IO_MMAP messages. But the received message's structure io_mmap_t does not contain any variables holding information about number of bytes to map into the caller's address space. So, my question is how to implement this in QNX.
Thanks for the answer.
I am trying to port linux device driver to QNX 6.3.
- Code: Select all
int xx_control_mmap(struct file *filp, struct vm_area_struct *vma)
{
....
off = (vma->vm_pgoff << PAGE_SHIFT);
vsize = vma->vm_end - vma->vm_start;
....
if(off >= MMAP_OFFSET_L2_DMA) {//MMAP_OFFSET_L2_DMA==0x70000000
off -= MMAP_OFFSET_L2_DMA;
region = &card->l2;
.....
ret = remap_page_range(vma, vma->vm_start, physical, vsize, vma->vm_page_prot);
}
....
}
xx_control_mmap is the original linux file_operations "method". In QNX there is also mmap function used to handle an IO_MMAP messages. But the received message's structure io_mmap_t does not contain any variables holding information about number of bytes to map into the caller's address space. So, my question is how to implement this in QNX.
Thanks for the answer.
- miiso
- Active Member
- Posts: 12
- Joined: Tue Mar 06, 2007 2:12 pm
I think it's actually causing a remap of the client's address space. This is not possible under QNX. What you will have to is to have the device driver create a shared object that overlays the physical address you want to map into the client, and then have the client map that in itself. You will need to add a few devctls (or your own messages might be easier)
- cburgess
- QNX Master
- Posts: 209
- Joined: Tue Aug 31, 2004 8:40 pm
- Location: Ottawa
In Linux there is used file_operations structure holding pointers to functions operating on device files. If you then in user space call fread(/dev/...), OS thereafter calls appropriate function from file_operations structure, to return some output from the device to the user.
What I know in QNX there is resmgr_io_funcs_t structure, which have to be filled with almost the same operations, i.e. to handle _IO_READ message I just need to point member read from resmgr_io_funcs_t structure to appropriate function (this is also described here http://www.qnx.com/developers/docs/6.3.0/neutrino/prog/resmgr.html#HANDLING_READ_MSG).
From linux device drivers chapter 13 http://www.xml.com/ldd/chapter/book/ch13.html...
...in Linux the mmap method is part of the file_operations structure and is invoked when the mmap system call is issued. With mmap, the kernel performs a good deal of work before the actual method is invoked, and therefore the prototype of the method is quite different from that of the system call. This is unlike calls such as ioctl and poll, where the kernel does not do much before calling the method.
The system call is declared as follows (as described in the mmap(2) manual page):
mmap (caddr_t addr, size_t len, int prot, int flags, int fd,
off_t offset)
On the other hand, the file operation is declared as
int (*mmap) (struct file *filp, struct vm_area_struct *vma);
In the original Linux driver (which I am porting), is on response on mmap system call executed the code I have posted before ( int xx_control_mmap(struct file *filp, struct vm_area_struct *vma) {... ). This code is used to map hardware memory into kernels memory via remap_page_range function.
Shouldn't I use _IO_MMAP() callouts to do this in QNX???? And if so, how to get number of bytes to be mapped???
Thanks a lot.
Michal
What I know in QNX there is resmgr_io_funcs_t structure, which have to be filled with almost the same operations, i.e. to handle _IO_READ message I just need to point member read from resmgr_io_funcs_t structure to appropriate function (this is also described here http://www.qnx.com/developers/docs/6.3.0/neutrino/prog/resmgr.html#HANDLING_READ_MSG).
From linux device drivers chapter 13 http://www.xml.com/ldd/chapter/book/ch13.html...
...in Linux the mmap method is part of the file_operations structure and is invoked when the mmap system call is issued. With mmap, the kernel performs a good deal of work before the actual method is invoked, and therefore the prototype of the method is quite different from that of the system call. This is unlike calls such as ioctl and poll, where the kernel does not do much before calling the method.
The system call is declared as follows (as described in the mmap(2) manual page):
mmap (caddr_t addr, size_t len, int prot, int flags, int fd,
off_t offset)
On the other hand, the file operation is declared as
int (*mmap) (struct file *filp, struct vm_area_struct *vma);
In the original Linux driver (which I am porting), is on response on mmap system call executed the code I have posted before ( int xx_control_mmap(struct file *filp, struct vm_area_struct *vma) {... ). This code is used to map hardware memory into kernels memory via remap_page_range function.
Shouldn't I use _IO_MMAP() callouts to do this in QNX???? And if so, how to get number of bytes to be mapped???
Thanks a lot.
Michal
- miiso
- Active Member
- Posts: 12
- Joined: Tue Mar 06, 2007 2:12 pm
It's not mapping the physical into kernel memory, it's mapping it into the user's memory. This is not possible with QNX6. An _IO_MMAP callout is essentially a special case of _IO_DUP and is actually received from the kernel, when the user did a mmap. The kernel will subsequently _IO_READ in the contents of the file as the user code generates page faults.
- cburgess
- QNX Master
- Posts: 209
- Joined: Tue Aug 31, 2004 8:40 pm
- Location: Ottawa
we did map physical memory into process space at least, there should be similar possible i guess.
this is for custom pci device, may this help you a bit.
pciInfo.Class = 0x42042 // Your Device Class
pciInfo.DeviceId = ........ // Your device id
pci_attach_device ( NULL, PCI_INIT_ALL | PCI_SHARE | PCI_SEARCH_CLASS, i, &pciInfo ) ;
pciInfo.BaseAddressSize[i] holds the size, as
pciInfo.CpuBaseAddress[i] holds the physptr
memptr = (off_t) mmap (NULL, (size_t) memsize , PROT_READ | PROT_WRITE, MAP_SHARED | MAP_PHYS, NOFD, physptr);
(Mark this is not complete code, just 3 lines out of 100s ^^)
this is for custom pci device, may this help you a bit.
pciInfo.Class = 0x42042 // Your Device Class
pciInfo.DeviceId = ........ // Your device id
pci_attach_device ( NULL, PCI_INIT_ALL | PCI_SHARE | PCI_SEARCH_CLASS, i, &pciInfo ) ;
pciInfo.BaseAddressSize[i] holds the size, as
pciInfo.CpuBaseAddress[i] holds the physptr
memptr = (off_t) mmap (NULL, (size_t) memsize , PROT_READ | PROT_WRITE, MAP_SHARED | MAP_PHYS, NOFD, physptr);
(Mark this is not complete code, just 3 lines out of 100s ^^)
- micro
- Senior Member
- Posts: 458
- Joined: Thu Jul 22, 2004 8:41 pm
8 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 2 guests