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

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

被折叠的 条评论
为什么被折叠?



