页表结构详细说明

一、页表

1. 内存地址的分解

我们知道linux采用了分页机制,通常采用四级页表,页全局目录(PGD),页上级目录(PUD),页中间目录(PMD),页表(PTE)。如下:
在这里插入图片描述

其含义定义在arch/arm64/include/asm/pgtable-hwdef.h文件中:

CONFIG_PGTABLE_LEVELS				//页表级数

//offset
#define PAGE_SHIFT		CONFIG_ARM64_PAGE_SHIFT			//页offset,为12
#define PAGE_SIZE		(_AC(1, UL) << PAGE_SHIFT)		//页大小,为4k

//PTE
#define PTRS_PER_PTE		(1 << (PAGE_SHIFT - 3))		//PTE位数,为9

#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)

//PMD
#if CONFIG_PGTABLE_LEVELS > 2
#define PMD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(2)
#define PMD_SIZE		(_AC(1, UL) << PMD_SHIFT)		//2M
#define PMD_MASK		(~(PMD_SIZE-1))
#define PTRS_PER_PMD		PTRS_PER_PTE				//PMD位数,为9
#endif

//PUD
#if CONFIG_PGTABLE_LEVELS > 3
#define PUD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(1)
#define PUD_SIZE		(_AC(1, UL) << PUD_SHIFT)		//1G
#define PUD_MASK		(~(PUD_SIZE-1))
#define PTRS_PER_PUD		PTRS_PER_PTE				//PUD位数,为9
#endif

//PGD
#define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))  //4096 
#define VA_BITS			(CONFIG_ARM64_VA_BITS)		//4级页表为48,3级页表为39
#define PGDIR_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS)
#define PGDIR_SIZE		(_AC(1, UL) << PGDIR_SHIFT)		
#define PGDIR_MASK		(~(PGDIR_SIZE-1))
#define PTRS_PER_PGD		(1 << (VA_BITS - PGDIR_SHIFT))

看到这里我们知道4级页表虚拟地址为48位,页全局目录(PGD),页上级目录(PUD),页中间目录(PMD),页表(PTE)都是9位,offset是12位。但是有些系统是使用3级页表的,那么他的虚拟地址为39位,页全局目录(PGD),页中间目录(PMD),页表(PTE)都是9位,offset是12位,也就是说,少了页上级目录(PUD)。其实我们使用3级页表就够了,39为的虚拟地址可以操作512g的内存,是完全够用的。我们国产操作系统就是使用3级页表的。最后说明一下。无论是3级页表还是4级页表,我们的物理地址都是48位的。

1.2 页表的数据结构

我们已经确立了页表项的数目,但没有定义其结构。内核提供了4个数据结构(定义在 arch/arm64/include/asm/pgtable-types.h中)来表示页表项的结构。

typedef struct { pteval_t pte; } pte_t;
#define pte_val(x)	((x).pte)
#define __pte(x)	((pte_t) { (x) } )

#if CONFIG_PGTABLE_LEVELS > 2
typedef struct { pmdval_t pmd; } pmd_t;
#define pmd_val(x)	((x).pmd)
#define __pmd(x)	((pmd_t) { (x) } )
#endif

#if CONFIG_PGTABLE_LEVELS > 3
typedef struct { pudval_t pud; } pud_t;
#define pud_val(x)	((x).pud)
#define __pud(x)	((pud_t) { (x) } )
#endif

typedef struct { pgdval_t pgd; } pgd_t;
#define pgd_val(x)	((x).pgd)
#define __pgd(x)	((pgd_t) { (x) } )

typedef struct { pteval_t pgprot; } pgprot_t;
#define pgprot_val(x)	((x).pgprot)
#define __pgprot(x)	((pgprot_t) { (x) } )

typedef u64 pteval_t;
typedef u64 pmdval_t;
typedef u64 pudval_t;
typedef u64 pgdval_t;

从代码中我们看到了以下东西:

  1. 页表项的结构
    pgd_t 用于全局页目录项。
    pud_t 用于上层页目录项。
    pmd_t 用于中间页目录项。
    pte_t 用于直接页表项。
页表项的结构pgd_t 用于全局页目录项。pud_t 用于上层页目录项。pmd_t 用于中间页目录项。pte_t 用于直接页表项。

1.3 特定于页表的信息

arch/arm64/include/asm/pgtable-hwdef.h

/*
 * Level 3 descriptor (PTE).
 */
#define PTE_TYPE_MASK		(_AT(pteval_t, 3) << 0)
#define PTE_TYPE_FAULT		(_AT(pteval_t, 0) << 0)
#define PTE_TYPE_PAGE		(_AT(pteval_t, 3) << 0)
#define PTE_TABLE_BIT		(_AT(pteval_t, 1) << 1)
#define PTE_USER		(_AT(pteval_t, 1) << 6)		/* AP[1] */
#define PTE_RDONLY		(_AT(pteval_t, 1) << 7)		/* AP[2] */
#define PTE_SHARED		(_AT(pteval_t, 3) << 8)		/* SH[1:0], inner shareable */
#define PTE_AF			(_AT(pteval_t, 1) << 10)	/* Access Flag */
#define PTE_NG			(_AT(pteval_t, 1) << 11)	/* nG */
#define PTE_DBM			(_AT(pteval_t, 1) << 51)	/* Dirty Bit Management */
#define PTE_CONT		(_AT(pteval_t, 1) << 52)	/* Contiguous range */
#define PTE_PXN			(_AT(pteval_t, 1) << 53)	/* Privileged XN */
#define PTE_UXN			(_AT(pteval_t, 1) << 54)	/* User XN */
#define PTE_HYP_XN		(_AT(pteval_t, 1) << 54)	/* HYP XN */

/*
 * Level 2 descriptor (PMD).
 */
#define PMD_TYPE_MASK		(_AT(pmdval_t, 3) << 0)
#define PMD_TYPE_FAULT		(_AT(pmdval_t, 0) << 0)
#define PMD_TYPE_TABLE		(_AT(pmdval_t, 3) << 0)
#define PMD_TYPE_SECT		(_AT(pmdval_t, 1) << 0)
#define PMD_TABLE_BIT		(_AT(pmdval_t, 1) << 1)

#define PUD_TYPE_TABLE		(_AT(pudval_t, 3) << 0)
#define PUD_TABLE_BIT		(_AT(pudval_t, 1) << 1)
#define PUD_TYPE_MASK		(_AT(pudval_t, 3) << 0)
#define PUD_TYPE_SECT		(_AT(pudval_t, 1) << 0)

还有一些用于处理内存页的体系结构相关状态的函数:

函数描述
pte_present页在内存中吗
pte_read从用户空间可以读取该页吗
pte_write可以写入到该页吗
pte_exec该页中的数据可以作为二进制代码执行吗
pte_dirty页是脏的吗?其内容是否修改过
pte_file该页表项属于非线性映射吗
pte_young访问位(通常是_ PAGE_ACCESS )设置了吗
pte_rdprotect清除该页的读权限
pte_wrprotect清除该页的写权限
pte_exprotect清除执行该页中二进制数据的权限
pte_mkread设置读权限
pte_mkwrite设置写权限
pte_mkexec允许执行页的内容
pte_mkdirty将页标记为脏
pte_mkclean“清除”页,通常是指清除 _PAGE_DIRTY 位
pte_mkyoung设置访问位,在大多数体系结构上是 _PAGE_ACCESSED
pte_mkold清除访问位
以上函数一般是用于设置、删除、查询某个特定的属性(例如,页的写权限)。

1.4 页表的格式、

ARM64 处理器把页表称为转换表( translation table ),最多 4 级。分别是页全局目录(PGD),页上级目录(PUD),页中间目录(PMD),页表(PTE)。ARM64 处理器把表项称为描述符( descriptor ),使用 64 位的长描述符格式。描述符的第 0 位指示描述符是不是有效的: 0 表示无效, 1 表示有效;第 1 位指定描述符类型。

  1. 页目录项,就是在页全局目录(PGD),页上级目录(PUD),页中间目录(PMD)中, 0 表示块( block )描述符, 1 表示表( table )描述符。块描述符存放一个内存块(即巨型页)的起始地址,表描述符存放下一级转换表的地址。
  2. 页目表项,就是页表(PTE), 0 表示保留描述符, 1 表示页描述符。

1.4.1 页目录项

  1. 无效描述符:无效描述符的第 0 位是 0 。
    在这里插入图片描述

  2. 块描述符:块描述符的最低两位是 01。
    在这里插入图片描述

  3. 表描述符:表描述符的最低两位是 11。
    在这里插入图片描述

1.4.2 页目表项

  1. 无效描述符:无效描述符的第 0 位是 0。
    在这里插入图片描述

  2. 保留描述符:保留描述符的最低两位是 01。
    在这里插入图片描述

  3. 页描述符:页描述符的最低两位是 11
    在这里插入图片描述

无论是页目录项的块描述符还是页表项的页描述符,都是表示一个整体的内存;块描述符一般用于巨型页,而页描述符用于普通页。
他们的内存属性被拆分成一个高属性块和一个低属性块,具体可以看下面的图和表:
在这里插入图片描述

位数含义
59 ~ 62基于页的硬件属性( Page-Based Hardware Attributes ),如果没有实现 ARMv8.2-TTPBHA ,忽略。
55 ~ 58保留给软件使用。
54在异常级别 0 ,表示 UXN ( Unprivileged execute-Never ),即不允许异常级别0 执行内核代码;在其他异常级别,表示 XN ( execute-Never ),不允许执行。
53PXN ( Privileged execute-Never ),不允许在特权级别(即异常级别 1/2/3 )执行。
52连续( Contiguous ),指示这条转换表项属于一个连续表项集合,一个连续表项集合可以被缓存在一条 TLB 表项里面
51脏位修饰符( Dirty Bit Modifier , DBM ),指示页或内存块是否被修改过。
11非全局( not global , nG )。 nG 位是 1 ,表示转换不是全局的,是进程私有的,有一个关联的地址空间标识符( Address Space Identifier , ASID ); nG 位是 0 ,表示转换是全局的,是所有进程共享的,内核的页或内存块是所有进程共享的。
10访问标志( Access Flag , AF ),指示页或内存块自从相应的转换表描述符中的访问标志被设置为 0 以后是否被访问过。
8 ~ 9可共享性( SHareability , SH ), 00 表示不共享, 01 是保留值, 10 表示外部共享, 11 表示内部共享。
6 ~ 7AP[2:1] ( Data Access Permissions ,数据访问权限)。AP[2] 用来选择只读或读写, 1 表示只读, 0 表示读写; AP[1] 用来选择是否允许异常级别 0 访问, 1 表示允许异常级别 0 访问, 0 表示不允许异常级别 0 访问。
5非安全( Non-Secure , NS )。对于安全状态的内存访问,指定输出地址在安全地址映射还是在非安全地址映射。
2 ~ 4内存属性索引( memory attributes index , AttrIndx ),指定寄存器 MAIR_ELx中内存属性字段的索引,内存属性间接寄存器( Memory Attribute Indirection Register ,MAIR_ELx )有 8 个 8 位内存属性字段: Attr , n 等于 0 ~ 7 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/13063.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HCIP-6.9BGP路由反射器原理与配置

路由反射器原理与配置 1、路由反射器概念1.1、路由反射器原理&#xff1a;1.2、多集群路由反射器1.3、备份路由反射器2、路由反射器配置3、路由反射器防环机制 1、路由反射器概念 IBGP的水平分割&#xff0c;IBGP 1只能update一跳&#xff0c;就是说在IBGP 2 设备收到IBGP 1设…

密码学|DES加密算法|学习记录

DES简介 DES属于对称密码算法中的分组加密算法 密钥一共64bit&#xff0c;其中56位参与运算&#xff0c;其余8bit为校验位&#xff08;8 16 24 32 40 48 56 64&#xff09; n个64位明块经过加密后得到的n个64位密文块加在一起就是密文 DES一般步骤 IP置换 &#xff1a; IP置…

Python中的异常——概述和基本语法

Python中的异常——概述和基本语法 摘要&#xff1a;Python中的异常是指在程序运行时发生的错误情况&#xff0c;包括但不限于除数为0、访问未定义变量、数据类型错误等。异常处理机制是Python提供的一种解决这些错误的方法&#xff0c;我们可以使用try/except语句来捕获异常并…

AI已经解锁自动化能力 | 颠覆商业模式和劳动力市场

AI已经解锁自动化能力&#xff0c;将颠覆商业模式和劳动力市场。目前AutoGPT的开源项目&#xff1a; BabyAGI、Auto-GPT、AgentGPT、TeenagerAGI、Jarvis。 AutoGPT原理&#xff1a; 3个GPT4协同合作&#xff0c;一个GPT4负责分解目标创建任务&#xff0c;另一个GPT4负责分配…

C# switch case语句入门and业务必知点

具体的语法形式如下。 switch(表达式) { case 值 1: 语句块 1; break; case 值 2: 语句块 2; break; ... default: 语句块 n; break; } 在这里&#xff0c;switch 语句中表达式的结果必须是整型、字符串…

Linux用户的分类与家目录,ls、pwd、cd、mkdir、touch、rmdir、rm指令与选项等

Linux中用户的分类与用户的家目录 在Linux当中&#xff0c;用户的分类只分为两类&#xff0c;一类叫做超级用户root&#xff0c;还有就是其他也就是传说中的普通用户。我们刚刚登进去时&#xff0c;默认所处的目录是***/root或者/home/用户名***&#xff0c;比如说/root, /hom…

Unity InputSystem (一)

什么是InputSystem InputSystem 是 2019 年 Unity 新推出的插件&#xff0c;输入系统包实现了一个系统来使用任何类型的输入设备来控制你的 Unity 内容。它旨在成为 Unity 的经典输入管理器更强大、更灵活、更可配置的替代品。 新输入系统基于事件&#xff0c;输入设备和动作逻…

信安大佬真的用kali吗?

Kali只是现在网络安全和kali比较火的一个操作系统 下面我为大家讲讲kali系统都有那些优点 Kali介绍Kali Linux是基于Debian的Linux发行版&#xff0c; 设计用于数字取证操作系统。面向专业的渗透测试和安全审计。 集成化&#xff1a;预装超过300个渗透测试工具兼容好&#x…

【JavaEE】File、InputStream和OutputStream的使用

1.File 在计算机中目录结构如下&#xff1a; 而File就表示一个目录或者一个普通文件。 File表示目录&#xff1a; File表示普通文件&#xff1a; 我们先来看File的构造方法&#xff1a; 构造器描述File(File parent, String child)根据父目录 孩子文件路径&#xff0c;创…

ROS学习第九节——服务通信

1.基本介绍 服务通信较之于话题通信更简单些&#xff0c;理论模型如下图所示&#xff0c;该模型中涉及到三个角色: ROS master(管理者)Server(服务端)Client(客户端) ROS Master 负责保管 Server 和 Client 注册的信息&#xff0c;并匹配话题相同的 Server 与 Client &#…

如何在不丢失数据的情况下重装Windows 10?

为什么需要重新安装Windows 10&#xff1f; 随着时间的推移&#xff0c;Windows可能会变慢。这可能是由多种原因引起的&#xff0c;例如您安装了许多额外的启动程序&#xff0c;这些程序会延长启动过程等。如果您的Windows系统速度变慢并且无论您卸载多少程序都没有加速&…

Pixhawk基础—认识Pixhawk

Pixhawk简介 pixhawk是由3DR联合APM小组与PX4小组于2014年推出的飞控PX4的升级版&#xff0c;它同时拥有PX4和APM两套固件和相应的地面站软件。该飞控是目前全世界飞控产品中硬件规格最高的产品。 Pixhawk基础 端口介绍 1、Spektrum DSM receiver(Spektrum DSM信号转换为PWM…

PXE+Kickstart自动化安装操作系统

文章目录 PXEKickstart 完美自动化部署系统理论知识&#xff1a;1、PXE2、DHCP 实践实验&#xff1a;1、DHCP服务器配置2、TFTP服务器配置3、HTTP服务器安装4、PXE配置5、Kickstart实践配置 PXEKickstart 完美自动化部署系统 理论知识&#xff1a; 无人值守原理&#xff1a;K…

思科实验 EIGRP

1.1.1 实验目的 通过对 CCNA 课程中的 EIGRP 实验部分进行回顾&#xff0c;从而更加准确掌握 EIGRP 路由协议的 配置方法&#xff0c;以及对 network 命令的正确理解。并且学会对 EIGRP 路由协议查看排错的相关命 令。 1.1.2 实验拓扑 拓扑说明&#xff1a;本实验由两台思科路…

第七章 法律行为与法律意识

目录 第一节 法律行为 一、 法律行为的含义与特征二、 法律行为的结构 &#xff08;一&#xff09;法律行为的内在方面 动机目的认知能力 &#xff08;二&#xff09;法律行为的外在方面 行动&#xff08;行为&#xff09;手段结果 三、法律行为的分类 第二节 法律意识 一、法…

Qt Quick - PageIndicator

Q 理论使用总结 一、概述二、简单使用例子1. SwipeView 和 PageIndicator2. StackLayout 和 PageIndicator 三、常用属性四、定制化 一、概述 PageIndicator用于指示含有多个页面的容器中&#xff0c;当前处理活动的页。记住&#xff0c;这个只是指示当前的活动页&#xff0c;…

4个Python库来美化你的Matplotlib图表

Matplotlib是一个被广泛使用的Python数据可视化库&#xff0c;相信很多人都使用过。 但是有时候总会觉得&#xff0c;Matplotlib做出来的图表不是很好看、不美观。 今天就给大家分享四个美化Matplotlib图表的Python库&#xff0c;它们可以轻松让你的Matplotlib图表变得好看&…

【进阶C语言】有关动态内存管理的经典笔试题(详细图文讲解)

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于C语言进阶系列&#xff0c;本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数…

ActiveMQ使用

一、什么是消息中间件 消息中间件顾名思义实现的就是在两个系统或两个客户端之间进行消息传送 二、什么是ActiveMQ ActiveMQ是一种开源的基于JMS&#xff08;Java Message Servie&#xff09;规范的一种消息中间件的实现&#xff0c;ActiveMQ的设计目标是提供标准的&#xff0c…

4.23、TCP状态转换(为什么四次挥手)

4.23、TCP状态转换 1.TCP状态转换图2.为什么需要四次挥手&#xff0c;状态转换 1.TCP状态转换图 2.为什么需要四次挥手&#xff0c;状态转换 2MSL&#xff08;Maximum Segment Lifetime&#xff09; 主动断开连接的一方, 最后进入一个 TIME_WAIT状态, 这个状态会持续: 2msl ms…