linux源代码版本号:2.6.36

CPU: x86的32位

pfn_to_page 函数困扰了我几天,每次查找都没有找到针对的地方。今天终于找到了,其实pfn_to_page不是真正的还是,而是宏。

该宏定义包含的头文件路径:include/asm-generic/memory_model.h

pfn_to_pag宏根据make menuconfig编译选项选择不同的函数,详细代码如下:

/*

--------------------------------------------------------------------------------------------------------------------------------

memory_model.h

--------------------------------------------------------------------------------------------------------------------------------

*/

#ifndef __ASM_MEMORY_MODEL_H
#define __ASM_MEMORY_MODEL_H

#ifndef __ASSEMBLY__

#if defined(CONFIG_FLATMEM)

#ifndef ARCH_PFN_OFFSET
#define ARCH_PFN_OFFSET         (0UL)
#endif

#elif defined(CONFIG_DISCONTIGMEM)

#ifndef arch_pfn_to_nid
#define arch_pfn_to_nid(pfn)    pfn_to_nid(pfn)
#endif

#ifndef arch_local_page_offset
#define arch_local_page_offset(pfn, nid)        \
        ((pfn) - NODE_DATA(nid)->node_start_pfn)
#endif

#endif /* CONFIG_DISCONTIGMEM */

/*
 * supports 3 memory models.
 */
#if defined(CONFIG_FLATMEM)

#define __pfn_to_page(pfn)      (mem_map + ((pfn) - ARCH_PFN_OFFSET))
#define __page_to_pfn(page)     ((unsigned long)((page) - mem_map) + \
                                 ARCH_PFN_OFFSET)
#elif defined(CONFIG_DISCONTIGMEM)

#define __pfn_to_page(pfn)                      \
({      unsigned long __pfn = (pfn);            \
        unsigned long __nid = arch_pfn_to_nid(__pfn);  \
        NODE_DATA(__nid)->node_mem_map + arch_local_page_offset(__pfn, __nid);\
})

#define __page_to_pfn(pg)                                               \
({      struct page *__pg = (pg);                                       \
        struct pglist_data *__pgdat = NODE_DATA(page_to_nid(__pg));     \
        (unsigned long)(__pg - __pgdat->node_mem_map) +                 \
         __pgdat->node_start_pfn;                                       \
})

#elif defined(CONFIG_SPARSEMEM_VMEMMAP)

/* memmap is virtually contiguous.  */
#define __pfn_to_page(pfn)      (vmemmap + (pfn))
#define __page_to_pfn(page)     (unsigned long)((page) - vmemmap)

#elif defined(CONFIG_SPARSEMEM)
/*
 * Note: section's mem_map is encorded to reflect its start_pfn.
 * section[i].section_mem_map == mem_map's address - start_pfn;
 */
#define __page_to_pfn(pg)                                       \
({      struct page *__pg = (pg);                               \
        int __sec = page_to_section(__pg);                      \
        (unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec)))
; \
})

#define __pfn_to_page(pfn)                              \
({      unsigned long __pfn = (pfn);                    \
        struct mem_section *__sec = __pfn_to_section(__pfn);    \
        __section_mem_map_addr(__sec) + __pfn;          \
})
#endif /* CONFIG_FLATMEM/DISCONTIGMEM/SPARSEMEM */

#define page_to_pfn __page_to_pfn
#define pfn_to_page __pfn_to_page

#endif /* __ASSEMBLY__ */

#endif

/*

--------------------------------------------------------------------------------------------------------------------------------

memory_model.h

--------------------------------------------------------------------------------------------------------------------------------

*/

pfn_to_page 函数相关推荐

  1. linux mips架构PHYS_OFFSET、CAC_BASE、HIGHMEM_START、PAGE_OFFSET、virt_to_phys、phys_to_virt、page_to_phys的定义

    在include/asm-mips/mach-generic/spaces.h中: #ifndef PHYS_OFFSET #define PHYS_OFFSET  _AC(0, UL) #endif ...

  2. Linux 设备驱动程序(三)

    系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核(一) 深入理解 Linux 内核(二) Linux 设备驱动程序(一) Linux 设备驱动程序(二) Linux 设备驱动程序( ...

  3. DMA、链式DMA、RDMA(精华讲解)

    一.DMA DMA全称Direct Memory Access,即直接存储器访问.CPU完成传输配置后,即可不在参与传输过程,由DMA控制器将数据从一个地址空间复制到另外一个地址空间.最常见的是本地D ...

  4. linux内核提供的内存操作函数

    1.kmalloc()/kfree()         static __always_inline void *kmalloc(size_t size, gfp_t flags)         内 ...

  5. linux brk函数,linux内存管理之sys_brk实现分析(续)

    unmap_region是整个收缩过程中的核心,它主要完成相应项表项的修改,具体映射页框的释放 代码如下: static void unmap_region(struct mm_struct *mm, ...

  6. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  7. Mysql函数group_concat、find_in_set 多值分隔字符字段进行数据库字段值翻译

    Mysql函数group_concat.find_in_set进行数据库字段值翻译 场景 配方表:记录包含的原料 sources表示原料,字段值之间用逗号分隔 原料表:对应原料id和原料名称 现需要查 ...

  8. C++ 笔记(34)— C++ exit 函数

    当遇到 main 函数中的 return 语句时,C++ 程序将停止执行.但其他函数结束时,程序并不会停止.程序的控制将返回到函数调用之后的位置.然而,有时候会出现一些非常少见的情况,使得程序有必要在 ...

  9. C++ 笔记(30)— 友元函数与友元类

    我们知道类的私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行.这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦. ...

  10. 浅显易懂 Makefile 入门 (07)— 其它函数(foreach 、if、call、origin )

    1. foreach 函数 foreach 函数定义如下: $(foreach <var>,<list>,<text>) 函数的功能是:把参数 <list&g ...

最新文章

  1. SQL字符串基本操作汇总
  2. tomcat设置自动监听替换class文件
  3. 交易性金融资产账务处理问题及改进
  4. 2017年09月23日普级组 环
  5. 我跑了ERNIE和BERT两个模型,结果出乎意料......
  6. 函数计算如何帮助语雀构建稳定且安全的业务架构?
  7. 【Android Studio安装部署系列】十三、Android studio添加和删除Module 2
  8. Java 异常处理机制
  9. python如果想测试变量的类型、可以使用_python里测试变量类型用什么
  10. FPGA实现低高速接口更新说明
  11. 层次化防御保证企业门户网站安全
  12. bash sbin/start-yarn.sh出现localhost: rcmd: socket: Permission denied
  13. Pixel 3a 开箱及 Google Fi 服务评测视频
  14. Atitit 软件知识点分类体系 分类 按照书籍的分类 学科分类 体系与基础部分 计算机体系结构 硬件接口技术(usb,agp,pci,div,hdmi) os操作系统 中间件 语言部分
  15. DEVC++中的 “万能头文件” <bits/stdc++.h>
  16. 第三十一章 与昔一何殊勇怯(一之全)
  17. Keras-训练网络时的问题:loss一直为nan,accuracy一直为一个固定的数
  18. html p首字母缩进,css如何控制首行缩进2个字符?
  19. php中表格标记是,HTML标记语言——表格标记_HTML/Xhtml_网页制作
  20. Adobe XD 下载和安装教程

热门文章

  1. 用Sql Server 2000的数据库备份来还原Sql Server 2005中的数据库
  2. FOREACH的遍历
  3. 明细表批量新增,修改,删除sql
  4. Laravel 5.3 windows环境安装
  5. iOS 客户端对于运营商劫持的一点点对抗方式
  6. MySQL字符集设置及字符转换(latin1转utf8)
  7. 局域网计算机不能共享常见问题
  8. 控制输入,非法字符不能输入到TextBox.
  9. 大数据与机器学习:实践方法与行业案例.1.4 本章小结
  10. Java制作证书的工具keytool用法总结