I am confused about the following comment:
/* 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. */
I understand the first sentence which is to find the actual physical address, however, I don't understand why the kernel virtual address correspond to that address is returned. In short, since uaddr is a user virtual address, then why is it related to kernel virtual address?
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;
}
Thanks in advance.
There are three kinds of addresses that the comment is talking about:
So, with a simple ASCII art, this is the situation:
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 |
+-----------+ +-----------+ +-----------+
That function, given a valid user space virtual address, makes a lookup and retrieves the associated kernel space virtual address. This lookup can be done since both of them point to the same physical address, and there's a one-to-one correspondence between those. The lookup is done through the Kernel Page Table, which is probably what those two calls to lookup_page(...)
and pte_get_page(...)
do.