在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. Ruby类扩张(extension)

    创建: 2017/09/07 更新: 2017/09/16 修改标题字母大小写 ruby ---> Ruby    扩张类  class 类名     扩张的内容  end           ...

  2. php循环跳出

    PHP中的循环结构大致有for循环,while循环,do{} while 循环以及foreach循环几种,不管哪种循环中,在PHP中跳出循环大致有这么几种方式: 代码: <?php $i = 1 ...

  3. codevs2594解药还是毒药(状压dp)

    2594 解药还是毒药  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description Smart研制出对付各种症状的解药,可是 ...

  4. Appium + python -always_allows弹窗

    from appium import webdriverfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.web ...

  5. JavaScript在表格中模拟搜索多关键词搜索和筛选

    模拟搜索需要实现以下功能: 1.用户的模糊搜索不区分大小写,需要小写字母匹配同样可以匹配到该字母的大写单词. 2.多关键词模糊搜索,假设用户关键词以空格分隔,在关键词不完整的情况下仍然可以匹配到包含该 ...

  6. Kubernetes Port Forward 机制访问 pod

    需求:研发需要调试部署的pod是否能正常提供访问,但又不对pod进行暴露到集群外. 实现:通过Kubernetes的Port Forward机制对本机端口映射到pod端口来实现 1.安装kubectl ...

  7. oen /var/run/nginx.pid failed

    nginx: [error] open() "/var/run/nginx.pid" failed (2: No such file or directory) [root@TES ...

  8. HTML简单入门

    - Java攻城狮学习路线 - 基本结构 标准文档:www.w3.org <!DOCTYPE html> <html> <head> <meta charse ...

  9. 九九乘法表---for循环的嵌套

    package com.zuoye.test;//控制台输出九九乘法表public class Jiujiu { public static void main(String[] args) { in ...

  10. 微信小程序swiper bindChange重复执行

    swiper是微信小程序的一个滑动组件,非常重要.如果只是做简单的轮播图而不进行复杂的逻辑,直接可以使用,甚至不需要知道组件的方法.今天在做一个如下的页面时,快速滑动swiper出现了问题: 控制台打 ...