首页 > 系统相关 >内存管理-9-内存常用函数和宏

内存管理-9-内存常用函数和宏

时间:2024-07-01 16:09:38浏览次数:14  
标签:__ 常用 phys 函数 pfn 内存 include page define

基于msm-5.4

1. 页与页帧号转换

//include/asm-generic/memory_model.h
#define pfn_to_page(pfn)    (vmemmap + (pfn))
#define page_to_pfn(page)    (unsigned long)((page) - vmemmap)

注:使能了 CONFIG_SPARSEMEM_VMEMMAP 才使用的是这一组宏。vmemmap是一个struct page*类型的指针,实际上是当做数组使用。sizeof(page)=64,指针相减为偏移元素个数。


2. 页与物理地址转换

//include/linux/pfn.h
#define PFN_PHYS(x)    ((phys_addr_t)(x) << PAGE_SHIFT) //x<<12
#define PHYS_PFN(x)    ((unsigned long)((x) >> PAGE_SHIFT))

//include/asm-generic/memory_model.h
#define    __phys_to_pfn(paddr)    PHYS_PFN(paddr)
#define    __pfn_to_phys(pfn)    PFN_PHYS(pfn)

//arm64/include/asm/memory.h
#define page_to_phys(page)    (__pfn_to_phys(page_to_pfn(page)))
#define phys_to_page(phys)    (pfn_to_page(__phys_to_pfn(phys)))

//page_to_phys 展开后:(page - vmemmap) << PAGE_SHIFT)
//phys_to_page 展开后:vmemmap + (phys >> PAGE_SHIFT)

注:指针相减去,是struct page元素偏移个数,而不是单纯的数值相减。


3. 页与虚拟地址转换

//arm64/include/asm/memory.h
#define page_to_virt(x)    ({                        \
    __typeof__(x) __page = x;                    \
    u64 __idx = ((u64)__page - VMEMMAP_START) / sizeof(struct page);\
    u64 __addr = PAGE_OFFSET + (__idx * PAGE_SIZE);            \
    (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\
})
#define virt_to_page(x)    ({                        \
    u64 __idx = (__tag_reset((u64)x) - PAGE_OFFSET) / PAGE_SIZE;    \
    u64 __addr = VMEMMAP_START + (__idx * sizeof(struct page));    \
    (struct page *)__addr;                        \
})

//展开后为:

#define page_to_virt(x) \
(void *)(((u64)x - VMEMMAP_START)/sizeof(struct page) * PAGE_SIZE + PAGE_OFFSET)

#define virt_to_page(x) \
(struct page *)(VMEMMAP_START + ((((u64)x - PAGE_OFFSET) / PAGE_SIZE) * sizeof(struct page)))


4. page_address

实现是在 mm/highmem.c 中,返回page页映射的虚拟地址。实验,从伙伴系统中分配出页,其返回的虚拟地址与 page_to_virt(x) 返回的虚拟地址相等。

 

 

 

注:头文件包含关系

#include <linux/mm.h>
    #include <linux/mmdebug.h>
    #include <linux/gfp.h>
    #include <linux/bug.h>
    #include <linux/list.h>
    #include <linux/mmzone.h>
    #include <linux/rbtree.h>
    #include <linux/atomic.h>
    #include <linux/debug_locks.h>
    #include <linux/mm_types.h>
    #include <linux/mmap_lock.h>
    #include <linux/range.h>
    #include <linux/pfn.h>
    #include <linux/percpu-refcount.h>
    #include <linux/bit_spinlock.h>
    #include <linux/shrinker.h>
    #include <linux/resource.h>
    #include <linux/page_ext.h>
    #include <linux/err.h>
    #include <linux/page_ref.h>
    #include <linux/memremap.h>
    #include <linux/overflow.h>
    #include <linux/sizes.h>
    #include <linux/android_kabi.h>
    #include <linux/android_vendor.h>
    #include <asm/page.h>
        #include <linux/personality.h>
        #include <asm/pgtable-types.h>
        #include <asm/memory.h>
        #include <asm-generic/getorder.h>
    #include <asm/pgtable.h>
    #include <asm/processor.h>
    #include <linux/page-flags.h>
    #include <linux/huge_mm.h>

 

标签:__,常用,phys,函数,pfn,内存,include,page,define
From: https://www.cnblogs.com/hellokitty2/p/18278281

相关文章

  • 常用基础电子元器件及其作用
    一、概述罗列常用且基础的电子元器件,并简单说明其作用。二、相关电子元器件的概念1.电阻概念:作用:常见电阻: 2.电容概念:作用:常见电容 3.电感:电磁感应元件概念:作用:常见......
  • 常用正则表达式
    一、校验数字的表达式 1数字:^[0-9]*$ 2n位的数字:^\d{n}$ 3至少n位的数字:^\d{n,}$ 4m-n位的数字:^\d{m,n}$ 5零和非零开头的数字:^(0|[1-9][0-9]*)$ 6非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$ 7带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,......
  • C#常用的4种锁的使用以及解释
    1、lockinternalclassProgram{staticobjectlockObject=newobject();staticvoidMain(string[]args){Studentstudent=newStudent();Threadthread1=newThread(newThreadStart(Start1));......
  • 嵌入式Linux系统编程 — 5.5 sleep、usleep和nanosleep系统休眠函数
    目录1为什么需要休眠2 sleep、usleep和nanosleep函数2.1sleep函数2.2 usleep函数2.3 nanosleep函数3示例程序1为什么需要休眠有时需要将进程暂停或休眠一段时间,进入休眠状态之后,程序将暂停运行,直到休眠结束。以下是一些常见的休眠场景和作用:避免过载:在高......
  • 探索开源世界:常用的条形码图像处理库及其应用
                    在数字时代,条形码作为信息传输的重要媒介,其识别与处理技术显得尤为重要。无论是物流管理、库存控制,还是产品追溯,条形码的准确读取都是实现高效运营的关键。本文将带领大家走进开源软件的世界,探索那些优秀的条形码图像处理库,了解它们的特点、......
  • 01.Redis常用的一些命令
    简介:Redis是一款开源的使用ANSIC语言编写、遵守BSD协议、支持网络、可基于内存也可持久化的日志型、Key-Value高性能数据库。Redis与其他Key-Value缓存产品相比有以下三个特点:支持数据持久化,可以将内存中的数据保存在磁盘中,重启可再次加载使用支持简单的Key-Value类型的......
  • 【FreeRTOS】两个Delay函数
    目录0前言1Delay函数1.1两个Delay函数1.2总结2程序2.1函数修改2.2总结0前言在我们实际开发过程中,一般都用事件开发不要使用死循环1Delay函数1.1两个Delay函数FreeRTOS中有两个Delay函数:vTaskDelay:至少等待指定个数的TickInterrupt才能变为就绪......
  • 学懂C#编程:常用高级技术——学会C#的高级特性 反射
    反射(Reflection)是C#中的一项高级特性,它允许程序在运行时检查和操作程序集、模块、类型等元数据信息。通过反射,你可以在不知道类型信息的情况下,动态地创建对象、调用方法、访问属性等。反射的基本概念反射的核心在于System.Reflection命名空间,它提供了许多类和接口,用于获取类......
  • Swagger php注解常用语法梳理
    Swaggerphp注解常用语法梳理快速编写你的RESTFULAPI接口文档工具,通过注释定义接口和模型,可以和代码文件放置一起,也可以单独文件存放。Swagger优势通过代码注解定义文档,更容易保持代码文档的一致性模型复用,减少文档冗余,带来更可靠的文档提供客户端访问接口,可以直接......
  • 内联函数(inline)
    ①概念引入多用于复用性强的函数(代码量较少具有特定功能的函数)坏处:让你的代码上下文很臃肿(冗余)好处:在复用性强的函数调用的时候直接插入函数代码段而不是进行函数跳转(编译器弄的),减少性能消耗提高运行效率。减少函数调用开销:函数调用涉及压栈、跳转等操作,会产生......