我有点困惑的术语物理/逻辑/虚拟的操作系统(我使用Linux的开放SUSE)地址
以下是我的理解:
物理地址 - 当处理器处于系统模式中,由处理器所使用的地址是物理地址。
逻辑地址 - 当处理器处于用户模式,所用的地址是逻辑地址。 这些是通过将与所述偏移value.It的方式提供一种存储器保护的基址寄存器反正映射到一些物理地址。
我所遇到的讨论虚拟和逻辑地址/地址空间是相同的。 是真的吗?
任何帮助深表感谢。
我有点困惑的术语物理/逻辑/虚拟的操作系统(我使用Linux的开放SUSE)地址
以下是我的理解:
物理地址 - 当处理器处于系统模式中,由处理器所使用的地址是物理地址。
逻辑地址 - 当处理器处于用户模式,所用的地址是逻辑地址。 这些是通过将与所述偏移value.It的方式提供一种存储器保护的基址寄存器反正映射到一些物理地址。
我所遇到的讨论虚拟和逻辑地址/地址空间是相同的。 是真的吗?
任何帮助深表感谢。
我的回答是真实的现代的Linux系统上运行英特尔CPU,而我只是讲用户级进程,而不是内核代码。 不过,我认为它会给你一些有识之士足够去想其他的可能性
关于问题3:
我所遇到的讨论虚拟和逻辑地址/地址空间是相同的。 是真的吗?
据我所知,他们是相同的,至少在现代操作系统的英特尔处理器上运行。
让我尝试定义两个概念之前,我更多地解释:
虚拟地址是很好,一个虚拟地址,用硬件电路沿OS叫做MMU(内存管理单元)欺骗你的程序,它在系统中的单独运行,它有整个地址空间(有32位系统,意味着你的程序会认为它有4个GB的内存,粗略地讲)。
显然,如果你有一个以上的程序在运行的时候(你总是这样,GUI,init进程,壳牌,时钟应用程序,日历,等等),这是不行的。
会发生什么事是,OS将把大部分的程序存储在硬盘上,您最常使用的部分将出现在RAM,但嘿,这并不意味着他们会让你知道地址。
例如:您的过程可能有一个命名的给了虚拟地址到0xFF(计数器)(被假设...)变量,并命名为(oftenNotUsed)的另一变量,给了虚拟地址(和0xAA)。
如果你毕竟链接的发生读你的编译代码的组件,你会使用这些地址来访问他们,但好,(oftenNotUsed)变量会不会真的出现在和0xAA RAM,这将是在硬盘因为你不使用它。
此外,变量(计数器)可能不会在物理上(0xFF的),它会在其他地方在RAM中,当你的CPU试图获取什么在为0xFF,对与MMU和操作系统的一部分,将做一个映射并获得该变量从那里它在RAM真正可用的,你甚至不会注意到它是不是在为0xFF。
如果你的程序要求(oftenNotUsed)可变现在会发生什么? 该MMU + OS会注意到这个“小姐”,并会从硬盘获取为您到RAM中,然后把它交给你,如果它是在地址(和0xAA); 此取出装置,这是存在于RAM一些数据将被发回给硬盘。
现在想象一下,这个运行系统中的每一个过程。 每个人都认为他们的RAM 4GB的,竟没有一个人有,但一切正常,因为每个人都有在RAM可用的物理自己程序的某些部分,但大部分程序驻留在硬盘。 不要混淆程序存储器的这一部分被放入HD你可以通过文件操作访问程序数据。
虚拟地址 :你在程序中使用的地址,你的CPU使用来获取数据,是不是真实的,并通过MMU被转换到一些物理地址的地址; 每个人都有一个和它的大小取决于你的系统(Linux上运行32位具有4GB地址空间)
物理地址 :如果你在一个操作系统上运行,你永远也做不到的地址。 这是您的数据,无论它的虚拟地址,驻留在内存中。 如果您的数据来回发送到硬盘,以适应其他进程更多的空间,这将会改变。
所有我所提到的,虽然它的整体概念的简化版本,是所谓的计算机系统的内存管理的一部分。
物理地址 - 当处理器处于系统模式中,由处理器所使用的地址是物理地址。
不一定是真实的。 这取决于具体的CPU。 在x86 CPU的,一旦你启用页面转换,所有的代码停止与物理地址或地址平凡转换成物理地址的操作(除了SMM,据我所知,但在这里,这并不重要)。
逻辑地址 - 当处理器处于用户模式,所用的地址是逻辑地址。 这些是通过将基址寄存器与所述偏移值反正映射到一些物理地址。
逻辑地址并不一定适用于用户模式独占。 在x86的CPU,他们在内核模式中也存在。
我所遇到的讨论虚拟和逻辑地址/地址空间是相同的。 是真的吗?
这取决于具体的CPU。 x86处理器可以在段不明确地使用这样的方式来配置。 他们是隐式使用,他们的基地始终为0(除线程本地存储段)。 什么,当你从逻辑地址下降的段选择仍然是一个32位(或64位),其值与32位(或64位)的虚拟地址一致的偏移量。 在这个简化的建立可以考虑这两个是相同的或逻辑地址不存在。 这是不正确的,但最实用的目的,足够好的近似的。
我指的是下面的答案基础上,英特尔的x86 CPU
差异逻辑之间的虚拟地址
每当你的程序是执行中CPU产生逻辑的说明其中包含(偏移的16位段选择位和32位),使用逻辑地址字段被产生的地址。基本上虚拟(线性地址)。
段选择为16比特的字段外面第一13位是指数(这是一个指向段描述符驻留在GDT,如下所述),1个比特字段TI(TI = 1,参见LDT,TI = 0参阅GDT)
现在段选择OR说段标识符指的是代码段或数据段或堆栈段等的Linux包含一个GDT / LDT(全局/局部描述符表),其中包含的每个区段的8字节的描述符,并保持基体的(虚拟)地址分割。
因此,对于每个逻辑地址,虚拟地址是使用以下步骤来计算。
1)检查段选择,以确定哪些描述符表存储段描述符的TI字段。 该字段表示描述符或者是在GDT(在这种情况下,分段单元从GDTR寄存器得到GDT的线性基地址),或在活性LDT(在这种情况下,区域分割部得到的碱的该线性地址从LDTR寄存器LDT)。
2)计算从所述段选择的索引字段的段描述符的地址。 索引字段是由图8(a段描述符的大小)相乘,并且将结果加到GDTR或LDTR寄存器的内容。
3)添加的偏移的逻辑地址到段描述符的基地场,从而获得线性(虚拟)地址。
现在是Pagging单位的地址到物理地址的虚拟地址转换的工作。
请参阅:了解Linux内核,第2章内存寻址
通常发出(对于x86架构)的每个地址是其经由段表转换为线性地址的逻辑地址。 翻译成线性地址后,然后通过页表转换为物理地址。
一个很好的文章,解释的深度是相同的:
http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation/
用户虚拟地址这是由用户空间程序见到的常规地址。 用户地址的长度是32或64位,这取决于底层的硬件结构,并且每个进程具有其自己的虚拟地址空间。
物理地址处理器和系统内存之间使用的地址。 物理地址是32位或64位值; 甚至32位系统可以在某些情况下使用64位的物理地址。
总线地址的外围总线和存储器之间使用的地址。 它们经常是相同的由所述处理器所使用的物理地址,但是这不是必须的。 总线地址是高度依赖于体系结构,当然。
内核逻辑地址 ,这些构成了内核的正常地址空间。 这些地址映射大部分或全部的主内存,并且常常被当作好像它们是物理地址。 在大多数的体系结构,逻辑地址和它们相关的物理地址只有一个常数的偏移量是不同的。 逻辑地址使用硬件的本地指针大小,因而可能无法满足所有的物理内存在大量配备32位系统。 逻辑地址通常保存在unsigned long类型或void *的类型的变量。 从用kmalloc返回的内存有一个逻辑地址。
内核虚拟地址这些在他们不一定有直接映射到物理地址的逻辑地址不同。 所有的逻辑地址都是内核虚拟地址; 通过vmalloc的分配的存储器还具有虚拟地址(但没有直接的物理映射)。 的kmap返回虚拟地址的功能。 虚拟地址通常保存在指针变量。
如果你有一个逻辑地址,宏__pa()(定义)将返回其关联的物理地址。 物理地址可以(),但只为低内存页面映射回逻辑地址与__va。
参考 。
物理地址是受存储单元,即,一个加载到存储器地址寄存器看到的地址。 逻辑地址是由CPU产生的地址。 用户程序不能看到真实的物理address.Memory映射单元将逻辑地址到物理地址。 在使用前由使用者过程中产生的逻辑地址必须被映射到物理存储器。
逻辑存储器是相对于各自的程序,即(启动程序的点+偏移)
虚拟内存使用,它映射到内存和硬盘的页表。 这样,每个过程可以保证对每一道工序更多的内存。
在用户模式或用户空间程序通过看到的所有地址都是虚拟地址。 当由内核看到内核模式的地址仍虚拟但称为逻辑,因为它们是等于物理+ pageoffset。 物理地址是它们由RAM看到的人。 随着虚拟内存在程序中的每个地址经过页表。
当u写一个小程序如:
int a=10;
int main()
{
printf("%d",a);
}
compile: >gcc -c fname.c
>ls
fname.o //fname.o is generated
>readelf -a fname.o >readelf_obj.txt
/ readelf是一个命令,以了解目标文件和文件executabe这将是0和1。 输出被写入readelf_onj.txt文件 /
`>vim readelf_obj.txt`
/ *“节头”下,你会看到你的目标文件。数据的.text .RODATA部分。 每启动或基址是从0000开始并生长至相应尺寸,直到它达到在标题“大小” ---->这些是逻辑地址下的大小。* /
>gcc fname.c
>ls
a.out //your executabe
>readelf -a a.out>readelf_exe.txt
>vim readelf_exe.txt
/ *这里的所有部分的基地址不为零。 它将从特定地址开始和结束到特定地址。 链接器将给予连续地址,以所有部分(注意在readelf_exe.txt文件。观察基址和各部分的尺寸,他们会不断地启动),因此只基址是不同--->这就是所谓的虚拟地址空间。* /
物理地址 - >内存LL具有的物理地址。 当你的可执行文件被加载到内存中就会有物理地址。 其实,虚拟不会忽略被映射到执行物理地址。