首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于80x86的Linux的分段和分页机制(4)

基于80x86的Linux的分段和分页机制(4)

2.5 页表处理

pte_t、pmd_t、pud_t和pgd_t分别描述页表项、页中间目录项、页上级目录和页全局目录项的类型格式。当PAE被激活时它们都是64位的数据类型,否则都是32位数据类型。pgprot_t是另一个64位(PAE激活时)或32位(PAE禁用时)的数据类型,它表示与一个单独表项相关的保护标志。

五个类型转换宏(__ pte、__ pmd、__ pud、__ pgd和__pgprot)把一个无符号整数转换成所需的类型。另外的五个类型转换宏(pte_val,pmd_val, pud_val,pgd_val和pgprot_val)执行相反的转换,即把上面提到的四种特殊的类型转换成一个无符号整数。

内核还提供了许多宏和函数用于读或修改页表表项:
• 如果相应的表项值为0,那么,宏pte_none、pmd_none、pud_none和pgd_none产生的值为1,否则产生的值为0。
• 宏pte_clear、pmd_clear、pud_clear和pgd_clear清除相应页表的一个表项,由此禁止进程使用由该页表项映射的线性地址。ptep_get_and_clear()函数清除一个页表项并返回前一个值。
•set_pte,set_pmd,set_pud和set_pgd向一个页表项中写入指定的值。set_pte_atomic与set_pte作用相同,但是当PAE被激活时它同样能保证64位的值能被原子地写入。
• 如果a和b两个页表项指向同一页并且指定相同访问优先级,pte_same(a,b)返回1,否则返回0。
• 如果页中间目录项指向一个大型页(2MB或4MB),pmd_large(e)返回1,否则返回0。

宏pmd_bad由函数使用并通过输入参数传递来检查页中间目录项。如果目录项指向一个不能使用的页表,也就是说,如果至少出现以下条件中的一个,则这个宏产生的值为1:
• 页不在主存中(Present标志被清除)。
• 页只允许读访问(Read/Write标志被清除)。
• Acessed或者Dirty位被清除(对于每个现有的页表,Linux总是强制设置这些标志)。

pud_bad宏和pgd_bad宏总是产生0。没有定义pte_bad宏,因为页表项引用一个不在主存中的页,一个不可写的页或一个根本无法访问的页都是合法的。

如果一个页表项的Present标志或者PageSize标志等于1,则pte_present宏产生的值为1,否则为0。前面讲过页表项的PageSize标志对微处理器的分页部件来讲没有意义,然而,对于当前在主存中却又没有读、写或执行权限的页,内核将其Present和PageSize分别标记为0和1。这样,任何试图对此类页的访问都会引起一个缺页异常,因为页的Present标志被清0,而内核可以通过检查PageSize的值来检测到产生异常并不是因为缺页。

如果相应表项的Present标志等于1,也就是说,如果对应的页或页表被装载入主存,pmd_present宏产生的值为1。pud_present宏和pgd_present宏产生的值总是1。

下表中列出的函数用来查询页表项中任意一个标志的当前值;除了pte_file()外,其他函数只有在pte_present返回1的时候,才能正常返回页表项中任意一个标志。



函数名称

说明
pte_user( )
User/Supervisor 标志。
pte_read( )
User/Supervisor 标志(表示 80x86 处理器上的页不受读的保护)。
pte_write( )
Read/Write 标志。
pte_exec( )
User/Supervisor 标志( 80x86 处理器上的页不受代码执行的保护)。
pte_dirty( )
Dirty 标志。
pte_young( )
Accessed 标志。
pte_file( )
Dirty 标志(当 Present 标志被清除而 Dirty 标志被设置时,页属于一个非线性磁盘文件映射)。
继承事业,薪火相传
返回列表