页表 Page tables
逻辑地址与物理地址的转化
页表是由页表项(PTE)组成的数组。512个PTE构成一个页表页(Page-table page)。
PTE中包含了物理页码(PPN physical page number)以及一些标志,来控制物理空间块的读写访问权限。
物理地址与虚拟地址的映射为三层树形结构,每一层存储下一层页表页的地址,最后一层存储物理地址的PTE。
(个人理解:计算机中的物理地址被逻辑性理解成了页面+偏移量,其本质没发生变化,依旧是某一内存单元的编号)


图 PTE的格式
代码解析
walk函数用来获得逻辑地址(va virtual address)的所在物理地址(pa physical address)的PTE (一般都是对整个page做操作,很少有对某个特定地址进行操作,所以是获得该va所在page的PTE,主要操作包括对其标志位进行处理)
主要展示了逻辑地址是如何转换成物理地址的,这是分页机制最核心的一个部分
page和上篇exec提到的segment共同组成计算机中虚拟内存机制
// Return the address of the PTE in page table pagetable
// that corresponds to virtual address va. If alloc!=0,
// create any required page-table pages.
//
// The risc-v Sv39 scheme has three levels of page-table
// pages. A page-table page contains 512 64-bit PTEs.
// A 64-bit virtual address is split into five fields:
// 39..63 -- must be zero.
// 30..38 -- 9 bits of level-2 index.
// 21..29 -- 9 bits of level-1 index.
// 12..20 -- 9 bits of level-0 index.
// 0..11 -- 12 bits of byte offset within the page.
//返回逻辑地址va所对应的PTE的指针
pte_t *
walk(pagetable_t pagetable, uint64 va, int alloc)
{
if(va >= MAXVA)
panic("walk");
for(int level = 2; level > 0; level--) {
//PX(level,va) 获取level对应的PTE 如上图的L2
//以L2为例,这里获得了L2在第三级页表页中位置编号
//相当于物理地址的偏移量
pte_t *pte = &pagetable[PX(level, va)];
// PTE_V valid 表示PTE是否合法
if(*pte & PTE_V) {
//PTE2PA 将PTE转换成实际的物理地址
//这个物理地址即第二级页表页的起始地址
pagetable = (pagetable_t)PTE2PA(*pte);
} else {
//如果PTE_V=0 说明第二级页表页还未创建,则创建一个
if(!alloc || (pagetable = (pde_t*)kalloc()) == 0)
return 0;
//用0填充
memset(pagetable, 0, PGSIZE);
//然后将PTE_V置 1
*pte = PA2PTE(pagetable) | PTE_V;
}
}
return &pagetable[PX(0, va)];
}
附:
typedef uint64 pte_t;
typedef uint64 *pagetable_t; // 512 PTEs
// extract the three 9-bit page table indices from a virtual address.
#define PXMASK 0x1FF // 9 bits
#define PXSHIFT(level) (PGSHIFT+(9*(level)))
#define PX(level, va) ((((uint64) (va)) >> PXSHIFT(level)) & PXMASK)
#define PTE_V (1L << 0) // valid
#define PTE_R (1L << 1)
#define PTE_W (1L << 2)
#define PTE_X (1L << 3)
#define PTE_U (1L << 4) // 1 -> user can access
// shift a physical address to the right place for a PTE.
#define PA2PTE(pa) ((((uint64)pa) >> 12) << 10)
#define PTE2PA(pte) (((pte) >> 10) << 12)
可执行文件以节section划分部分,载入内存后,以段segment划分部分,换了个名字(大概)
页表 Page tables的更多相关文章
- PatentTips - Substitute virtualized-memory page tables
BACKGROUND Many computer systems utilize virtualized memory for security, stability and/or other pur ...
- PatentTips - Maintaining shadow page tables in a sequestered memory region
BACKGROUND Malicious code, known as malware, which includes viruses, worms, adware, etc., may attack ...
- Extended paging tables to map guest physical memory addresses from virtual memory page tables to host physical memory addresses in a virtual machine system
A processor including a virtualization system of the processor with a memory virtualization support ...
- linux thtree level page tables
To translate a virtual address into a physical one, the CPU must take the contents of each level fie ...
- 【译】x86程序员手册39-10.3切换到保护模式
10.3 Switching to Protected Mode 切换到保护模式 Setting the PE bit of the MSW in CR0 causes the 80386 to b ...
- 【硬核】MMU是如何完成地址翻译的
目录 1. 什么是虚拟内存? 2. 虚拟内存的作用 3. 虚拟内存与物理内存 3.1 CPU存取数据 3.2 物理地址常用术语 3.3 虚拟地址常用术语 3.4 页表常用术语 3.5 页命中/缺页 4 ...
- Operating System Memory Management、Page Fault Exception、Cache Replacement Strategy Learning、LRU Algorithm
目录 . 引言 . 页表 . 结构化内存管理 . 物理内存的管理 . SLAB分配器 . 处理器高速缓存和TLB控制 . 内存管理的概念 . 内存覆盖与内存交换 . 内存连续分配管理方式 . 内存非连 ...
- 临时2级页表的初始化过程 head_32.S 相关代码解释
page_pde_offset = (__PAGE_OFFSET >> 20); /* __PAGE_OFFSET是0xc0000000,page_pde_offset = 3072 = ...
- linux内存管理解析1----linux物理,线性内存布局及页表的初始化
主要议题: 1分页,分段模式及实模式 2Linux分页 3linux内存线性地址空间布局及物理内存空间布局 4linux页表初始化及代码解析 1.1.1内存寻址和保护模式 在X86平台上,内存控制单元 ...
随机推荐
- 案例九:shell脚本自动创建多个新用户,并设置密码
此脚本是用来批量创建用户并设置用户密码,在企业用非常实用. 脚本一 #!/bin/bash for name in $( seq 1 100 ) do useradd "user$name& ...
- [推荐]MyBatis 核心技术与面试 34 讲
MyBatis 核心技术与面试 34 讲 职业生涯中常被问到: 如何成为某方面的高手? 如何快速搞定某项技术? 我现在的水平处于什么阶段? -- 我暗暗想,我们从小学到中学到大学,经历了大考三六九.小 ...
- java.lang.SecurityException: MODE_WORLD_READABLE错误解决
问题描述:运行Android项目有以下报错: 解决方法: 把 MODE_WORLD_READABLE 更换成 MODE_PRIVATE 即可,因为MODE_WORLD_READABLE 模式已经被废弃 ...
- Jenkins 进阶篇 - 任务关联
有时候我们的一个任务里面会进行很多的步骤,例如构建一个后端的 Java 服务,可能会有代码静态扫描,静态扫描通过后会打包成 jar 或者 war 文件,打包成功后可能还会对制品进行存档备份,然后可能会 ...
- PHP的OpenSSL加密扩展学习(一):对称加密
我们已经学过不少 PHP 中加密扩展相关的内容了.而今天开始,我们要学习的则是重点中的重点,那就是 OpenSSL 加密扩展的使用.为什么说它是重点中的重点呢?一是 OpenSSL 是目前 PHP 甚 ...
- PHP打印跟踪调试信息
对于大部分编译型语言来说,比如 C . Java . C# ,我们都能很方便地进行断点调试,但是 PHP 则必须安装 XDebug 并且在编辑器中进行复杂的配置才能实现断点调试的能力.不过,如果只是简 ...
- webpack learn2-vue的jsx写法和postcss 1
首先输入命令安装 npm i postcss-loader autoprefixer babel-loader babel-core 在根目录创建文件 .babelrc和postcss.config. ...
- Jmeter系列(16)- 常用断言之Xpath断言
Apply to: Main sample and sub-samples:可以同时应用到主Sample和子Sample Main sample only:只能应用到主Sample. Sub-samp ...
- mybatis if else if 条件判断SQL片段表达式取值和拼接
前言 最近在开发项目的时候涉及到复杂的动态条件查询,但是mybaits本身不支持if elseif类似的判断但是我们可以间接通过 chose when otherwise 去实现其中choose为一个 ...
- regexp 正则表达式
* 给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回 true,否则返回 false input: 'rattler' output: true function conta ...