页表管理
来源:互联网 发布:golang占位符 编辑:程序博客网 时间:2024/06/10 04:58
在不支持PAE的x86机器上,两层页表已足够。中间页目录(PMD)被定义成大小为1,它在系统初始化时直接映射为全局页目录(PGD),并在编译时间以外的时段进行优化。
描述页目录
每个进程都有一个指向其自己PGD的指针(mm_struct->pgd
),它其实就是一个物理页面帧。该帧包括了一个pgd_t
类型的数组。在x86结构中,进程页表的载入是通过把mm_struct->pgd
复制到cr3
寄存器完成,这种方式对TLB的刷新有副作用。事实上,这种方式体现了在不同结构中__flush_tlb()
的实现情况。
描述页表项
三层页表中的每一个项PTE
、PMD
、PGD
分别由pte_t
、pmd_t
、pgd_t
描述。他们实际上都是无符号的整型数据,之所以定义成结构,一方面是为了起到数据类型保护的作用,以使他们不会被滥用;另一方面是为了满足某些特性,如在支持PAE的x86中,将有额外的4位用于大于4GB内存的寻址。
未启用PAE的x86结构下,定义如下
typedef struct { unsigned long pte_low; } pte_t;typedef struct { unsigned long pmd; } pmd_t;typedef struct { unsigned long pgd; } pgd_t;typedef struct { unsigned long pgprot; } pgprot_t;
在不支持PAE的x86中,pte_t
是一个32位的整形指针。因为每个pte_t
指向一个页面帧的地址,而所有的被指向的地址都确定是页对齐的。因此在32为值里面有12位空闲出来用于描述这个页表项的状态位。
Linux不会将PSE位(_PAGE_PROTNONE
)用于用户页面,当某个页面常驻内存,且内核不希望用户访问的时候,也就是当一个区域通过使用mprotect()
函数设置PROT_NONE
标志保护起来的时候,实际上是将_PAGE_PRESENT
置为0,将_PAGE_PROTNONE
置为1。当使用宏pte_present()
检查这两位的情况时,只有内核自己知道这个页是在内存中的,但对于用户是不可访问的。因为_PAGE_PRESENT
位被清零了,当用户试图访问这个页面时,会触发一次缺页异常,内核能够强制安全检查,以确定是要将页面换出或终止进程。
使用页表项
页表遍历操作:
pgd_t *pgd;pmd_t *pmd;pte_t *ptep, pte;pgd=pgd_offset(mm, address);if(pgd_none(*pgd)||pgd_bad(*pgd)) goto out;pmd=pmd_offset(pgd, address);if(pmd_none(*pmd)||pmd_bad(*pmd)) goto out;ptep=pte_offset(pmd, address);if(!ptep) goto out;pte=*ptep;
内核页表
对于x86结构,页表初始化分为两个阶段。bootstrap阶段设置页表使之映射8MB的空间,使得分页单元能被启动;第二个阶段初始化了剩余的页表。
- bootstrap
arch/i386/kernel/head.S中的汇编函数startup_32()
负责启动分页单元。vmlinuz
中的所有内核代码都是以PAGE_OFFSET+1MiB
为基址编译的,内核实际上装载在内存的0x00100000处(1MiB)。第一个MiB被用于BIOS与某些设备通信。在启动分页单元之前,bootstrap中的代码通过减去__PAGE_OFFSET
将1MiB视为基址。因此在分页单元启动之前,需要建立一个页表映射转换8MiB的物理内存到虚拟地址的PAGE_OFFSET
。
页表将虚拟地址的0x00000000~0x00800000和0xc00100000~0xc00900000映射到了0x00100000~0x00900000的物理地址处
- 页表管理
- 操作系统页表管理
- 深入理解linux内存管理之 页表管理
- 内存管理--页表机制
- oracl--表管理,约束管理,序列管理
- 表管理
- 管理表
- 表管理
- 管理表
- 管理表
- 表管理
- 管理表
- 内存管理—页式管理/段式管理/段页式管理
- 表空间管理,段管理
- 页式管理 多级页表
- linux页表机制管理初始化
- mini2440MMU管理建立页表笔记
- 内存管理图解---------页目录表 页表
- 决策树算法以及个人经历吐槽
- UWB在中国可使用频段的担心
- 2016年程序员如何提高自己的方法有哪些?
- 维护篇(5.2)-15. 外网接口性能测试 ❀ 飞塔 (Fortinet) 防火墙
- Linux 4.4.6 中断向量分析
- 页表管理
- leetcode:Tenth Line 【shell】
- jvm调优-垃圾回收算法
- async模块的异步处理
- 解决利用安卓真机调试程序时日志不显示的问题
- opencv_traincascade训练haar时Error: Insufficient memory等问题
- 页面跳转
- Android开源项目分类汇总
- java并发之Semaphore(信号量)