了解 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;
}
提前致谢。
评论说的地址一共有三种:
- 物理地址:这是真实地址,I.E.计算机物理内存中的真实准确位置。
- 内核虚拟地址:这是内核看到该物理地址的虚拟地址。
- 用户虚拟地址:这是用户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(...)
的两个调用所做的。
我对以下评论感到困惑:
/* 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;
}
提前致谢。
评论说的地址一共有三种:
- 物理地址:这是真实地址,I.E.计算机物理内存中的真实准确位置。
- 内核虚拟地址:这是内核看到该物理地址的虚拟地址。
- 用户虚拟地址:这是用户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(...)
的两个调用所做的。