;开始创建页目录项(PDE)
.create_pde: ; 创建Page Directory Entry
mov eax, PAGE_DIR_TABLE_POS ; PAGE_DIR_TABLE_POS = 0x100000
add eax, 0x1000 ; 此时eax为第一个页表的位置及属性
mov ebx, eax ; 此处为ebx赋值,是为.create_pte做准备,ebx为基址。 ; 下面将页目录项0和0xc00都存为第一个页表的地址,
; 一个页表可表示4MB内存,这样0xc03fffff以下的地址和0x003fffff以下的地址都指向相同的页表,
; 这是为将地址映射为内核地址做准备 or eax, PG_US_U | PG_RW_W | PG_P ; 页目录项的属性RW和P位为1,US为1,表示用户属性,所有特权级别都可以访问.
; 第1个目录项,在页目录表中的第0个目录项写入第一个页表的位置(0x101000)及属性(7)
mov [PAGE_DIR_TABLE_POS + 0x0], eax
; 一个页表项占用4字节,0xc00表示第768个页表占用的目录项,0xc00以上的目录项用于内核空间,
;页目录第768项指向第一个页表
mov [PAGE_DIR_TABLE_POS + 0xc00], eax
; 也就是页表的0xc0000000~0xffffffff共计1G属于内核,0x0~0xbfffffff共计3G属于用户进程.
sub eax, 0x1000
; 使最后一个目录项指向页目录表自己的地址
mov [PAGE_DIR_TABLE_POS + 4092], eax ;下面创建页表项(PTE) ;把1M低端内存存储在第一页目录所指向的页表0~页表255内,每页4K
mov ecx, 256 ; 1M低端内存 / 每页大小4k = 256
mov esi, 0
mov edx, PG_US_U | PG_RW_W | PG_P ; 属性为7,US=1,RW=1,P=1
.create_pte: ; 创建Page Table Entry
mov [ebx+esi*4],edx ; 此时的ebx已经在上面通过eax赋值为0x101000,也就是第一个页表的地址
add edx,4096
inc esi
loop .create_pte ;创建内核其它页表的PDE
mov eax, PAGE_DIR_TABLE_POS
add eax, 0x2000 ; 此时eax为第二个页表的位置
or eax, PG_US_U | PG_RW_W | PG_P ; 页目录项的属性US,RW和P位都为1
mov ebx, PAGE_DIR_TABLE_POS
mov ecx, 254 ; 范围为第769~1022的所有目录项数量
mov esi, 769
.create_kernel_pde:
mov [ebx+esi*4], eax
inc esi
add eax, 0x1000
loop .create_kernel_pde
ret

指定了物理地址1M的页表 ,具体示意图如下:

关于页目录表:

1、  每个进程有一个属于自己的页目录表,可通过 CR3 寄存器找到 

2、  而内核也有一个独立于其它进程的页目录表[上面代码模拟了内核的页目录表],保存在 swapper_pg_dir[] 数组中

3、  当进程切换的时候,只需要将新进程的页目录把地址加载到 CR3 寄存器中即可

4、  创建一个新进程的时候,需要为它分配一个 page,作为页目录表,并将 swapper_pg_dir[] 的高 256 项拷贝过来[上面代码模拟了内核的页目录表769-1023项],低 768 项则清0

//===============================扩展===============================================

上图反映了如下信息:

1、 进程的4G 线性空间被划分成三个部分:进程空间(0-3G)、内核直接映射空间(3G– high_memory)、内核动态映射空间(VMALLOC_START - VMALLOC_END)

2、 三个空间使用同一张页目录表,通过 CR3 可找到此页目录表。但不同的空间在页目录表中页对应不同的项,因此互相不冲突

3、 内核初始化以后,根据实际物理内存的大小,计算出 high_memory、VMALLOC_START、VMALLOC_END 的值。并为“内核直接映射”空间建立好映射关系,所有的物理内存都可以通过此空间进行访问。

4、 “进程空间”和“内核动态映射空间”的映射关系是动态建立的(通过缺页异常)

假设在有三个线性地址 addr1, addr2, addr3 ,分别属于三个线性空间不同部分(0-3G、3G-high_memory、vmalloc_start-vmalloc_end),但是最终都映射到物理页面1:

1、 三个地址对应不同的页表和页表项

2、 但是页表项的高20bit肯定是1,表示物理页面的索引号是1

3、 同时,根据高20bit,可以从 mem_map[]中找到对应的struct page结构,struct page 用于管理实际的物理页面(就是实际物理页面的物理地址了,到这里就不绕弯子了,顺便想到高速缓冲的匹配命中操作是用哈希表,换算出的要访问的实际物理地址拿到哈希表的输入计算一下哈希值,看看有没命中)(红线)

4、 从线性地址最终的,根据页目录表,页表,可以找到物理地址

5、 struct page和物理地址之间很容易互相转换

6、 从物理地址,可以很容易的反推出在内核直接映射空间的线性地址(蓝线)。要想得到在进程空间或者内核动态映射空间的对应的线性地址,则需要遍历相应的“虚存区间”链表。

关于页目录表:

1、 每个进程有一个属于自己的页目录表,可通过 CR3 寄存器找到

2、 而内核也有一个独立于其它进程的页目录表,保存在 swapper_pg_dir[] 数组中

3、 当进程切换的时候,只需要将新进程的页目录把地址加载到 CR3 寄存器中即可

4、 创建一个新进程的时候,需要为它分配一个 page,作为页目录表,并将swapper_pg_dir[] 的高256项拷贝过来,低768项则清0

linux0.11版本,所有进程共享同一个页目录而各自使用不同的页表,该共享的页目录就放在物理地址最前面的4k

//===============================END===============================================

地址转换图:

程序运行时虚拟地址转化为物理地址过程:

OS创建页目录和页的更多相关文章

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

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  2. php创建简单的列表页

    php创建简单的列表页 样例 代码 <?php $userInfo[] = array( 'id'=>'1', 'username'=>'fry', 'sex'=>'nan', ...

  3. 【Mysql】InnoDB 引擎中的页目录

    一.页目录和槽 接上一篇,现在知道记录在页中按照主键大小顺序串成了单链表. 那么我使用主键查询的时候,最顺其自然的办法肯定是从第一条记录,也就是 Infrimum 记录开始,一直向后找,只要存在总会找 ...

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

    内核知识第八讲,PDE,PTE,页目录表,页表的内存管理 一丶查看GDT表. 我们通过WinDbg + 虚拟机可以进行双机调试.调试一下看下GDT表 我们知道,GDT表中.存储的是存储段信息. 保存了 ...

  5. 如何创建Filter的属性页

    本篇文档我们将要讲述如何给一个filter创建一个属性页,通过CBasePropertyPage基类.这篇文档的实例代码演 示了创建属性页的步骤,这里我们假设我们要创建属性页的视频filter支持饱和 ...

  6. Word 2007 如何设置正文第一页----目录显示正文从第一页开始

    最近学校里开始要求写论文了,其中有个目录中的页码都不是从第一页开始的,毕竟前面还有封面.中英文摘要.目录等,所以正文内容就不是从第一页开始的了,但是很多的书上所有正文都是从第一页开始的,我的论文如何才 ...

  7. 内核module读取进程页目录

    根据当前CR3寄存器内容,读取对应物理内存中的页目录页,并进行解析 1: void dumpPageDirectoryEntry(u32 entry) 2: { 3: u8 present; 4: u ...

  8. 用C#操作IIS创建虚拟目录和网站

    #region CreateWebsite 添加网站 public string CreateWebSite(string serverID, string serverComment, string ...

  9. 配置ASM以及创建恢复目录

    本次配置ASM沿用了搭建RAC的环境配置,系统选用CENTOS6.8 首先本地配置YUM,安装GRID集群件所需要的RPM包 [root@rac01 Packages]# cd /etc/yum.re ...

随机推荐

  1. 天梯赛 L2-024. 部落

    题解:并查集,这里要用路径压缩来优化 代码:// 这里范围理错了, 浪费20分钟debug #include <set> #include <iostream> #includ ...

  2. GoLand中同一个目录下的package无法调用

    代码结构: 三个代码的package 都是 pipefilter,执行split_filter_test.go 就会提示   undefined:xxxxxxx Golang实际都可以自己补全另一个文 ...

  3. vue+iview tables多个分页实现

    如果一个页面有多个分页那么可以把每个page和pageSize放到一个对象中,如下: dataList: { name: 'dataList', // 方便取到dataList对象 id: null, ...

  4. c#的异步处理思路和vue前端中异步处理思路比较

    前语:目前工作在做的项目是前端基于vue的组件式开发,通过api接口调用,后端数据逻辑是一个c#实现的WCF服务 1.总结自己在c# .NET 4.5后的新异步方式  async搭配await来实现  ...

  5. 最近跟进一个CS项目,用到c#基础知识,准备开个分类记录一下

    C#在txt类文件中追加内容 string path = "test.txt";FileStream mystream = new FileStream(path, FileMod ...

  6. STM8 定时器

    中断映射表 对应stm8_interrupt.c #pragma vector=1 __interrupt void TRAP_IRQHandler(void) { } #pragma vector= ...

  7. python selenium测试用例断言

    1.if ...else ...判断进行断言 #coding=utf-8 from time import * from selenium import webdriver "): driv ...

  8. Android笔记(九) Android中的布局——框架布局

    框架布局没有任何定位方式,所有的控件都会摆放在布局的左上角. 代码示例: framelayout.xml <?xml version="1.0" encoding=" ...

  9. CentOS 7的Linux系统优化加固

    1.关闭selinux 2.关闭防火墙 3.关闭NetworkManager 4.为系统运维管理员创建普通用户,并配置sudo(vi  sudo) 5.清空泄漏系统版本信息的文件 6.基础优化sshd ...

  10. IO五种模型和select与epoll工作原理(引入nginx)

    用户速度体验的1-3-10原则 性能影响 有很多研究都表明,性能对用户的行为有很大的影响: 79%的用户表示不太可能再次打开一个缓慢的网站 47%的用户期望网页能在2秒钟以内加载 40%的用户 ...