现在的位置: 首页 > 综合 > 正文

保护模式及其编程——分页机制

2017年05月24日 ⁄ 综合 ⁄ 共 4798字 ⁄ 字号 评论关闭
摘要:分页机制是实现虚拟存储的关键,但是它的实现比较简单。传统的页都是<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">4K</span></span>大小,当然,在最近的内核中,分页机制因为一些原因而比较繁琐。在这里,我们仅仅浅谈最简单的分页机制,在其他的文章中,我们将讲解现代新<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">linux</span></span>内核中的分页机制。

我们通过设置<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">cr0</span></span>的<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">PG</span></span>位来开启分页机制。页大小是<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">4K</span></span>,并且是<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">4K</span></span>对齐的。线性地址到物理地址的转换中,可能某些线性地址是无效的。如果某个线性地址对应的页不存在,那么访问的时候将产生一个异常。分页和分段最大的不同就是分页是固定大小的。为了减少地址转化需要的总线周期数量,我们使用<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">TLB</span></span>缓存最近使用的页表。

<h1 style="margin: 0px; padding: 0px;"><a target=_blank name="t0" style="color: rgb(202, 0, 0);"></a><span style="font-size: 18px; color: rgb(255, 0, 0);"><span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">1.</span></span>页表结构</span></h1>
<h2 style="margin: 0px; padding: 0px;"><a target=_blank name="t1" style="color: rgb(202, 0, 0);"></a><span style="font-size: 18px; color: rgb(255, 0, 0);"><span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">1.1</span></span>两级页表结构</span></h2>页表中,每项的大小是<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">32b</span></span>,其中<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">20b</span></span>用来存放页面的物理地址,<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">12b</span></span>用于存放属性信息。

页表含有<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">1M</span></span>个表项,每项<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">4B.</span></span>第一级表是页目录,存放在<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">1</span></span>页<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">4k</span></span>页面中,含有<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">1K</span></span>个表项。第二级是页表,也是<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">1K</span></span>个表项。二级页表的查找过程如下图
<img src="http://img.blog.csdn.net/20140219212854015?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdHJvY2hpbHVzZXM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" style="border: none; max-width: 100%;" />
<h2 style="margin: 0px; padding: 0px;"><a target=_blank name="t2" style="color: rgb(202, 0, 0);"></a><span style="font-size: 18px; color: rgb(255, 0, 0);"><span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">1.2.</span></span>不存在的页表</span></h2>页目录表的每个表项都有一个<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">present</span></span>属性,这个属性可以节省存放页表所需要的空间。另外,这个属性还可以用于在虚拟内存中存放二级页表。这意味着,任何时候只有部分二级页表在物理内存中,其余可以保存在磁盘上。

<h1 style="margin: 0px; padding: 0px;"><a target=_blank name="t3" style="color: rgb(202, 0, 0);"></a><span style="font-size: 18px; color: rgb(255, 0, 0);"><span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">2.</span></span>页表项格式</span></h1>
页表项格式如下图:

<img src="http://img.blog.csdn.net/20140219212909781?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdHJvY2hpbHVzZXM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" style="border: none; max-width: 100%;" />
其中属性位包含如下信息:
<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">P——b0</span></span>,存在位标志
<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">R/W——b1</span></span>,读写位标志
<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">U/S——b2</span></span>,用户<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">/</span></span>超级用户标志
<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">A——b5</span></span>,已经访问标志
<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">D——b6</span></span>,脏位标志
<span style="font-family: 'DejaVu Sans Mono', monospace;"><span lang="en-US">AVL——</span></span>保留字段
G:第8b,表示全局页
<span style="font-size: 14.44444465637207px;">保护模式是否开启,取决于cr0的第0位PG。</span>
<span style="font-size: 14.44444465637207px;">
</span>
<span style="font-size: 14.44444465637207px;">有关数据结构;一个页表或者页目录项大小是4B;而开启分页机制以后,存储单元变成了页(不存在说,一部分存储开启了分页机制,另外一部分没有开启分页机制(除非这部分不能通过操作系统访问到))。所以,一个页上含有1024个页表项;一个页目录,对应1K*4K=4M的空间;一个程序有4G的线性地址空间,正好需要1K个页目录来存储,它占用的页表是4M.</span>
<span style="font-size: 14.44444465637207px;">
</span>
<span style="font-size: 14.44444465637207px;">另外,页表和页目录表都表项都是32b的,其中地址对应的是20b(第12b清零)。</span>
<span style="font-size: 14.44444465637207px;">
</span>
<span style="font-size: 14.44444465637207px;">当页目录或者页表项被修改的时候,对应TLB中的项目也就失效了;当cr3重新加载的时候,所有的TLB都失效了(G标志为1的除外)</span>
<span style="font-size: 14.44444465637207px;">因为页目录基地址是4K对齐的,所以CR3中仅用20b来存储它的基地址。</span>

抱歉!评论已关闭.