内存管理

 

在网上搜到一个这样的问题:

 

在驱动中用ioremap映射一段内存物理地址,然后用virt_to_phys或virt_to_bus转换为物理地址,但为什么这个物理地址和我ioremap前的地址不一样呢?这个地址仅仅把虚拟地址减去了一个偏移0xc0000000,怎么解释呢?


链接:http://www.unixresources.net/linux/clf/driver/archive/00/00/52/06/520628.html

 

摘一些牛人的回答:

 

====================================================

 

1)ioremap可以映射外设的物理空间。但好像不适合物理内存。 
2)virt_to_bus可以算出内存的物理地址,供DMA使用。但这个函数是否对外设空间有效,就不知道了。

 

====================================================

 

linux device driver第13章提到了多种地址,其中有 

kernel logical address: These addresses map most or all of main memory.and are often treated as if they were physical addresses. On most architectures, logical addresses and their associated physical addresses differ only by a constant offset. 
内核逻辑地址和物理地址之间只有一个偏移量的差别。而且内核在启动时就是根据这种逻辑地址和物理地址的对应关系给896MB以下内存建立了页表。virt_to_phys只接受这种直接映射的虚拟地址作为参数。 
kernel virtual address: ioremap返回的就是这种地址。它在VMALLOC_START和VMALLOC_END之间搜索到一块空闲的虚拟地址空间,把它和物理地址(ioremap的参数)建立联系,并建立页表。VMALLOC_START是根据最大内存地址的虚拟地址(kernel logical address)计算出来的,如在i386中: 
#define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & ~(VMALLOC_OFFSET-1)) 

可见kernel logical address和kernel virtual address 是不一样的,而且在值上是不会重叠的。对kernel virtual address调用virt_to_phys也是没有意义的。 

 

====================================================

另有解释: http://blog.csdn.net/hedoudou/archive/2009/10/12/4657028.aspx

 


在x86下,外设的i/o地址是独立的,即有专门的指令访问外设i/o,i/o地址就是所谓的“总线地址”。而“物理地址”就是ram地址。   
在arm中,i/o和ram统一编址,但linux为了统一各个平台,仍然保留这个概念,其实就是物理地址。    
linux   无论kernel还是user   space,都是直接访问虚拟地址(uclinux除外),要访问i/o,必须把i/o地址转换成虚拟地址才能访问。

MMU启动前程序中的地址为物理地址,和硬件手册中规定的地址一致。MMU启动后程序中的地址为虚拟地址,参照MMU地址映射表  

 

你可能感兴趣的:(内存管理)