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

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

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

下表中列出的函数用来查询页表项中任意一个标志的当前值;除了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 标志被设置时,页属于一个非线性磁盘文件映射)。
下表列出的另一组函数用于设置页表项中各标志的值:

函数名称

说明
mk_pte_huge( )
设置页表项中的 PageSize Present 标志。
pte_wrprotect( )
清除 Read/Write 标志。
pte_rdprotect( )
清除 User/Supervisor 标志。
pte_exprotect( )
清除 User/Supervisor 标志。
pte_mkwrite( )
设置 Read/Write 标志。
pte_mkread( )
设置 User/Supervisor 标志。
pte_mkexec( )
设置 User/Supervisor 标志。
pte_mkclean( )
清除 Dirty 标志。
pte_mkdirty( )
设置 Dirty 标志。
pte_mkold( )
清除 Accessed 标志(把此页标记为未访问)。
pte_mkyoung( )
设置 Accessed 标志(把此页标记为访问过)。
pte_modify(p,v)
把页表项 p 的所有访问权限设置为指定的值 v
ptep_set_wrprotect()
pte_wrprotect() 类似,但作用于指向页表项的指针。
ptep_set_access_flags( )
如果 Dirty 标志被设置为 1 则将页的访问权设置为指定的值,并调用flush_tlb_page() 函数。
ptep_mkdirty( )
pte_mkdirty() 类似,但作用于指向页表项的指针。
ptep_test_and_clear_dirty( )
pte_mkclean() 类似,但作用于指向页表项的指针并返回 Dirty 标志的旧值。
ptep_test_and_clear_young( )
pte_mkold() 类似,但作用于指向页表项的指针并返回 Accessed标志的旧值。
现在,我们来讨论下表中列出的宏,它们把一个页地址和一组保护标志组合成页表项,或者执行相反的操作,从一个页表项中提取出页地址。请注意这其中的一些宏对页的引用是通过 “页描述符”的线性地址,而不是通过该页本身的线性地址。
宏名称
说明
pgd_index(addr)
找到线性地址 addr 对应的的目录项在页全局目录中的索引(相对位置)。
pgd_offset(mm, addr)
接收内存描述符地址 mm 和线性地址 addr 作为参数。这个宏产生地址addr 在页全局目录中相应表项的线性地址;通过内存描述符 mm 内的一个指针可以找到这个页全局目录。
pgd_offset_k(addr)
产生主内核页全局目录中的某个项的线性地址,该项对应于地址 addr
pgd_page(pgd)
通过页全局目录项 pgd 产生页上级目录所在页框的页描述符地址。在两级或三级分页系统中,该宏等价于 pud_page() ,后者应用于页上级目录项。
pud_offset(pgd, addr)
参数为指向页全局目录项的指针 pgd 和线性地址 addr 。这个宏产生页上级目录中目录项 addr 对应的线性地址。在两级或三级分页系统中,该宏产生 pgd ,即一个页全局目录项的地址。
pud_page(pud)
通过页上级目录项 pud 产生相应的页中间目录的线性地址。在两级分页系统中,该宏等价于 pmd_page() ,后者应用于页中间目录项。
pmd_index(addr)
产生线性地址 addr 在页中间目录中所对应目录项的索引(相对位置)。
pmd_offset(pud, addr)
接收指向页上级目录项的指针 pud 和线性地址 addr 作为参数。这个宏产生目录项 addr 在页中间目录中的偏移地址。在两级或三级分页系统中,它产生 pud ,即页全局目录项的地址。
pmd_page(pmd)
通过页中间目录项 pmd 产生相应页表的页描述符地址。在两级或三级分页系统中, pmd 实际上是页全局目录中的一项。
mk_pte(p,prot)
接收页描述符地址 p 和一组访问权限 prot 作为参数,并创建相应的页表项。
pte_index(addr)
产生线性地址 addr 对应的表项在页表中的索引(相对位置)。
pte_offset_kernel(dir,addr)
线性地址 addr 在页中间目录 dir 中有一个对应的项,该宏就产生这个对应项,即页表的线性地址。另外,该宏只在主内核页表上使用。
pte_offset_map(dir, addr)
接收指向一个页中间目录项的指针 dir 和线性地址 addr 作为参数,它产生与线性地址 addr 相对应的页表项的线性地址。如果页表被保存在高端存储器中,那么内核建立一个临时内核映射,并用 pte_unmap 对它进行释放。 pte_offset_map_nested 宏和 pte_unmap_nested 宏是相同的,但它们使用不同的临时内核映射。
pte_page( x )
返回页表项 x 所引用页的描述符地址。
pte_to_pgoff( pte )
从一个页表项的 pte 字段内容中提取出文件偏移量,这个偏移量对应着一个非线性文件内存映射所在的页。
pgoff_to_pte(offset )
为非线性文件内存映射所在的页创建对应页表项的内容。
下面我们罗列最后一组函数来简化页表项的创建和撤消。当使用两级页表时,创建或删除一个页中间目录项是不重要的。如本节前部分所述,页中间目录仅含有一个指向下属页表的目录项。所以,页中间目录项只是页全局目录中的一项而已。然而当处理页表时,创建一个页表项可能很复杂,因为包含页表项的那个页表可能就不存在。在这样的情况下,有必要分配一个新页框,把它填写为 0 ,并把这个表项加入。
继承事业,薪火相传
返回列表