关于JOS未分页之前物理地址映射问题的思考

在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接受的参数也是线性的(虚拟的)。

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

时间: 2024-10-12 02:36:55

关于JOS未分页之前物理地址映射问题的思考的相关文章

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

在kern/pmap.c 里面会又以下这段代码,要知道boot_alloc只会分配线性地址,真正建立虚拟页和物理页映射关系的在后面的page_alloc. ////////////////////////////////////////////////////////////////////// // create initial page directory. kern_pgdir = (pde_t *) boot_alloc(PGSIZE); memset(kern_pgdir, 0, PG

(转)分页和分段的区别

转自:http://blog.csdn.net/wangrunmin/article/details/7967293 一. 分页存储管理 1.基本思想 用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等.可将用户程序的任一页放在内存的任一块中,实现了离散分配. 2. 分页存储管理的地址机构 15          12         11                  0 页号P                 页内位移量W 页号4

操作系统内存管理之 分页与虚存(页表、页框、内存)

一 页面与页表 1 页面 分页存储管理是将作业的逻辑地址划分为一系列同等大小的部分,称为页.并为各页加以编号,每个作业的页的编号都是从0开始的.与之类似,把可用的物理内存也划分为同样大小的连续的部分,称为块或页框.同样为块也进行标号,从0#开始.在为进程分配内存空间时,以页为单位,每个内存中的块存放一页用户作业.只要内存中有足够多的块,这些块可以相邻也可以不相邻,就可以存放整个作业了. 页面的大小对于内存利用和系统开销来说非常重要,页面太大,在作业的最后一页必然会剩余较大不能利用的空间--内碎片

何谓可分页和非分页内存

何谓可分页和非分页内存 1)默认情况下,内核加载器会加载所有的代码部分和全局数据到非分页内存中.而且,加载器是一次加载整个驱动的可执行文件,包括相关的DLL.加载后,内核加载器关闭驱动程序文件,甚至你可以删除当前正在执行的驱动文件. 但是,你可以告诉加载器你希望驱动的哪部分是可分页,所谓可分页,就是可能会被换页出内存(Page out).可以使用下面的指令来实现: #define ALLOC_PRAGMA #pragma alloc_text(PAGE, function_name1) #pra

为虚拟磁盘 添加/删除物理磁盘

为虚拟磁盘 添加/删除物理磁盘 Add-Physicaldisk     此命令用于将指定的物理磁盘添加到虚拟磁盘    在存储池一节已经介绍过将物理磁盘加入存储池的用法,    在这里将介绍在虚拟磁盘上的用法    在正式介绍命令用法之前先回答 在Get-StoragePool,Get-VirtualDisk,New-VirtualDisk    三节中的提问    要获取未被虚拟磁盘使用的物理磁盘,你必须学会灵活的使用管道命令    $pool_pd = @(Get-StoragePool 

TP5分页类

<?php class Page { public $page; //当前页 public $total; //总记录数 public $listRows; //每页显示记录数 private $uri;//动态url public $pageNum; //总页数 private $listNum=6;//显示页码按钮数量 public $render;//分页后的html模板 public $data;//分页后渲染到模板的数据 /* * 初始化分页数据 *$sdata 待分页的数据 * $l

Struts分页的一个实现

在Web应用程序里,分页总让我们开发人员感到很头疼,倒不是因为技术上有多么困难,只是本来和业务没有太多关系的这么一个问题,你却得花不少功夫来处理.要是稍不留神,时不时出点问题就更郁闷了.我现在做的一个项目也到了该处理分页的时候了,感觉以前处理得都不好,所以这次有所改变,基本目标是在现有(未分页)的代码基础上,尽量少做修改,并且同样的代码可以应用于不同模块的分页.以下就是我用的方法: 首先,考虑分页绝大多数发生在列表时,组合查询时也需要用到.在我的项目里,列表的Action一般名字为ListXXX

【Asp.Net WebFrom】分页

Asp.Net WebForm 分页 一. 前言 Asp.Net WebForm 内置的DataPager让人十分蛋疼 本文使用的分页控件是第三方分页控件 AspNetPager,下载地址: 链接: http://pan.baidu.com/s/1eQJ2HR8 密码: aost 相关属性及其效果图: 二.使用第三方分页控件 AspNetPager 第一步:显示未分页前的数据 前端代码: 注意:将ListView控件的EnableViewState="False".说明即使是Enabl

检查点(Checkpoint)过程如何处理未提交的事务

每次我讲解SQL Server之前,我都会先简单谈下当我们执行查询时,在SQL Server内部发生了什么.执行一个SELECT语句非常简单,但是执行DML语句更加复杂,因为SQL Server要修改内存中的相关页,并在事务日志里记录整个事务. 介绍完这些特定步骤后,我总会问同样的问题:当我们有个未提交的事务,这个时候刚好有检查点(Checkpoint)发生,SQL Server会崩溃么?在我们数据文件里有我们未提交的数据么?先思考下,然后再写下你的答案. 创建测试场景 现在我想和你一起重建这个