当前位置: 代码迷 >> 驱动开发 >> 虚拟内存和虚拟地址的小疑点
  详细解决方案

虚拟内存和虚拟地址的小疑点

热度:396   发布时间:2016-04-28 09:59:59.0
虚拟内存和虚拟地址的小问题
PE文件的虚拟内存空间一般是从0x00400000开始的,假设code段的起始地址是0x00401000这个地址怎么分配物理内存的,系统是怎么做映射的?
------解决思路----------------------
你是什么系统的内存系统啊?
Windows or Linux?
------解决思路----------------------
获得虚拟地址,肯定需要对MMU操作了,不过如果是Linux系统,直接调用ioremap()就可实现

我在iTOP-4412开发板上也遇到类似问题,共同努力
------解决思路----------------------
引用:
是windows
主要问题是通过descriptor.base+VA得到的线性地址为什么在进程间不会有冲突?我记得实模式下在同一地址是有多种CS:offset结构的

这个"descriptor"是什么?你说的"冲突"指的是什么类型的冲突?“实模式”是什么?

------解决思路----------------------
“线性地址”是什么?
------解决思路----------------------
楼主的理解已经无限接近真相了,只是要记住一条,这里所谈到的所有虚拟地址,物理地址,不是处于无政府状态的随便乱转的,这里有一个操作系统的内存管理模块在居中调度。操作系统会小心的维持所有的进程,让他们相信自己独占了所有的4G内存(这里姑且认为是4G吧)。内存管理模块会清楚的track每一块虚拟内存真真映射到了哪块物理内存上去,肯定内存会不够用,那就会出现所谓的page fault,触发缺页中断,做换页。。。说远了,不过整体上来说,你谈到的转换机制是没错的,但是武器是要有使用者的,对吧?
------解决思路----------------------
引用:
Quote: 引用:

关于进程间的地址冲突或者不冲突可以试着这么理解:
进程A有一个虚拟地址XXXX,进程B有一个虚拟地址YYYY,虽然XXXX==YYYY,但是由于进程A和进程B有不同的地址空间,内存管理系统会给进程A和进程B提供不同的内存映射;虽然虚拟地址一样,可是不会指向同样的物理内存。
这样就不会有地址冲突了。

根据映射的过程,虚拟地址先转换成线性地址,线性地址在经过页转换机构得到物理地址,如果线性地址相同,那么必然物理地址相同,但是不同进程中的虚拟地址经过转换后又有可能得到相同的线性地址,这是我对地址变换的一点认识,但显然这种认识出现了偏差,不知道问题出在哪儿?


虚拟地址和线性地址其实是一个概念。
MIPS处理器支持多个地址空间,每个地址空间有ASID(Address Space ID),放在EntryHi寄存器中。对应到linux,每个用户态进程,以及内核态,都有自己的ASID。进程空间切换的时候,需要修改这个寄存器。
虚拟地址到物理地址的转换,需要CPU的MMU和TLB模块的协助。注意,这两个模块是CPU内部的,是硬件模块,而不是软件模块。
cpu工作在用户态模式时,取虚拟地址,经MMU,读寄存器取ASID,配合虚拟地址的VPN(virtual page number),查TLB缓存。如果命中,直接向MMU返回物理地址。如果没有,触发一个异常,由cpu的异常处理流程完成TLB缓存的重填(也即查内核中该进程的多级页表),再返回给MMU物理地址。如果物理地址不存在,则还会触发一个缺页异常,让相应异常处理流程完成内存页的换入。
内核态也有虚拟地址,用于vmalloc分配逻辑上连续,但物理上不连续的内存。工作模式和用户态的进程类似。

------解决思路----------------------
根据intel 的手册。
MMU通过CR3寄存器所指向的页表进行虚拟地址到线性地址的转换。
而线性地址通过CS段寄存器,和GDT(全局描述符表)转换为物理地址。(多数情况,线性地址==物理地址)
整个转换过程,我只会写代码,不是很会说。
所以传送门: http://book.51cto.com/art/200812/103231.htm
这个说了个大概,如果你不进行内核编程懂这些就够了。