在kern/pmap.c 里面会又以下这段代码,要知道boot_alloc只会分配线性地址,真正建立虚拟页和物理页映射关系的在后面的page_alloc.

//////////////////////////////////////////////////////////////////////

        // create initial page directory.

        kern_pgdir = (pde_t *) boot_alloc(PGSIZE);

        memset(kern_pgdir, 0, PGSIZE);

这里有个疑问,memset仅会接受虚拟地址,而这里boot_alloc分配出的kern_pgdir 是线性地址,这里还“没有建立起实际的物理映射”,怎么就能用memset去把kern_pgdir指向的地址出PGSIZE大小空间的数据所有填充为0.

前面说的话已经又双引號了,嘿嘿。说明这就是个假象,或者说我理解的不够透彻. 这里要感谢Eric eshyong。以及和我一起讨论问题的Essential
On C & Linux的道友.

上面代码部分还处于已经开启分页可是还没有建立起全部的分页映射. 为什么这样说,是由于之前JOS的kernel
作者手动静态的完毕了部分内存的映射,而这部分内存就是物理内存的前4M(0x400000)

在kern/entrypgdir.c 里面

注意这里把虚拟地址的 [0,4M) [KERNBASE,KERNBASE + 4M) 两个区间都映射到同一物理地址区间[0,4M)

所谓的静态映射就是手动的...把一个个地址页面都分配好。例如以下....

Revisit the page table setup in  kern/entry.S  and  kern/entrypgdir.c . Immediately after we turn on paging, EIP is still a low number (a little over 1MB). At what point do we transition to running at an EIP above
KERNBASE? What

makes it possible for us to continue executing at a low EIP between when we enable paging and when we begin running at an EIP above KERNBASE? Why is this transition necessary?

这里就相当于要回答这个问题,在刚刚开启分页的时候(entry.S 里面 cr0 的)

	# Turn on paging.
movl %cr0, %eax
orl $(CR0_PE|CR0_PG|CR0_WP), %eax
movl %eax, %cr0

紧接着此时EIP指令寄存器还指向地址的低空间(1M多一点点的地方)

   不难看出jmp这行代码使得地址空间起了变化,分页机制開始作用

既然分页已经开启了,那么就应当把高地址的KERNBASE映射到物理地址上,之前事实上就已经做好了,这里把虚拟地址的 [0,4M) [KERNBASE,KERNBASE + 4M) 两个区间都映射到同一物理地址区间[0,4M)的目的就在于不要让指令的寻址受到地址空间变化的影响.

(这段代码我重复给出,比較重要)

回到我们原来的问题

//////////////////////////////////////////////////////////////////////

        // create initial page directory.

        kern_pgdir = (pde_t *) boot_alloc(PGSIZE);

        memset(kern_pgdir, 0, PGSIZE);

这里有个疑问。memset仅会接受虚拟地址,而这里boot_alloc分配出的kern_pgdir 是线性地址,这里还“没有建立起实际的物理映射”,怎么就能用memset去把kern_pgdir指向的地址出PGSIZE大小空间的数据所有填充为0.

在这一步的时候。boot_alloc确实是申请出的线性地址,可是注意!这部分地址早就被静态映射好了。

此时的kern_pgdir 得到的是线性地址,然而它并不须要page_alloc来给它动态的分配实际的内存,由于之前已经分配好了.

memset接受的參数也是线性的(虚拟的)。

二零一四年 十月 摄于妙音寺前

关于JOS 未对全部内存分页映射之前 物理地址映射问题的思考的更多相关文章

  1. 操作系统之Linux的内存分页管理

    内存是计算机的主存储器.内存为进程开辟出进程空间,让进程在其中保存数据.我将从内存的物理特性出发,深入到内存管理的细节,特别是了解虚拟内存和内存分页的概念. 内存 简单地说,内存就是一个数据货架.内存 ...

  2. JVM优化之调整大内存分页(LargePage)

    转自:http://cjjwzs.iteye.com/blog/1059381 本文将从内存分页的原理,如何调整分页大小两节内容,向你阐述LargePage对JVM的性能有何提升作用,并在文末点明了大 ...

  3. Linux的内存分页管理

    作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载 内存是计算机的主存储器.内存为进程开辟出进程空间,让进程在其中保存数据.我将从内存的物理特性出发,深入到内存 ...

  4. (理论篇)从基础文件IO说起虚拟内存,内存文件映射,零拷贝

    为了快速构建项目,使用高性能框架是我的职责,但若不去深究底层的细节会让我失去对技术的热爱. 探究的过程是痛苦并激动的,痛苦在于完全理解甚至要十天半月甚至没有机会去应用,激动在于技术的相同性,新的框架不 ...

  5. linux 内存分页

    内存是计算机的主存储器.内存为进程开辟出进程空间,让进程在其中保存数据.我将从内存的物理特性出发,深入到内存管理的细节,特别是了解虚拟内存和内存分页的概念. 内存 简单地说,内存就是一个数据货架.内存 ...

  6. Linux的内存分页管理【转】

    内存是计算机的主存储器.内存为进程开辟出进程空间,让进程在其中保存数据.我将从内存的物理特性出发,深入到内存管理的细节,特别是了解虚拟内存和内存分页的概念. 内存 简单地说,内存就是一个数据货架.内存 ...

  7. 【操作系统之十】内存分页管理与swap

    一.虚拟内存电脑里内存分内存条(这里我们叫物理内存)和硬盘,内存条保存程序运行时数据,硬盘持久保存数据.那么虚拟内存是什么? 程序运行会启动一个进程,进程里有程序段.全局数据.栈和堆,这些都会加载到内 ...

  8. [转帖]运维必读:Linux 的内存分页管理

    运维必读:Linux 的内存分页管理 https://cloud.tencent.com/developer/article/1356431 内存是计算机的主存储器.内存为进程开辟出进程空间,让进程在 ...

  9. C#实现的内存分页机制的一个实例

    C#实现的内存分页机制的一个实例 //多页索引表管理类(全局主索引表管理类) public class MuliPageIndexFeatureClass : IDisposable { protec ...

随机推荐

  1. 网络简要<入门篇>对应配置代码

    交换机的配置 (1)交换机的模式: switch>    用户模式,可以查看设备的部分内容 SW-3ceng>enable SW-3ceng#          进入特权模式,可以查看更多 ...

  2. C# 设置百分比保留2位数

    double a=50; double b=100; 没有小数部分Label1.Text = (a   /   (a+b)).ToString("0%")   两位小数Label2 ...

  3. MyEclipse中快速复制粘贴当前行的操作

  4. Spring boot (12) tomcat jdbc连接池

    默认连接池 tomcat jdbc是从tomcat7开始推出的一个连接池,相比老的dbcp连接池要优秀很多,spring boot将tomcat jdbc作为默认的连接池,只要在pom.xml中引入了 ...

  5. 在.xls;*.xlsx类型文件的导入(可以导入多条数据)

    2018-11-28   17:36:35 需要jar包:poi-3.8-201203026.jar jsp页面: <LINK href="${basePath}plugins/upl ...

  6. 5.23Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分

    作者:https://www.cnblogs.com/lyjin/p/6389349.html PO:持久对象(persistent object):---po就是在Object/Relation M ...

  7. 在Winform中怎么实现图片的旋转,比如说实现仪表盘功能,看代码吧,看太不懂的欢迎问

    ; //旋转的角度 //Timer定时器 private void timer1_Tick(object sender, EventArgs e) { timer1.Enabled = false; ...

  8. 闰年or平年判断

    <script type="text/javascript">var year = prompt("请输入一个年份");if(year!=null) ...

  9. openMSP430之Custom linker script

    The use of the -mmcu switch is of course NOT mandatory. It is simply a convenient way to use the pre ...

  10. Percona Xtrabackup导出/导入单表

    默认情况下,InnoDB表不能通过直接复制表文件的方式在mysql服务器之间进行移植,即便使用了innodb_file_per_table选项.而使用Xtrabackup工具可以实现此种功能,不过,此 ...