On Tue, Aug 09, 2011 at 11:29:51PM -0700, Eric Camachat wrote:
> Hi,
>
> I have a problem to map kernel memory to userspace via /dev/mem.
> The mmap() succeeded, but when I try to access it, the program will
> hang forever (until press ctrl-c to terminate it).
>
> # memtest-user
> memtest_vma_open: virt 0x7fbc90085000, phys 0x3eee8000
> paddr = 0x3eee8000
> mem = 0x7fbc90089000
> map = 0x7fbc90085000
> map[0]= 4c4c4c4c
> map[1]= 4c4c4c4c
> *** Hang here, it cannot (finish) access the memory mapped via /dev/mem ***
>
> My test source below, and it runs properly on HVM, VirtualBox, QEM and
> physical machines.
> What mistake I did?
>
> My kernel module look like this:
> =================================================================================
[...snip...]
> memtest_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
> unsigned long arg)
> {
> int ret = -ENOIOCTLCMD;
> phys_addr_t *paddr;
> unsigned long *vaddr;
> uint32_t *size;
>
> switch(cmd) {
> case MEMTEST_DMA_SIZE:
> size = (uint32_t*)arg;
> *size = _size;
Though your output shows that this assignment works, shouldn't this
kind of direct assignment across kernel space and user land be
avoided? It is bad practice to do direct assignment I think.
copy_{from,to}_user should do the job.
> ret = 0;
> break;
> case MEMTEST_DMA_PADDR:
> paddr = (phys_addr_t*)arg;
> *paddr = _pbase;
> ret = 0;
> break;
> case MEMTEST_DMA_VADDR:
> vaddr = (unsigned long*)arg;
> *vaddr = _vbase;
> ret = 0;
> break;
> }
> return ret;
> }
>
>
[...snip...]
> static struct file_operations memtest_fops = {
> .owner = THIS_MODULE,
> .llseek = no_llseek,
> .ioctl = memtest_ioctl,
My kernel doesn't have field called 'ioctl' in file_operations.
So which kernel do you use? 2.6.18? I don't have old kernel at the
moment so I can't help you much...
> .mmap = memtest_mmap,
> };
>
>
[...snip...]
> static void __exit memtest_exit(void)
> {
> if (_vbase != 0)
> free_page(_vbase);
I suppose you should use free_pages here, since you use
__get_free_pages when allocating.
> unregister_chrdev(MEMTEST_MAJOR, MEMTEST_NAME);
> }
>
>
> MODULE_LICENSE("GPL");
>
> module_init(memtest_init);
> module_exit(memtest_exit);
> =================================================================================
>
> Here is my user program:
>
> =================================================================================
>
[...snip...]
> if (map)
> {
> printf("map[0]= %x\n", map[0]);
> printf("map[1]= %x\n", map[1]);
This confuses me. You did write different values in _vbase[0],
_vbase[1]. But the output '4C4C4C4C' shows that the value is 'L'.
I just skimmed the output and the code. I don't run your code since I
don't have a suitible environment at the moment...
Wei.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|