2.5.2 对页目录及页表的处理

   page.hpgtable.hpgtable-2level.h三个文件中还定义有大量的宏,用以对页目录、页表及表项的处理,我们在此介绍一些主要的宏和函数。

 

  1.表项值的确定

   static inline int pgd_none(pgd_t pgd)           { return 0; }

   static inline int pgd_present(pgd_t pgd)        { return 1; }

 

   #define pte_present(x)  ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))

     pgd_none()函数直接返回0,表示尚未为这个页目录建立映射,所以页目录项为空。pgd_present()函数直接返回1,表示映射虽然还没有建立,但页目录所映射的页表肯定存在于内存(即页表必须一直在内存)。

pte_present宏的值为10,表示P标志位。如果页表项不为0,但标志位为0,则表示映射已经建立,但所映射的物理页面不在内存。

  2. 清相应表的表项:

  #define pgd_clear(xp)                           do { } while (0)

  #define pte_clear(xp)   do { set_pte(xp, __pte(0)); } while (0)

  pgd_clear宏实际上什么也不做,定义它可能是为了保持编程风格的一致。pte_clear就是把0写到页表项中。

 3.对页表表项标志值进行操作的宏。

 这些宏的代码在pgtable.h文件中,表2.1给出宏名及其功能。

  2.1 对页表表项标志值进行操作的宏及其功能

    宏名

功能

Set_pte()

把一个具体的值写入表项

Pte_read()

返回User/Supervisor标志值(由此可以得知是否可以在用户态下访问此页)

Pte _write()

如果Present标志和Read/Write标志都为1,则返回1(此页是否存在并可写)

Pte _exec()

返回User/Supervisor标志值

Pte _dirty()

返回Dirty标志的值(说明此页是否被修改过)

Pte _young()

返回Accessed标志的值(说明此页是否被存取过)

Pte _wrprotect()

清除Read/Write标志

Pte _rdprotect()

清除User/Supervisor标志

Pte _mkwrite

设置Read/Write标志

Pte _mkread

设置User/Supervisor标志

Pte _mkdirty()

Dirty标志置1

Pte _mkclean()

Dirty标志置0

Pte _mkyoung

Accessed标志置1

Pte _mkold()

Accessed标志置0

Pte _modify(p,v)

把页表p的所有存取权限设置为指定的值v

Mk_pte()

把一个线性地址和一组存取权限合并来创建一个32位的页表

Pte _pte_phys()

把一个物理地址与存取权限合并来创建一个页表

Pte _page()

从页表项返回页的线性地址

 

 

   实际上页表的处理是一个复杂的过程,在这里我们仅仅让读者对软硬件如何结合起来有一个初步的认识,有关页表更多的内容我们将在第六章接着讨论。