物理地址、虚拟地址、线性地址之间的联系是什么?
我在看《情景分析》是有点疑惑:物理地址、虚拟地址、线性地址之间的联系是什么?
他们之间是如何转换的?通常来说在什么情况下需要转换?
谢谢各位大侠先!!!!! 首先,我建议你先看<<深入理解linux内核>>
所谓的物理地址就是在内存中的地址,而操作系统为了编程的方便,让我们编写的程序使用虚拟地址
让我详细解释一下
我们写的程序经过编译器编译之后产生的是逻辑地址因为Intel是基于段式管理的所以操作系统将逻辑地址转换成线性地址(详见情景分析第一章)
实际上linux完全绕过了段式存储,实际上逻辑地址转换成线性地址时并没有变化。然后这里的线性地址就是我们通常所说的虚拟地址。再通过页式管理将这些虚拟地址映射成物理地址。 是我问题提的不好,让您误会了
在linux中针对i386架构的cpu所作的地址映射实际上是使线性地址和逻辑地址相等,
也就是说逻辑地址就是线性地址,因此cpu可以通过ecs寄存器中的段地址(也就是线性地址)再到pgd\pte中找到相应的物理地址。
我的疑惑是:在编译器编译一段程序后,会给程序分配一个入口地址,这个地址其实就是
虚拟地址吧?(也就是线性地址?)可是编译器根据什么给程序分配入口地址呢?也就是
说在编译连接时都有什么因素会影响到程序的入口地址?为什么不将程序的入口地址分配
为虚存空间的起始地址?因为反正虚拟地址在程序被调入系统空间时还需要根据情况来分
配物理空间与之相对应。既然分配了线性地址,就说明在系统空间中分配给进程的相应物
理空间在编译时就已经确定了,这样的话如果内核将程序调进系统空间时该页面已经被使
用了那岂不很麻烦?
由以上的疑惑才会想知道虚拟地址、线性地址、物理地址之间的关系和他们之间是如何转
换的。也许是我上面的理解就根本不对。我觉得理清了他们之间在内核中实际的转换关系
后也许会明白这些东西。
另外,linux走了一条捷径,在i386中将虚拟地址和线性地址映射成了同一种东西,那么
如果虚拟地址和线性地址不是相等的话,它们之间又应该如何互相映射呢?
谢谢!! 你好,你问的很好,我也不是特别的懂,现在我就我的理解说一下,请大家多指教:这里只讨论linuxi386系列:
我们先看下面一段反汇编代码:(这是我随便截取的,旨在说明各种地址的关系)
0804835c <main>:
804835c: 55 push %ebp
804835d: 89 e5 mov %esp,%ebp
804835f: 83 ec 08 sub $0x8,%esp
8048362: 83 e4 f0 and $0xfffffff0,%esp
8048365: b8 00 00 00 00 mov $0x0,%eax
804836a: 29 c4 sub %eax,%esp
804836c: e8 0b ff ff ff call 804827c <_init+0x28>
,看到最左面的地址了吗?那是gcc编译的时候给的,gcc再ld(估计是链接还是什么的)的时候总是从0x8000000开始的,至于0x8000000就可以理解成为虚拟地址了,也可以看成是逻辑地址(逻辑地址是这么理解的吗?是不是逻辑地址是那些段式管理的os里面的概念呢?)了.
楼上的第一句 "在linux中针对i386架构的cpu所作的地址映射实际上是使线性地址和逻辑地址相等" 这句话很含糊,i386系列本身就是要将逻辑地址通过段式管理来映射到最终的物理地址,而linux是页式管理,根本就没有段式管理的必要,但是因为linux跑在i386上面自然要遵从段式管理的需要,因为这是硬件上的要求,可是linux绕了一个弯子,让段式管理的段式映射有了等于 没有,而楼上你的"因此cpu可以通过ecs寄存器中的段地址(也就是线性地址)再到pgd\pte中找到相应的物理地址。 "这句话完全将段式管理和页式管理搞混掉了.
我们看到上面的程序的最后一行就是对804827c(这个是虚拟地址,可以理解成逻辑地址吗?)寻址,接着进行段式管理的地址转换(具体看qjfx)转换的结果还是804827c,这就是线性地址,然后在根据已经设置好的的pgd/pte进行最终的线性地址到物理地址的映射.
你的第一个问题,编译之后的确是虚拟地址,但不是线性地址,要先转个弯子(形式上的进行段式管理一下),虽然二者的地址是一样的.
第二个问题,编译器确切根据什么给地址我不清楚,但是qjfx上p35上面提到用户程序的起始地址是在0x8000000上开始的,此时可以不用考虑实际的物理地址怎样.要不然怎么叫虚拟地址呢:)?
最后一个问题"既然分配了线性地址,就说明在系统空间中分配给进程的相应物
理空间在编译时就已经确定了",在我们编译程序的时候不要忘了我们是在操作系统上的,os做的工作就是为我们分配相应的物理内存和相应的pgd/pte映射,如果该页面已被使用,那os是不会分配给用户的.
不知道上面的解释还有什么疑问,本人水平有限,请多指教 我的理解是虽然系统必须经过段式管理的步骤,但是在具体的页式管理下段式管理完全变成透明了,甚至它进行的权限验证都没有被liunx加以重视。
虚拟地址和逻辑地址在我的理解中就是同一种东西,在虚拟空间中每个进程理论上可以拥有3G自己的空间,这个空间中的编址就是虚拟地址,其实也就是逻辑地址。
而楼上你的"因此cpu可以通过ecs寄存器中的段地址(也就是线性地址)再到pgd\pte中找到相应的物理地址。 "这句话完全将段式管理和页式管理搞混掉了.
这里是我写错了,应该是cr3控制寄存器
我的想法是基于这样一种理解:在给定一个虚拟地址(线性地址)后,在内存中就确定了一个物理页面。如果这种理解不对的话,那么线性地址-〉pgt-〉pte-〉page这种过程应该怎样理解? "在给定一个虚拟地址(线性地址)后,在内存中就确定了一个物理页面。"
这句话似乎有问题,首先在进程生成的时候os会对其进行物理页面的分配以及pte和pgd的相应的初始化,然后执行程序的时候一切都水到渠成,在线性地址-->gdt这个过程中os做了很多工作 当然详细的在比如说qjfx中的"用户堆栈的扩展"里面有涉及到
daemonx那您认为线性地址--> gdt -->gte-->page的理解有什么问题呢? 可以给详细的解释一下吗? 书中对这些地址映射的过程讲解的很详细,也很清楚,在那种情景下的过程也顺理成章,就因为很清楚,所以我觉得
在给定一个虚拟地址(线性地址)后,在内存中就确定了一个物理页面。
没有错阿。 我的意思是虚拟地址不一定就对应了真正的物理页面,当有时对一个虚拟地址进行映射的时候发现pte里面根本就没有对应的物理地址(pte里都是0),此时发生一个页面异常,于是操作系统开始为这个虚拟地址分配一个物理页框,有时一个pte有映射,可是映射的这个物理面却不一定在物理内存里面(你知道,pte只用高20位,低12位是一些设置),里面的一个设置好像是present位标志了,所以给定一虚拟地址不一定有相应的物理页框对应,否则你想,如果你的程序有200mb,而你的内存只有128mb那这些虚拟地址又怎能对应相应的物理页框呢?
其实从虚存地址到相应的gdt/gpt中去寻找是否能映射到物理地址,不能就会引起系统调用,os试图分配一个物理页面给这个虚拟地址.
这样解释可以吗? 符合逻辑的想法应该是虚拟地址和物理地址没有必然联系。
换句话说无论虚拟地址是什么,物理地址都应该是根据当前系统的叶面分配情况来和虚拟地址叶面相对应的。也就是虚拟地址左右不了物理地址。
可pgd是全局的,虚拟地址定了以后根据情景分析里面描述的方法通过pgd-pte-page的过程后其实找到的是一个确定的物理地址。这就不符合逻辑了。 我知道你的意思了,你的前面的说法的确很对,注意这里pgd里面装得是pte的地址.
我们知道,当一个进程销亡时,那系统要回收他的所有资源,自然也有物理页面,我们可以看一看系统调用brk()(在qjfx160页),pgd的确是全局的,可是全局并不意味着不变,怎么变brk()讲的很清楚,最终brk()取消了pte对物理地址的映射,所以pgd--pte--page也不是永远不变的 我明白了
虽然经过映射可以知道使用的是pte中的那一项,也可以知道那一项所指的页面的偏移量是多少,但是却无法知道那一项所指的页面时哪一页,具体给pte中的项分配页面指针的工作是由mm根据当前物理页面的分配情况来分配的,这样理解对吧?
首先,我建议你先看<<深入理解linux内核>>
请问在哪里可以找到这本书? 基本是 这样的,不过你的"mm"指什么?是mmu吗?mmu可只是完成一些硬件上转换而已,其实是os在这里面做了很多工作,相信你在都qjfx的时候会发现的.以上你说的工作是由内存管理进行的.:)
页:
[1]
2