Linux内存管理相关宏和变量

1. #define VA_BITS (CONFIG_ARM64_VA_BITS)
虚拟地址宽度,最大值为48,比如配置为39,用户地址0- 0x0000007f_ffffffffff
内核空间地址为0xffffff80_00000000-0xfffffffff_fffffffff,分别为256G

#define VA_START (UL(0xffffffffffffffff) << VA_BITS)
内核虚拟地址起始地址:0xffffff80_00000000
#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1))

PHYS_OFFSET
	Physical start address of the first bank of RAM.

PAGE_OFFSET
	Virtual start address of the first bank of RAM.  During the kernel
	boot phase, virtual address PAGE_OFFSET will be mapped to physical
	address PHYS_OFFSET, along with any other mappings you supply.
	This should be the same value as TASK_SIZE.

2.

#define MODULES_END (PAGE_OFFSET)
#define MODULES_VADDR (MODULES_END - SZ_64M)

模块虚拟地址

//struct page 数组的大小
#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)

vmalloc 分配的起始地址
#define VMALLOC_START (KASAN_SHADOW_END + SZ_64K)


vmalloc分配结束地址
#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)


struct page数起始地址
#define VMEMMAP_START (VMALLOC_END + SZ_64K)

3.
memstart_addr为DDR的起始物理地址(base),vmemmap为什么减去起始ddr的物理地址 ?
在计算一个page的pfn时,都是基于系统的物理0地址,所以预先减去base,在进行page和pfn转换时,就可以直接相加/相减
pfn_to_page(pfn)  vmemmap + pfn ;如果不预先减去base,那么应该是vmemmap +(pfn- pfn_base)
#define vmemmap ((struct page *)VMEMMAP_START - \

SECTION_ALIGN_DOWN(memstart_addr >> PAGE_SHIFT))//__va

ARM64_HW_PGTABLE_LEVELS(va_bits):根据内核支持最大虚拟地址来确定页表级数

由于每级页表占用9bit,所以 (va_bits-PAGE_SHIFT)/(PAGE_SHIFT-3)

向上取整:((((va_bits) - PAGE_SHIFT) + (PAGE_SHIFT - 3) - 1) / (PAGE_SHIFT - 3))

 最后简化:(((va_bits) - 4) / (PAGE_SHIFT - 3))

所以就有 #define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))

ARM64_HW_PGTABLE_LEVEL_SHIFT(n) : 根据页表级n,计算出第n级页表bit偏移

#define PMD_SHIFT        ARM64_HW_PGTABLE_LEVEL_SHIFT(2) : PMD页表的偏移bit =21

#define PMD_SIZE        (_AC(1, UL) << PMD_SHIFT):一个PMD表项能标识的内存size = 2M

PGDIR_SIZE //一个PGD能表示的内存大小

PUD_SHIFT/PGDIR_SHIFT 类似PMD的理解.

pgd_offset_k(addr):根据虚拟地址addr获取对应的pgd项.

pmd_offset(addr): 根据虚拟地址addr,从pud中获取对应的pmd项

pmd_index(addr):根据虚拟地址addr,计算pmd的index

//把pud的物理地址设置到pgd项中.

static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
{
    set_pgd(pgd, __pgd(__pa(pud) | PUD_TYPE_TABLE));
}

//把pte的物理地址设置到pmd项中.

pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)

从上面可以看出pgd,pmd,pte中保存的内容都是物理地址

PTRS_PER_PGD: PGD项个数

PTRS_PER_PTE: PTE项个数

PTRS_PER_PMD:PMD项个数,这是三个一般都是相等且为(1<<9)

如果level为3,则PUD=1

 4.内存相关的debug目录
/proc/meminfo
/proc/pagetypeinfo
/proc/buddyinfo
/proc/slabinfo
/proc/vmstat                                                     
/proc/zoneinfo
/proc/vmallocinfo
/sys/kernel/slab    

/sys/kernel/debug/extfrag

/sys/kernel/debug/memblock

/proc/sys/vm


5.早期分配内存接口

early_alloc

6.sparse 内存模型

   #define SECTION_SIZE_BITS    30 //一个section的大小2的30次方=1G

  #define PAGES_PER_SECTION       (1UL << PFN_SECTION_SHIFT)//一个secion中的page数量

#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT)//把pfn转换成section号

#define NR_MEM_SECTIONS        (1UL << SECTIONS_SHIFT)//计算系统中section数量

7.分配内存的flags

/*
 * Watermark modifiers -- controls access to emergency reserves
 *
 * __GFP_HIGH indicates that the caller is high-priority and that granting
 *   the request is necessary before the system can make forward progress.
 *   For example, creating an IO context to clean pages.
 *
 * __GFP_ATOMIC indicates that the caller cannot reclaim or sleep and is
 *   high priority. Users are typically interrupt handlers. This may be
 *   used in conjunction with __GFP_HIGH
 *
 * __GFP_MEMALLOC allows access to all memory. This should only be used when
 *   the caller guarantees the allocation will allow more memory to be freed
 *   very shortly e.g. process exiting or swapping. Users either should
 *   be the MM or co-ordinating closely with the VM (e.g. swap over NFS).
 *
 * __GFP_NOMEMALLOC is used to explicitly forbid access to emergency reserves.
 *   This takes precedence over the __GFP_MEMALLOC flag if both are set.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值