2

我对以下评论感到困惑:

/* 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. */

我理解第一句话是找到实际的物理地址,但是,我不明白为什么会返回与该地址相对应的内核虚拟地址。总之,既然 uaddr 是一个用户虚拟地址,那它为什么和内核虚拟地址有关呢?

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;
}

提前致谢。

4

1 回答 1

1

评论中提到了三种地址:

  1. 物理地址:这是真正的地址,即在你的计算机物理内存中真正的确切位置。
  2. 内核虚拟地址:这是内核看到该物理地址的虚拟地址。
  3. 用户虚拟地址:这是用户空间程序看到该物理地址的虚拟地址。

因此,使用简单的 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 |
+-----------+    +-----------+    +-----------+

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

于 2019-07-24T15:34:24.160 回答