转:http://book.51cto.com/art/200812/103305.htm
在内存分段系统中,一个程序的逻辑地址通过分段机制自动地映射(变换)到中间层的4GB(232B)线性地址空间中。程序每次对内存的引用都是对内存段中内存的引用。当程序引用一个内存地址时,通过把相应的段基址加到程序员看得见的逻辑地址上就形成了一个对应的线性地址。此时若没有启用分页机制,则该线性地址就被送到CPU的外部地址总线上,用于直接寻址对应的物理内存。如图5-6所示。
|
图5-6 虚拟地址(逻辑地址)到物理地址的变换过程 |
CPU进行地址变换(映射)的主要目的是为了解决虚拟内存空间到物理内存空间的映射问题。虚拟内存空间的含义是指一种利用二级或外部存储空间,使程序能不受实际物理内存量限制而使用内存的一种方法。通常虚拟内存空间要比实际物理内存量大得多。
那么虚拟存储管理是怎样实现的呢?原理与上述列车运行的比喻类似。首先,当一个程序需要使用一块不存在的内存时(即在内存页表项中已标出相应内存页面不在内存中),CPU就需要一种方法来得知这个情况。这是通过80386的页错误异常中断来实现的。当一个进程引用一个不存在页面中的内存地址时,就会触发CPU产生页出错异常中断,并把引起中断的线性地址放到CR2控制寄存器中。因此处理该中断的过程就可以知道发生页异常的确切地址,从而可以把进程要求的页面从二级存储空间(如硬盘上)加载到物理内存中。如果此时物理内存已经被全部占用,那么可以借助二级存储空间的一部分作为交换缓冲区(Swapper)把内存中暂时不使用的页面交换到二级缓冲区中,然后把要求的页面调入内存中。这也就是内存管理的缺页加载机制,在Linux 0.12内核中是在程序mm/memory.c中实现。
Intel CPU使用段(Segment)的概念来对程序进行寻址。每个段定义了内存中的某个区域以及访问的优先级等信息。假定大家知晓实模式下内存寻址原理,现在我们根据CPU在实模式和保护模式下寻址方式的不同,用比较的方法来简单说明32位保护模式运行机制下内存寻址的主要特点。
在实模式下,寻址一个内存地址主要是使用段和偏移值,段值被存放在段寄存器中(如ds),并且段的长度被固定为64KB。段内偏移地址存放在任意一个可用于寻址的寄存器中(如si)。因此,根据段寄存器和偏移寄存器中的值,就可以算出实际指向的内存地址,如图5-7a所示。
而在保护模式运行方式下,段寄存器中存放的不再是被寻址段的基地址,而是一个段描述符表(Segment Descriptor Table)中某一描述符项在表中的索引值。索引值指定的段描述符项中含有需要寻址的内存段的基地址、段的长度值和段的访问特权级别等信息。寻址的内存位置是由该段描述符项中指定的段基地址值与一个段内偏移值组合而成。段的长度可变,由描述符中的内容指定。可见,和实模式下的寻址相比,段寄存器值换成了段描述符表中相应段描述符的索引值以及段表选择位和特权级,称为段选择符(Segment Selector),但偏移值还是使用了原实模式下的概念。这样,在保护模式下寻址一个内存地址就需要比实模式下多一个环节,即需要使用段描述符表。这是由于在保护模式下访问一个内存段需要的信息比较多,而一个16位的段寄存器放不下这么多内容。示意图如图5-7b所示。注意,如果你不在一个段描述符中定义一个内存线性地址空间区域,那么该地址区域就完全不能被寻址,CPU将拒绝访问该地址区域。
|
图5-7 实模式与保护模式下寻址方式的比较
a) 实模式下寻址 b) 保护模式下寻址
|
每个描述符占用8字节,其中含有所描述段在线性地址空间中的起始地址(基址)、段的长度、段的类型(如代码段和数据段)、段的特权级和其他一些信息。一个段可以定义的最大长度是4GB。
保存描述符项的描述符表有3种类型,每种用于不同目的。全局描述符表(Global Descriptor Table,GDT)是主要的基本描述符表,该表可被所有程序用于引用访问一个内存段。中断描述符表(Interrupt Descriptor Table,IDT)保存了定义中断或异常处理过程的段描述符。IDT表直接替代了8086系统中的中断向量表。为了能在80x86保护模式下正常运行,必须为CPU定义一个GDT表和一个IDT表。最后一种类型的表是局部描述符表(Local Descriptor Table,LDT)。该表应用于多任务系统中。通常每个任务使用一个LDT表。作为对GDT表的扩充,每个LDT表为对应任务提供了更多的可用描述符项,因而也为每个任务提供了可寻址内存空间的范围。这些表可以保存在线性地址空间的任何地方。为了让CPU能定位GDT表、IDT表和当前的LDT表,需要为CPU分别设置GDTR、IDTR和LDTR三个特殊寄存器。这些寄存器中将存储对应表的32位线性基地址和表的限长字节值。表限长值是表的长度值减1。
当CPU要寻址一个段时,就会使用16位的段寄存器中的选择符来定位一个段描述符。在80x86 CPU中,段寄存器中的值右移3位即是描述符表中一个描述符的索引值。13位的索引值最多可定位8192(0~8191)个描述符项。选择符中位2(TI)用来指定使用哪个表。若该位是0则选择符指定的是GDT表中的描述符,否则是LDT表中的描述符。
每个程序都可由若干个内存段组成。程序的逻辑地址(或称为虚拟地址)即是用于寻址这些段和段中具体地址位置。在Linux 0.12中,程序逻辑地址到线性地址的变换过程使用了CPU的全局段描述符表GDT和局部段描述符表LDT。由GDT映射的地址空间称为全局地址空间,由LDT映射的地址空间则称为局部地址空间,而这两者构成了虚拟地址的空间。具体的使用方式如图5-8所示。
|
图5-8 Linux系统中虚拟地址空间分配图
|
图中画出了具有两个任务时的情况。可以看出,每个任务的局部描述符表LDT本身也是由GDT中描述符定义的一个内存段,在该段中存放着对应任务的代码段和数据段描述符,因此LDT段很短,其段限长通常只要大于24字节即可。同样,每个任务的任务状态段TSS也是由GDT中描述符定义的一个内存段,其段限长也只要满足能够存放一个TSS数据结构就够了。
对于中断描述符表IDT,它保存在内核代码段中。由于在Linux 0.12内核中,内核和各任务的代码段和数据段都分别被映射到线性地址空间中相同基址处,且段限长也一样,因此内核的代码段和数据段是重叠的,各任务的代码段和数据段分别也是重叠的,如5-10和图5-11所示。任务状态段(Task State Segment,TSS)用于在任务切换时CPU自动保存或恢复相关任务的当前执行上下文(CPU当前状态)。例如对于切换出的任务,CPU就把其寄存器等信息保存在该任务的TSS段中,同时CPU使用新切换进任务的TSS段中的信息来设置各寄存器,以恢复该任务的执行环境,参见图4-37。在Linux 0.12中,每个任务的TSS段内容被保存在该任务的任务数据结构中。另外,Linux 0.12内核中没有使用到GDT表中第4个描述符(图中syscall描述符项)。从如下所示的include/linux/sched.h文件中第201行上的原英文注释可以猜想到,Linus当时设计内核时曾经想把系统调用的代码放在这个独立的段中。
200 /* 201 * Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall 202 * 4-TSS0, 5-LDT0, 6-TSS1 etc ... 203 */
|
分享到:
相关推荐
总的来说,Linux的分页分段机制是其内存管理的核心,通过这种方式,Linux能够提供高效、安全的内存服务,支持多任务并行运行,同时保证了各个进程之间的隔离性。理解和掌握这一机制对于任何深入研究Linux内核的人来...
在计算机系统中,分段机制是一种内存管理策略,它被用来组织和管理程序的内存空间。在本文中,我们将深入探讨“PA 3-2 分段机制1”这个主题,特别是关于CRO中的PE位如何控制保护模式和实地址模式,并理解16+32位逻辑...
Linux 倾向于使用分页机制来实现内存管理,而不是分段机制。Linux 中所有的用户空间进程使用相同的用户空间段描述符,以便于在不同进程之间共享内存。 页表机制 Linux 中的页表机制是通过 Paging Unit 来实现的。...
早期的内存分段机制是根据程序的逻辑结构,如代码、数据、栈和堆等,将内存划分为多个段。每个段有自己的属性,如权限和大小,段选择子(包含在虚拟地址中)用于在段表中找到对应的段基地址,段内偏移量则用来计算...
- **存储器管理**:支持内存分段和分页机制,提高了内存的灵活性和安全性。 - **多任务支持**:允许同时运行多个任务,提高系统的并发性能。 - **权限级别**:提供4个权限级别,增强系统的安全性和稳定性。 总之,...
### Linux内存分页机制原理详解 #### 一、引言 ...内存分段和分页机制不仅提高了内存的利用率,还增强了系统的安全性与稳定性。理解这些基本概念对于深入学习操作系统原理以及优化应用性能具有重要意义。
通过本文的介绍,我们可以了解到保护模式下的分段机制是操作系统内存管理的重要组成部分。它不仅提供了对内存的灵活管理和访问控制,还为实现虚拟内存提供了基础。全局描述符表和局部描述符表作为分段机制的核心组件...
如上图,Linux在内存管理上,把逻辑地址通过分段机制变化成线性地址,线性地址也是4G(32位系统)的程序地址。线性地址再通过分页机制转化成物理地址,后CPU去访问物理地址。 去年写个一篇关于IA32内存寻址的...
First fit, best fit and worst fit 操作系统lab-内存分配与分段分页机制
段寄存器用于实现内存分段机制。在x86架构中,主要有CS(Code Segment)、DS(Data Segment)、ES(Extra Segment)和SS(Stack Segment)四个段寄存器 。 c. 指针寄存器 指针寄存器主要用于存储指针或
首先,让我们了解一下分段机制。80386处理器在保护模式下可以支持16,000个段,每个段的大小可变,最大可达4GB。这种设计允许系统将内存空间划分为多个独立的部分,每个部分都有自己的属性和权限。逻辑地址到线性地址...
Linux虚拟内存管理机制 ... Linux操作系统的虚拟内存管理机制是基于X86处理器的分段机制和分页机制的,因此,了解X86处理器的分段机制和分页机制对理解Linux操作系统的虚拟内存管理机制非常重要。
分段机制是一种重要的内存管理技术,在Linux内核中扮演着基础角色。它通过将线性地址空间划分为较小的、受到保护的区域——即“段”,来实现对内存的有效管理。每一段可以用来存放程序的不同部分,比如代码、数据或...
- **硬件中的分段**:探讨了硬件层面的内存分段机制,了解它是如何工作的对于理解软件中的分段机制至关重要。 - **Linux中的分段**:详细说明了Linux内核如何处理内存分段,以及这种机制是如何支持进程隔离的。 - **...
虚拟地址包含一个16位的段选择器和一个32位的段内偏移量,通过分段机制,将段寄存器中的段选择器和段内偏移量相加,得到32位的线性地址。每个用户进程最多可以有16k个段,每段最大尺寸为4GB,所有段都必须映射到同一...
1. x86架构的内存分段机制。 2. 如何使用段寄存器和基址寄存器进行内存寻址。 3. 汇编语言中的寄存器和内存操作数的表示方法。 4. 如何通过偏移量来访问内存中的连续数据。 在实际编程中,这样的寻址方式可能用于...
分段机制是保护模式下内存管理的核心之一,它将线性地址空间划分为多个段(Segment),并通过这些段来存储代码和数据。每个段都有自己的描述符,包含了关于该段的基本信息和访问权限等。 ##### 1. 数据结构 - **段...
学习者会了解到段寄存器、偏移量和物理地址的关系,理解内存分段机制。此外,还会讲解如何使用寄存器组合来高效地处理内存数据。 第四章节可能涵盖的是更高级的主题,如条件转移指令、循环控制和子程序调用。这一章...
4. **内存管理**:内核通过页表和内存分段机制管理内存,确保数据的安全性和效率。它还包括虚拟内存系统,使得物理内存可以扩展到硬盘空间。 5. **文件系统**:Linux支持多种文件系统,如EXT4、XFS、Btrfs等。文件...