简体   繁体   English

linux 内核函数 page_address()

[英]linux kernel function page_address()

I'm confused with the function:我对函数感到困惑:

void * page_address(struct page *page)

which (1) "convert a given page to its logical address" according to "Linux Kerenl developement 3rd edition" (2) "returns the linear address associated with the page frame" according to "understanding the linux kernel>>" (3) "returns the physical address of the page" according to "understanding the linux virtual memory manager"其中(1)根据“Linux Kerenl development 3rd edition”(2)“将给定页面转换为其逻辑地址”(2)根据“了解 linux 内核>>”(3)“返回与页面框架关联的线性地址”根据“了解linux虚拟内存管理器”,“返回页面的物理地址”

which one is correct then?那么哪个是正确的呢?

Let's take (1): this function takes a pointer to the physical page (page frame), isn't that pointer the "logical address associated with that page frame" already?让我们来看看(1):这个函数接受一个指向物理页面(页框)的指针,那个指针不是已经是“与该页框关联的逻辑地址”了吗? what's the difference between that pointer value and the returned value then?那指针值和返回值有什么区别呢? thanks.谢谢。

1 and 2 are both correct - they are two ways of saying the same thing (although explanation 2 is clearer). 1 和 2 都是正确的——它们是表达同一事物的两种方式(尽管解释 2 更清楚)。 Explanation 3 is incorrect - page_address() returns the virtual address, not the physical address, of the page frame.解释 3 不正确 - page_address()返回页框的虚拟地址,而不是物理地址。

page_address() does not take a pointer to the page / page frame. page_address()接受指向页面/页面框架的指针。 It takes a pointer to the struct page , which is a kernel data object that represents the page.它接受一个指向struct page的指针,它是一个表示页面的内核数据对象。

page_address() returns virtual address of the page. page_address() 返回页面的虚拟地址。

http://lxr.free-electrons.com/source/mm/highmem.c#L408 http://lxr.free-electrons.com/source/mm/highmem.c#L408

/**
 * page_address - get the mapped virtual address of a page
 * @page: &struct page to get the virtual address of
 *
 * Returns the page's virtual address.
 */
 void *page_address(const struct page *page)
 {
          unsigned long flags;
          void *ret;
          struct page_address_slot *pas;

          if (!PageHighMem(page))
                  return lowmem_page_address(page);

          pas = page_slot(page);
          ret = NULL;
         spin_lock_irqsave(&pas->lock, flags);
         if (!list_empty(&pas->lh)) {
                 struct page_address_map *pam;

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

page_address() returns the physical address, not the virtual address: page_address() 返回物理地址,而不是虚拟地址:

https://www.kernel.org/doc/gorman/html/understand/understand023.html https://www.kernel.org/doc/gorman/html/understand/understand023.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM