Copy from :https://blog.csdn.net/tiantao2012/article/details/79135396
void *page_address(const struct page *page) 这个函数用于得到页的虚拟地址,这里的页可以是高端页或者低端页
其源码分析如下:
void *page_address(const struct page *page)
{
unsigned long flags;
void *ret;
struct page_address_slot *pas;
#可以看到这个函数的形参可以是高端页或者低端页。如果是低端页的话,直接调用lowmem_page_address 返回页的地址
if (!PageHighMem(page))
return lowmem_page_address(page);
#根据page地址得到page_address_slot
pas = page_slot(page);
ret = NULL;
#使用page_address_slot的成员变量lock来保护。看来page_address_slot是临界变量,需要锁保护
spin_lock_irqsave(&pas->lock, flags);
if (!list_empty(&pas->lh)) {
struct page_address_map *pam;
#所有的page_address_map是在lh这个list上,所以这里遍历这个list,看已经映射了页中是否有形参page。
#如果找到在已经映射的page中找到形参page,则返回这个页对应的虚拟地址,否则返回null.
list_for_each_entry(pam, &pas->lh, list) {
if (pam->page == page) {
ret = pam->virtual;
goto done;
}
}
}
done:
spin_unlock_irqrestore(&pas->lock, flags);
return ret;
}
这里的lowmem_page_address 函数如下,可以看到低端页都已经有虚拟地址了,只要转换一下就可以了.
static __always_inline void *lowmem_page_address(const struct page *page)
{
return page_to_virt(page);
}
————————————————
版权声明:本文为CSDN博主「tiantao2012」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tiantao2012/article/details/79135396