了解 pagedir_get_page() 中用户、内核和物理地址之间的关系

Understanding the relation between user, kernel and physical addresses in pagedir_get_page()

我对以下评论感到困惑:

/* Looks up the physical address that corresponds to user virtual
address UADDR in PD.  Returns the kernel virtual address
corresponding to that physical address, or a null pointer if
UADDR is unmapped. */

第一句我明白了,就是找实际的物理地址,但是我不明白为什么会返回那个地址对应的kernel虚拟地址。总之,uaddr既然是user虚拟地址,那为什么和kernel虚拟地址有关呢?

void *
pagedir_get_page (uint32_t *pd, const void *uaddr)
{
  uint32_t *pte;

  ASSERT (is_user_vaddr (uaddr));

  pte = lookup_page (pd, uaddr, false);
  if (pte != NULL && (*pte & PTE_P) != 0)
    return pte_get_page (*pte) + pg_ofs (uaddr);
  else
    return NULL;
}

提前致谢。

评论说的地址一共有三种:

  1. 物理地址:这是真实地址,I.E.计算机物理内存中的真实准确位置。
  2. 内核虚拟地址:这是内核看到该物理地址的虚拟地址。
  3. 用户虚拟地址:这是用户space程序看到该物理地址的虚拟地址。

所以,简单的ASCII艺术,就是这样的情况:

 User space    
  program 1         Kernel            RAM
+-----------+    +-----------+    +-----------+
| 0xAAAA000 |    | 0x1212000 |    | 0xA7EF000 |
| 0xBBBB000 |    | 0x4398000 |    | 0x0001000 |
| 0xCCCC000 |<---| 0x87FF000 |<---| 0x1234000 |
+-----------+    | ...       |    | ...       |
                 | ...       |    | ...       |
 User space      | ...       |    | ...       |
  program 2      | ...       |    | ...       |
+-----------+    | ...       |    | ...       |
| 0xDDDD000 |    | 0x7FF8000 |    | 0x3FFF000 |
| 0xEEEE000 |    | 0xABCD000 |    | 0x2010000 |
| 0xFFFF000 |<---| 0x98AE000 |<---| 0xA89A000 |
+-----------+    +-----------+    +-----------+

该函数,给定一个有效的用户space虚拟地址,进行查找并检索关联的内核space虚拟地址。可以完成此查找,因为它们都指向相同的 物理地址 ,并且它们之间存在一对一的对应关系。查找是通过 Kernel Page Table 完成的,这可能是对 lookup_page(...)pte_get_page(...) 的两个调用所做的。