首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux的页表

Linux的页表是操作系统用于管理虚拟内存到物理内存映射的数据结构。以下是关于Linux页表的基础概念、优势、类型、应用场景以及可能遇到的问题和解决方法:

基础概念

  1. 虚拟内存:操作系统提供的一种计算机技术,让应用程序认为它拥有连续的可用内存空间,而实际上这些空间可能被分割成多个物理内存碎片,甚至部分存储在磁盘上。
  2. 物理内存:计算机实际的RAM(随机存取存储器)。
  3. 页表:用于存储虚拟地址到物理地址映射的数据结构。

优势

  • 内存保护:不同进程的页表可以设置不同的访问权限,防止一个进程访问另一个进程的内存。
  • 内存管理:操作系统可以通过页表动态地分配和回收内存。
  • 虚拟化:通过页表,操作系统可以为每个进程提供独立的虚拟地址空间。

类型

Linux主要使用以下几种页表:

  1. 一级页表:最简单的页表结构,适用于内存较小的系统。
  2. 多级页表:如二级、三级或四级页表,适用于内存较大的系统,可以减少页表占用的空间。
    • PGD(Page Global Directory):一级页表。
    • PUD(Page Upper Directory):二级页表。
    • PMD(Page Middle Directory):三级页表。
    • PTE(Page Table Entry):四级页表,存储具体的虚拟地址到物理地址的映射。

应用场景

  • 进程切换:操作系统在切换进程时,需要切换页表以反映新进程的虚拟地址空间。
  • 内存映射文件:通过页表将文件内容映射到内存中,实现高效的文件读写操作。
  • 共享内存:多个进程可以通过页表共享同一块物理内存区域。

可能遇到的问题及解决方法

  1. 页表项缺失
    • 现象:访问内存时发生缺页异常。
    • 原因:页表中没有对应的页表项。
    • 解决方法:操作系统通过缺页处理程序加载缺失的页面到内存,并更新页表。
  • 页表项权限错误
    • 现象:访问内存时发生权限错误。
    • 原因:页表项中的权限设置不正确。
    • 解决方法:检查并修正页表项的权限设置。
  • 页表过大
    • 现象:页表占用过多内存,影响系统性能。
    • 原因:使用了一级页表或页表项过大。
    • 解决方法:使用多级页表结构,减少单级页表的大小。

示例代码

以下是一个简单的示例代码,展示如何在Linux内核中创建和访问页表项:

代码语言:txt
复制
#include <linux/mm.h>
#include <linux/slab.h>

// 创建页表项
pgd_t *create_pgd(void) {
    pgd_t *pgd = kmalloc(sizeof(pgd_t), GFP_KERNEL);
    if (!pgd)
        panic("Failed to allocate PGD");
    return pgd;
}

// 设置页表项
void set_pte(pgd_t *pgd, unsigned long virt_addr, unsigned long phys_addr) {
    p4d_t *p4d = pgd + (virt_addr >> 21);
    pud_t *pud = p4d + (virt_addr >> 12 & 0x1FF);
    pmd_t *pmd = pud + (virt_addr >> 6 & 0x1FF);
    pte_t *pte = pmd + (virt_addr & 0x3F);

    set_pte_at(&init_mm, virt_addr, pte, pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL));
}

// 示例调用
void example(void) {
    pgd_t *pgd = create_pgd();
    unsigned long virt_addr = 0x1000;
    unsigned long phys_addr = 0x2000;

    set_pte(pgd, virt_addr, phys_addr);
}

这个示例展示了如何在Linux内核中创建页表项并设置虚拟地址到物理地址的映射。实际应用中需要更多的错误处理和内存管理代码。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

页表与三级页表介绍

在操作系统与计组学习中,我们会学习到页表这个概念,可以说,如今计算机的函数内存调用有很大一部分都离不开页表的调用,本文旨在详解页表的概念应用以及操作系统中的三级页表,三级页表对于节省空间起了至关重要的作用...三级页表 所谓三级页表,就是将原来的虚拟地址的页码27位分为三级,每一级9位: 而原来的页表工作流程也变为下图: 通过虚拟地址转换时,首先通过前9位页码找到第一层页目录,第一层页目录中包含了中间页表的物理地址...,通过物理地址找到中间页表,再通过中间页表的44位物理地址找到底层页表,底层页表的44位物理地址便指向了最后的实际调用物理地址,将此物理地址+原来虚拟地址的offset偏移量便找到了最后的实际地址,这里的物理地址表示为...: 物理地址(56位) = 底层页表PPN(44位) + 虚拟地址offset(12位) 在三级页表的基础上,假设只使用了几个页面,那么中间层页表只需要加载0号页表即可,底层页表只需要加载要使用的几个页表项即可...至此,有关于页表与三级页表的介绍就到这里了,页表的存在对于内核区与用户区加载代码起了至关重要的作用,真正理解页表的转换机制有助于我们对操作系统的虚拟内存有更深刻的认识

24710

Linux内核页表管理-那些鲜为人知的秘密

,而页表管理是在虚拟内存管理中尤为重要,本文主要以回答几个页表管理中关键性问题来解析Linux内核页表管理,看一看页表管理中那些鲜为人知的秘密。...Linux内核为何使用多级页表?...2)使用多级页表结构优劣: 优势: 1.节省内存 2.可以按需分配各级页表 3.可以离散存储页表 劣势: 需要遍历多级页表,需要多次访问内存,实现复杂度高点 3)Linux内核综合考虑: 典型的以时间换空间...2)Linux内核 填写页表,将页表基地址告诉mmu 内核初始化建立内核页表,实现缺页异常等机制为用户任务按需分配并映射页表。 当然,内核也可以遍历页表,如缺页异常时遍历进程页表。 10...., PMD),直接页表(Page Table, PT),而支持arm64的linux使用4级页表结构分别是 pgd, pud, pmd, pt ,arm64手册中将他们分别叫做L0,L1,L2,L3级转换表

1.9K22
  • 多级页表的好处

    ,如果只使用了一个页表,一个表项的大小为4byte,32位系统有4GB的物理空间(一个进程看到是4GB大小的虚拟空间),每一个表项对应着物理空间的第xxx页(4KB大小的页),那么应该有4GB/4KB=...如果是二级页表,规则就会改变,让二级页表对应到物理内存上的4KB大小的页,一级页表此时变成映射为物理地址的4MB(这样子是无法定位到具体的页(4KB)的,所以二级页表再去找),这样先找到一级页表,一级页表再和二级页表进行结合...,二级页表相当于一级页表4MB分成了1024个(1KB个)4KB,找完后二级页表充当了offset的角色,此时定位到具体的4KB的页面,再用一级页表的offset一结合定位到具体物理地址。...这样一个进程浪费掉的空间是一级页表占用的:(4GB/4MB)*4byte=4KB,二级页表浪费掉的是1kb(1个一级页表占用这么多)*1kb(此时有1kb(4GB/4MB)个一级页表)=4MB,加起来是...4MB+4KB,比光用一级页表要多4KB,但是2级页表是可以不存在的,比如此时程序只用了%20的页,那么4MB就需要乘以%20,这样一下子就比只有一级页表时少了。

    1.7K30

    一文看懂影子页表和扩展页表

    二.影子页表 (Shadow page table) 影子页表我用一句话来描述就是:VMM把Guest和Host中的页表合并成一个页表,称为影子页表,来实现GVA->HPA映射。...3, HVA->HPA,这一过程就是我们已知的使用物理MMU完成VMM进程的虚拟内存到物理内存的转换。 4, 把GVA -> HPA,这一路的映射关系记录到页表中,这个页表就是影子页表。...虚拟机页表和影子页表通过一个哈希表建立关联(当然也有其他的关联方式),客户机操作系统把当前进程的页表基址载入PDBR时而VMM将会截获这一特权指令,将进程的影子页表基址载入客户机PDBR,使客户机在恢复运行时...Guest运行时,Guest页表被载入PDBR,而 EPT 页表被载入专门的EPT 页表指针寄存器 EPTP。...找到了页目录的HPA基地址,再通过GVA中的Directory offset段,就找到页表的VGA了,这个页表VGA再去EPT中进行GPA->HPA的转换,就找到页表VGA的HPA了。

    2.4K20

    Linux从头学16:操作系统-如何把【页目录和页表】当做普通物理页进行操作的?

    对页表进行"自操作" 在 x86 系统中,内存管理中的分页机制是非常重要的,在Linux操作系统相关的各种书籍中,这部分内容也是重笔浓彩。...如果你看过 Linux 内核相关书籍,一定对下面这张图又熟悉、又恐惧: 这是 Linux 系统中,页处理单元的多级页表查询方式。...其中黄色背景部分:页上级目录索引 和 页中间目录索引,是 Linux 系统自己扩展的,在原本的 x86 处理器中是不存在的,这也是导致 Linux 中相关部分代码更加复杂的原因。...文章链接在此:Linux从头学15:【页目录和页表】-理论 + 实例 + 图文的最完全、最接地气详解!,但是其中有一个环节被特意忽略过去了。...详细的讨论过程,请参考上一篇文章:Linux从头学15:【页目录和页表】-理论 + 实例 + 图文的最完全、最接地气详解!。

    1.7K20

    内核页表调试

    page映射区,linux内核用page结构体管理所有物理内存,每一页大小为PAGE_SIZE对于arm64,可能是4K,16K,64K。...而为了快速方便找到对应物理页而将所有的页帧结构体映射到此区域,后续只需使用virt_to_page, phys_to_page等宏实现虚拟地址,物理地址到对应页结构体的快速查询。...地址空间port属性说明 第一列 当前页表的映射范围地址 第二列 代表此映射范围大小 PMD PUD PTE 当标识为PMD PUD表示当前映射为block映射,如当前页表为4K,则pud的block映射一次性可映射...当标识为PTE表示为页表映射即PAGE_SIZE大小4K。 USR AP标记,用于标识当前范围是否在用户空间还是内核空间可读可写或者仅读。...x表述当前范围特权级别模式可执行,就是内核的可执行代码段,在内核中这段一般指向内核的text*段 SHD 表示可共享属性,在arm64上表述为多核之间可共享其页表可见 AF 访问标志,当首次映射页表时,

    20610

    内核知识第八讲,PDE,PTE,页目录表,页表的内存管理

    内核知识第八讲,PDE,PTE,页目录表,页表的内存管理 一丶查看GDT表....首先我们的CR3寄存器保存了表的首地址. 这里有一个页目录表,还有页表的关键词. 页目录表: 也称为PDE,而页表称之为PTE....CPU会通过虚拟地址,当作下表.去页目录表中查询.然后查到的结果再去页表中查询.这样就查到对应的物理地址了....PDE表的大小:   页目录表,存储在一个4K字节的物理页中,其中每一项是4个字节.保存了页表的地址.   而最大是1M个页. PTE表的大小.   PTE的大小也和PDE一样的....首先前边20位保存了页表或者物理地址的基地址. 比如我们的页目录表. 查到了第5项.那么从中取出千20位来,加上000就等于页表了.  然后从页表中查询千20位.

    1.8K10

    宋宝华: ARM64 Linux内核页表的块映射

    我们看看这种情况下的页表,我们既可以用最终的【20:12】对应的PTE映射项,以4K为单位,进行虚拟地址到物理地址的映射;又可以以【29:21】对应的PMD映射项,以2M为单位,进行虚拟地址到物理地址的映射...当然,如果用户态的虚实映射是这样的,用户实际得到了一个1GB的巨页。但是对于内核的线性映射区域而言,即便我们进行了1GB的PUD映射,这1G内部就可以进一步切割为4KB页或者2MB的巨页。...我们把它们全部选中,这样我们可以得到一个debugfs接口: /sys/kernel/debug/kernel_page_tables 来获知内核态页表的情况。...我在内核启动参数加的rodata=0实际上是让rodata_full为false。如果我把这个kernel启动选项去掉,我得到的内核页表是完全不一样,线性映射区也全部是PTE映射: ?...牧春童鞋在“Linux阅码场”这里还有一些精彩的文章: 宋牧春:Linux设备树文件结构与解析深度分析(1) 宋牧春:Linux设备树文件结构与解析深度分析(2) 宋牧春:多图详解Linux内存分配器

    3.6K10

    深入理解Linux内核页表映射分页机制原理

    Linux对于页表的操作主要定义了以下函数或宏。这些操作方法也是与体系架构相关的,因此需要按照体系架构的硬件定义去实现。...而Linux有一个三层的页表结构,可以很容易地将其包装成适合两层的页表结构—只使用PGD和PTE。但是,Linux还要求每个页面有一个“PTE”表,而且至少要有一个“dirty”位。...因此,在这里稍微调整了实现—告诉Linux在第一级有2048个条目,每个都是8字节。二级页表包含两个连续排列的硬件PTE表项,前面的表项是包含Linux需要的状态信息的Linux PTE。...ARMv7页表属性的定义分为Linux版本的页表和ARMv7硬件的页表。 Linux版本的PTE页表属性定义加入前缀L_,如下所示: /* * "Linux" PTE definitions....通过对比Linux版本的页表和ARMv7硬件的页表会发现,ARMv7硬件的页表缺少“dirty”位和“young”位。

    3.7K11

    Linux-3.14.12内存管理笔记【建立内核页表(3)

    前面已经分析了内核页表的准备工作以及内核低端内存页表的建立,接着回到init_mem_mapping()中,低端内存页表建立后紧随着还有一个函数early_ioremap_page_table_range_init...page_table_kmap_check(),其入参调用的one_page_table_init()是用于当入参pmd没有页表指向时,创建页表并使其指向被创建的页表。...,如果是,则把其pte页表的内容拷贝到page_table_range_init()申请的页表空间中,并将newpte新页表的地址设置到pmd中(32bit系统实际上就是页全局目录),然后调用__flush_tlb_all...为了避免前期可能对固定映射区已经分配了页表项,基于临时内核映射区间要求页表连续性的保证,所以在此重新申请连续的页表空间将原页表内容拷贝至此。...值得注意的是,与低端内存的页表初始化不同的是,这里的页表只是被分配,相应的PTE项并未初始化,这个工作将会交由以后各个固定映射区部分的相关代码调用set_fixmap()来将相关的固定映射区页表与物理内存关联

    1.6K11

    Linux-3.14.12内存管理笔记【建立内核页表(1)】

    前面已经分析过了Intel的内存映射和linux的基本使用情况,已知head_32.S仅是建立临时页表,内核还是要建立内核页表,做到全面映射的。...建立内核页表前奏,了解两个很关键的变量: max_pfn:最大物理内存页面帧号; max_low_pfn:低端内存区(直接映射空间区的内存)的最大可用页帧号; max_pfn 的值来自setup_arch...Linux是一个支持多硬件平台的操作系统,各种硬件芯片的分页并非固定的2级(页全局目录和页表),仅仅Intel处理器而言,就存在3级的情况(页全局目录、页中间目录和页表),而到了64位系统的时候就成了4...所以Linux为了保持良好的兼容性和移植性,系统设计成了以下的4级分页模型,根据平台环境和配置的情况,通过将页上级目录和页中间目录的索引位设置为0,从而隐藏了页三级目录和页中间目录的存在。...此外还有一个准备操作,在setup_arch()函数中调用的页表缓冲区申请操作: early_alloc_pgt_buf(): 【file:/arch/x86/mm/init.c】 void __init

    1.9K41

    Linux从头学15:【页目录和页表】-理论 + 实例 + 图文的最完全、最接地气详解

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++、嵌入式、Linux。...关注下方公众号,回复【书籍】,获取 Linux、嵌入式领域经典书籍;回复【PDF】,获取所有原创文章( PDF 格式)。...这里的每一个表,就称作页表,所以一共有1024个页表。 一个页表中一共有1024个表项,每一个页表项占用4个字节,所以一个页表就占用4KB的物理内存空间,正好是一个物理页的大小。...表示这个物理页中的数据是否被写过; 页目录 现在,每一个物理页,都被一个页表中的一个表项来指向了,那么这1024个页表的地址,应该怎么来管理呢? 答案是:页目录表!...页目录中,每一个表项的格式如下: 其中的属性字段,与页表中的属性类似,只不过它的描述对象是页表。 还有一点:每一个用户程序都有自己的页目录和页表!下文有详细说明。

    1.5K30

    【进程 进程表】页表通常存在PCB中

    通俗解释进程-科学家做蛋糕 科学家做蛋糕 然后女儿被蜜蜂蛰了 进程表–在内核 内存管理 经典 老式 管理方法: 基址寄存器(程序开始的地方) + 界限寄存器(程序长度) 空闲内存管理...每个页框有一个编号,即“页框号”(页框号=页帧号=内存块号=物理块号=物理页号),页框号从0开始 将进程的逻辑地址空间也分为与页框大小相等的一个个部分,每个部分称为一个“页”或“页面”。...操作系统以页框为单位为各个进程分配内存空间。进程的每个页面分别放入一个页框中。也就是说,进程的页面与内存的页框有一一对应的关系。 各个页面不必连续存放,可以放到不相邻的各个页框中。...重要的数据结构——页表 为了能知道进程的每个页面在内存中存放的位置,操作系统要为每个进程建立一张页表。...注:页表通常存在PCB中 一个进程对应一张页表 进程的每个页面对应一个页表项 每个页表项由“页号”和“块号”组成 页表记录进程页面和实际存放的内存块之间的映射关系

    1.6K20

    内核必须懂(七): Linux四级页表(x64)

    目录 前言 Intel四级页表 实操寻址 获取cr3 获取PGD 获取PUD 获取PMD 获取PTE 获取内容 最后 ---- 前言 Linux四级页表的作用主要就是地址映射, 将逻辑地址映射到物理地址...很多时候, 有些地方想不明白就可以查看实际物理地址进行分析. ---- Intel 四级页表 其实很多设计的根源或者说原因都来自于CPU的设计, OS很多时候都是辅助CPU....Linux的四级页表就是依据CPU的四级页表来设计的. 这里主要说的就是Intel x64页面大小为4KB的情况, 如图所示: ?...当然了, 按照CPU的图示, cr3肯定是指向PML4E. 在Linux当中, 第一级页表称为PGD, 当然是有历史原因的, 可以自行google....所以Linux的四级页表分别是PGD -> PUD -> PMD -> PTE. ? ---- 获取PGD 想要获取PGD中的内容需要通过计算. 这里先来处理一下局部变量地址.

    7.7K40

    Linux 匿名页的反向映射

    我们知道LINUX的内存管理系统中有”反向映射“这一说,目的是为了快速去查找出一个特定的物理页在哪些进程中被映射到了什么地址,这样如果我们想把这一页换出(SWAP),或是迁移(Migrate)的时候,就能相应该更改所有相关进程的页表来达到这个目的...1、为什么要使用反向映射   物理内存的分页机制,一个PTE(Page Table Entry)对应一个物理页,但一个物理页可以由多个PTE与之相对应,当该页要被回收时,Linux2.4的做法是遍历每个进程的所有...Linux采用三级页表: PGD:顶级页表,由pgd_t项组成的数组,其中第一项指向一个二级页表。...PMD:二级页表,由pmd_t项组成的数组,其中第一项指向一个三级页表(两级处理器没有物理的PMD)。 PTE:是一个页对齐的数组,第一项称为一个页表项,由pte_t类型表示。...,12-21表PMD,22-31位表PGD,即线性地址右移22位的结果为其在全局页目录的偏移 #define PTRS_PER_PGD 1024 // 因PGD共10位,所以其最多可以有2^

    3.7K31

    linux中透明巨页与巨页的区别

    在Linux中,透明巨页(Transparent HugePage)和巨页(HugePage)是两种不同的内存管理技术。 透明巨页是Linux内核中的一项特性,旨在提高内存的利用率和性能。...它通过将内存分配为更大的巨页(通常为2MB或1GB),减少了对内存页表的访问次数,从而提高了内存访问的效率。透明巨页是透明的,应用程序无需进行任何修改即可受益于这种内存管理技术。...而巨页是指一种更大尺寸的内存页,在Linux中可以使用不同的页面大小,常见的巨页大小是2MB或1GB。...巨页可以提供更高的内存访问性能,因为它减少了页表的数量,降低了TLB(Translation Lookaside Buffer)缓存的压力,从而减少了内存访问的开销。...巨页需要应用程序进行适当的修改和配置才能使用。 因此,透明巨页和巨页都是通过增加内存页的尺寸来提高内存访问性能,但透明巨页不需要应用程序的修改,而巨页需要应用程序的支持和配置。

    43910

    ARM32 页表映射

    我们从ARM linux内核建立具体内存区间的页表映射过程中来看页表映射是如何实现的。...,注意ARM Linux中实现了两份页表,硬件页表的地址r0+2048。...该函数的主要目的是根据Linux版本的页面表项内容来填充ARM硬件版本的页表项; 首先把linux内核版本的页表项内容写入linux版本的页表中,然后根据mem_type数据结构prot_pte的标志位来设置...linux内核最早基于x86体系结构设计的,所以linux内核关于页表的许多术语和设计都是针对x86体系的,而ARM Linux只能从软件架构上去跟随了,因此设计了两套页表。...版本中PTE页面表项标记为"dirty",并且发现PTE页表项内容改变了,ptep_set_access_flags()函数会把新的linux版本的页表项内容写入硬件页表,从而实现模拟过程;

    2.9K30

    Linux 标准大页和透明大页

    Huge pages ( 标准大页 ) 和 Transparent Huge pages( 透明大页 ) 在 Linux 中大页分为两种:Huge pages ( 标准大页 ) 和 Transparent...内存是以块即页的方式进行管理的,当前大部分系统默认的页大小为 4096 bytes 即 4K。1MB 内存等于 256 页;1GB 内存等于 256000 页。...CPU 拥有内置的内存管理单元,包含这些页面的列表,每个页面通过页表条目引用。当内存越来越大的时候, CPU 需要管理这些内存页的成本也就越高,这样会对操作系统的性能产生影响。...Huge Pages Huge pages 是从 Linux Kernel 2.6 后被引入的,目的是通过使用大页内存来取代传统的 4kb 内存页面, 以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能...Transparent Huge Pages Transparent Huge Pages 缩写 THP ,这个是 RHEL 6 开始引入的一个功能,在 Linux6 上透明大页是默认启用的。

    5.8K50
    领券