pmd_alloc/pte_alloc/pud_alloc设置页表

本文详细介绍了ARM64架构的CPU在初始化过程中如何通过TCR寄存器设置MMU,以及与页表级别(PGTABLE_LEVELS)相关的pmd_t,pud_t,pgd_t的定义和动态分配过程。着重讨论了pgd_offset,pud_offset,pmd_offset等函数在内存管理中的作用。

aarm64为打开MMU而进行的CPU初始化

ARM64的启动过程之(三):为打开MMU而进行的CPU初始化

cpu确定当系统VA_BITS和PAGE_SIZE 通过寄存器TCR

aarch64的TCR寄存器介绍_arm tcr 寄存器-优快云博客

类型定义

arm64设置64K的页表,这种情况下PGTABLE_LEVELS = 3
//arch/arm64/include/asm/pgtable-types.h

typedef u64 pteval_t;
typedef u64 pmdval_t;
typedef u64 pudval_t;
typedef u64 p4dval_t;
typedef u64 pgdval_t;
 
typedef struct { pteval_t pte; } pte_t;

#if CONFIG_PGTABLE_LEVELS > 2           //大于2级页表才有pmd_t
typedef struct { pmdval_t pmd; } pmd_t;
#define pmd_val(x)      ((x).pmd)
#endif

#if CONFIG_PGTABLE_LEVELS > 3         //大于3级页表才有pud_t
typedef struct { pudval_t pud; } pud_t;
#define pud_val(x)      ((x).pud)
#endif

typedef struct { pgdval_t pgd; } pgd_t;  //pgd_t总是存在
#define pgd_val(x)      ((x).pgd)


#if CONFIG_PGTABLE_LEVELS == 2          //等于2级页表,则没有pmd,pud和p4d
#include <asm-generic/pgtable-nopmd.h>
	#include <asm-generic/pgtable-nopud.h>
	#define __PAGETABLE_PMD_FOLDED 1
	typedef struct { pud_t pud; } pmd_t;   //根据include关系:pmd_t 就是pud_t,pud_t又是p4d_t,p4d_t里面又是pgd_t
	#define set_pud(pudptr, pudval)                 set_pmd((pmd_t *)(pudptr), (pmd_t) { pudval })

	static inline pmd_t * pmd_offset(pud_t * pud, unsigned long address)
	{
			return (pmd_t *)pud;
	}
	
#elif CONFIG_PGTABLE_LEVELS == 3           //等于3级页表,则没有pud和p4d
#include <asm-generic/pgtable-nopud.h>
	#include <asm-generic/pgtable-nop4d.h>
	#define __PAGETABLE_PUD_FOLDED 1
	typedef struct { p4d_t p4d; } pud_t;
	#define pud_val(x)   (p4d_val((x).p4d))
	#define set_p4d(p4dptr, p4dval) set_pud((pud_t *)(p4dptr), (pud_t) { p4dval })

	static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
	{
			return (pud_t *)p4d;
	}

	
	
#elif CONFIG_PGTABLE_LEVELS == 4       //等于4级页表,则没有p4d
#include <asm-generic/pgtable-nop4d.h>
	#define __PAGETABLE_P4D_FOLDED 1
	typedef struct { pgd_t pgd; } p4d_t;
	#define p4d_val(x)   (pgd_val((x).pgd))
	#define set_pgd(pgdptr, pgdval) set_p4d((p4d_t *)(pgdptr), (p4d_t) { pgdval })

	static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address)
	{   
			return (p4d_t *)pgd; 
	} 
#endif

头文件关系: 

include/linux/pgtable.h
	#include <asm/pgtable.h>  //arch/arm64/include/asm/pgtable.h
	#include <asm/pgtable-hwdef.h>
	#include <asm/pgtable-prot.h>
[root@localhost linux-5.10]# grep -R "pgtable-types.h" arch/arm64/include/

arch/arm64/include/asm/kasan.h:#include <asm/pgtable-types.h>
arch/arm64/include/asm/pgtable-prot.h:#include <asm/pgtable-types.h>
arch/arm64/include/asm/page.h:#include <asm/pgtable-types.h>
arch/arm64/include/asm/mte.h:#include <asm/pgtable-types.h>
		
内核头文件使用架构相关的arch/arm64/include/asm/pgtable-types.h来根据PGTABLE_LEVELS来包含inc
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古井无波1999

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值