阅读:2529回复:9
如何将用户空间的虚地址转换成物理地址
请教各路高手:如何将用户空间的虚地址转换成物理地址!
|
|
|
沙发#
发布于:2003-03-08 21:21
顶一下!!!
大侠们最好给讲一讲物理地址,虚地址的例子!!! |
|
板凳#
发布于:2003-03-09 11:27
我现在想要的是,用SDL创建了一个overlay得到了一个虚拟地址,那怎么才能知道该虚拟地址的物理地址呢,我需要对物理地址操作!
|
|
|
地板#
发布于:2003-03-10 09:32
要是有专门的函数,象Win2K中的MmGetPhysicalAddress(),那就一切ok了!咳,得不到物理地址可愁煞人了,不知哪位高人知道,请不吝赐教!谢谢
|
|
|
地下室#
发布于:2003-03-11 21:12
我不知道你把用户空间的虚地址转换为物理地址有什么用?
一般是系统空间的逻辑地址可以转换;可以用(asm/page.h)中__pa() 和__va()这两个宏,实际上这两个宏都很简单,就是把所有的内存放到3G以上,供操作系统使用。 至于你这个问题,如果说你查询的内存地址是通过mmap进入应用程序的用户空间的话,应该也可以解决。因为我们知道在linux下程序的虚拟内存空间是由很多个vma构成的。通过mmap的vma存在用户空间的虚地址和逻辑地址的一一对应关系,而逻辑地址和实际的内存物理地址只是相差oxc0000000. 呵呵,不知道我说清楚没有? 你最好看看ldd2的13章,当然分析linux的memory management也可以。 |
|
5楼#
发布于:2003-03-12 22:21
顶一下!!!这个与CPU有关的 :( :( :(, 如果指定一CPU, 按这个CPU来讲可能容易些, 不过假设以80X86为例, 呵呵, 那是比较复杂的, 大致说一下, PROCESS DESCRIPTOR中有个FIELD:mm, 这是个指向虚地址(线性地址)的FIELD(含有vm_area_struct, 两种管理: 线性和AVL树)参考linux/sched.h 和 linux/mm.h(/LINUX SOURCE/INCLUDE), 然后每个线性地址通过MMU转化为物理地址, 比较复杂, 这里不详述, 可参考INTEL IA-32 VOLUME 3里的第3章 |
|
|
6楼#
发布于:2003-08-04 21:58
用户空间连续的虚拟地址,很可能是不连续的物理地址,据我所知是没有这种转换函数的,因为中间还牵涉到缺页问题,即使你找到了其中一页的物理地址,又有什么用呢
|
|
7楼#
发布于:2003-08-05 10:05
[quote]顶一下!!!这个与CPU有关的 :( :( :(, 如果指定一CPU, 按这个CPU来讲可能容易些, 不过假设以80X86为例, 呵呵, 那是比较复杂的, 大致说一下, PROCESS DESCRIPTOR中有个FIELD:mm, 这是个指向虚地址(线性地址)的FIELD(含有vm_area_struct, 两种管理: 线性和AVL树)参考linux/sched.h 和 linux/mm.h(/LINUX SOURCE/INCLUDE), 然后每个线性地址通过MMU转化为物理地址, 比较复杂, 这里不详述, 可参考INTEL IA-32 VOLUME 3里的第3章 [/quote] hometown:你总是推荐INTEL IA-32 VOLUME 3 ,他真有那么好吗, 我怎么从来没看过,这是不是我一些概念不清楚的原因。 |
|
|
8楼#
发布于:2003-09-15 18:53
struct page *kvirt_to_pa(unsigned long adr)
{ struct page *ret = NULL; pmd_t *pmd; pte_t *pte; pgd_t *pgd; pgd = pgd_offset_k(adr); if (!pgd_none(*pgd)) { pmd = pmd_offset(pgd, adr); if (!pmd_none(*pmd)) { pte = pte_offset(pmd, adr); if (pte_present(*pte)) { ret = pte_page(*pte); } } } return ret; } /* Useful for using vmalloc()ed memory as DMA target */ unsigned long v4l2_vmalloc_to_bus(void *virt) { struct page *page; unsigned long kva, ret; page = kvirt_to_pa((unsigned long) virt); kva = ((unsigned long)page_address(page)) | (((unsigned long) virt) & (PAGE_SIZE - 1)); ret = virt_to_bus((void *) kva); return ret; } /* Useful for a nopage handler when mmap()ing vmalloc()ed memory */ struct page *v4l2_vmalloc_to_page(void *virt) { struct page *page; page = kvirt_to_pa((unsigned long) virt); return page; } 今天无意中翻到的,希望对你有帮助。更详细的参看bttv或v4l2的驱动(2.4内核),2.5的内核好像已经有vmalloc_to_page这个东东了 |
|
9楼#
发布于:2003-10-10 10:33
好像在user mode下面是不可以直接对物理地址进行操作的。
如果你是想从user mode下的程序的地址直接access到实际的物理地址,我觉得以下几种办法可以实现 1。在user mode下使用mmap函数。在你的device driver里用ioremap(),va/pa() 等函数来取得对应关系。然后在fops里的mmap()里写清楚对应关系。 2。raw I/O,可参考ldd2第13章的例子。 |
|