关闭

《深入理解linux内核》笔记二--内存寻址

896人阅读 评论(0) 收藏 举报

一、内存地址:

1、区分三种地址:

逻辑地址:是指由程式产生的和段相关的偏移地址部分。例如,你在进行C语言指针编程中,能读取指针变量本身值(&操作),实际上这个值就是逻辑地址,他是相对于你当前进程数据段的地址,不和绝对物理地址相干。只有在Intel实模式下,逻辑地址才和物理地址相等(因为实模式没有分段或分页机制,Cpu不进行自动地址转换);逻辑也就是在Intel保护模式下程式执行代码段限长内的偏移地址(假定代码段、数据段如果完全相同)。应用程式员仅需和逻辑地址打交道,而分段和分页机制对你来说是完全透明的,仅由系统编程人员涉及。应用程式员虽然自己能直接操作内存,那也只能在操作系统给你分配的内存段操作。

 

线性地址(也称虚拟地址):是逻辑地址到物理地址变换之间的中间层。程式代码会产生逻辑地址,或说是段中的偏移地址,加上相应段的基地址就生成了一个线性地址。如果启用了分页机制,那么线性地址能再经变换以产生一个物理地址。若没有启用分页机制,那么线性地址直接就是物理地址。Intel 80x86的线性地址空间容量为4G2的32次方即32根地址总线寻址)。

 

物理地址: 是指出目前CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果地址。如果启用了分页机制,那么线性地址会使用页目录和页表中的项变换成物理地址。如果没有启用分页机制,那么线性地址就直接成为物理地址了。

 

虚拟内存(Virtual Memory):是指计算机呈现出要比实际拥有的内存大得多的内存量。因此他允许程式员编制并运行比实际系统拥有的内存大得多的程式。这使得许多大型项目也能够在具有有限内存资源的系统上实现。一个非常恰当的比喻是:你不必非常长的轨道就能让一列火车从上海开到北京。你只需要足够长的铁轨(比如说3公里)就能完成这个任务。采取的方法是把后面的铁轨即时铺到火车的前面,只要你的操作足够快并能满足需求,列车就能象在一条完整的轨道上运行。这也就是虚拟内存管理需要完成的任务。在Linux0.11内核中,给每个程式(进程)都划分了总容量为64MB的虚拟内存空间。因此程式的逻辑地址范围是0x0000000到0x4000000。有时我们也把逻辑地址称为虚拟地址。因为和虚拟内存空间的概念类似,逻辑地址也是和实际物理内存容量无关的。逻辑地址和物理地址的“差距”是0xC0000000,是由于虚拟地址->线性地址->物理地址映射正好差这个值。这个值是由操作系统指定的。机理 逻辑地址(或称为虚拟地址)到线性地址是由CPU的段机制自动转换的。如果没有开启分页管理,则线性地址就是物理地址。如果开启了分页管理,那么系统程式需要参和线性地址到物理地址的转换过程。具体是通过设置页目录表和页表项进行的。

 

二、linux的分段分页机制:

分段可以给每个进程分配不同的线性地址空间,而分页可以把同一个线性地址空间映射到不同的物理空间。与分段相比,linux更喜欢使用分页方式。

1、分段机制:

逻辑地址到线性地址的转换:

逻辑地址由一个16位的段选择符和32位的偏移量组成。段选择符指定字符所在的段,而偏移量指定该字节在段中相对于段基地址的偏移量。

1.使用段选择符中的偏移值(段索引)在GDT或LDT表中找到相应的段描述符。(仅当一个新的段选择符加载到段寄存器中时才执行这一步)

2.根据段描述符中对访问权限和Limit判断该段是否可以访问,偏移量是否位于段的范围内。

3.从段描述符中取出段基地址,加上虚拟地址原有的32位偏移量就形成最终的线性地址。

无标题

 

 

 

 

 

 

 

 

 

2、分页机制:

二、 Linux中的分页机制

如前所述,Linux主要采用分页机制来实现虚拟存储器管理。这是因为:

· Linux的分段机制使得所有的进程都使用相同的段寄存器值,这就使得内存管变得简单,也就是说,所有的进程都使用同样的线性地址空间(04G)。

· Linux设计目标之一就是能够把自己移植到绝大多数流行的处理器平台。但是,许多RISC处理器支持的段功能非常有限。为了保持可移植性,Linux采用三级分页模式而不是两级,这是因为许多处理器(如康柏的AlphaSunUltraSPARCIntelItanium)都采用64位结构的处理器,在这种情况下,两级分页就不适合了,必须采用三级分页。

2.28为三级分页模式,为此,

Linux定义了三种类型的页表:

·总目录PGDPage GlobalDirectory

·中间目录PMDPage MiddleDerectory

·页表PTPage Table

2.28 Liunx的三级分页

尽管Linux采用的是三级分页模式,但我们的讨论还是以Intel奔腾处理器的两级分页模式为主,因此,Linux忽略中间目录层,以后,我们把总目录就叫页目录

 

三、 Linux分页管理机制

Linux使用分页管理机制来更加有效地利用物理内存.当创建一个进程时.仅仅把当前进程的一小部分真正装入内存.其余部分需要访问时.处理器产生一个页故障.由缺页中

断服务程序根据缺页虚拟地址和出错码调用写拷贝函数do—wp—page、此地址所属的vma的vm—ops指向的nopage、do—swap—page.swap—in等函数将需要的页换入物理内存。

随着可执行映像的运行和页面的换入.系统中的内存有可能变得不足.这时Linux核心就必须调用kswapd守护进程释放部分物理内存。kswapd在系统启动时由init进程建立。在系统的运行过程中。它被定期唤醒。检查系统中的空闲物理内存是否很少。如果是.则释放一部分内存.或者将一些页面换出到对换空间。然后继续睡眠。

(1) 缺页中断和页面换入

页面换入主要由缺页中断服务入口函数do—page—fault来实现。当系统中产生页面故障时.如果虚拟内存地址有效.则产生错误的原因有如下两种:

· 虚拟内存地址对应的物理页不在内存中。那么它必然在磁盘或对换空间中.如果在磁盘上.那么我们调用do—nO—page函数.而do—no—page调用vma一> vm—ops一> nopage()

函数建立页面映射.从对换空间或磁盘中调入页面.或者通过do—swap—page()函数调用swap—in()来换入页面。

· 该虚拟地址对应的物理页在内存。但是被写保护.如果这种情况发生在一个共享页面上.则需要“写拷贝“函数do—wp—page来换入页面.do—wp—page函数首先调用一get—

free—page获得一新页面.然后调用copy—COW—page拷贝页面的内容.当然还要调用相应的刷新函数刷新TLB和缓存等。

(2) 页交换进程和页面换出

正如我们上面所描述的.系统使用kswapd守护进程来定期地换出页面。使系统中有足够的空闲物理内存页。kswapd进程定期地检查系统中的空闲页面数.如果少于一定值.则按照以下三中途径获得空闲页面:① 减少缓冲区和页面高速缓存的大小;② 把共享内存占用的页面置换到对换空间;③ 换出或丢弃物理内存页。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:217336次
    • 积分:2856
    • 等级:
    • 排名:第12927名
    • 原创:39篇
    • 转载:30篇
    • 译文:1篇
    • 评论:12条
    最新评论