内核代码和数据的地址

  对于linux 0.11内核代码和数据来说,在head.s程序的初始化操作中已经把内核代码段和数据段都设置成长度为16M的段。在线性地址空间中这两个段的范围重叠,都是从线性地址0开始到地址0XFFFFFF共16M地址范围。在该范围中含有内核所有的代码、内核段表(GDT,IDT,TSS)、页目录表和内核的二级页表、内核局部数据和内核临时堆栈(将被用作第一个任务即任务0的用户堆栈)。其页目录表和二级页表已设置成把0-16M的线性地址空间一一对应到物理地址上,占用了4个目录项即4个二级页表。因此对于内核代码和数据来说,我们可以直接把它看作是物理内存中的地址。如下图:

  因此,默认情况下Linux 0.11内核最多可管理16MB的物理内存,共有4096个物理页面,每个页面4KB。通过上述分析可以看出:

1.内核代码段和数据段区域在线性地址空间和物理地址空间中是一样的,这样设置可以大大简化内核的初始化操作

2.GDT和IDT在内核数据段中,因此他们的线性地址也同样等同于他们的物理地址。在实模式下setup.s程序初始化操作中,我们曾经设置过临时的GDT和IDT,这是进入保护模式之前必须设置的。由于这两个表当时处于物理内存大约0x90200处,而进入保护模式之后内核系统模块处于物理内存0开始位置,并且0x90200处的空间也被挪作他用(用于高速缓冲),因此在进入保护模式后,在运行的第一个程序head.s中要重新设置这两个表。即设置GDTR和IDTR指向新的GDT和IDT,描述符也需要重新加载。由于开启分页机制时这两个表的位置没有变动,因此无需再重新建立或移动表位置。

3.除任务0以外,所有其他任务所需要的物理页面与线性地址中不同或部分不同,因此内核需要动态的在主内存区中为他们作映射操作,动态的建立页目录项和页表项。虽然任务的代码和数据也在内核中,但由于它需要另行分配获得内存,因此也需要自己的映射表项。

任务0的地址对应关系

  任务0是系统中第一个人工启动的任务。他的代码段和数据段长度被设置为640kb。该任务的代码和数据直接包含在内核代码和数据中,是从地址0开始的640KB的内容,因此它可以直接使用内核代码已经设置好的页目录和页表进行分页地址变换,同样,它的代码和数据在线性地址空间也是重叠的,对应的任务状态段TSS0也是手工预设值好的,并且位于任务0数据结构中,参见sched.h第113行开始的内容。TSS0段位于内核sched.c程序的代码中,长度为104字节,具体位置参加图5-23中"任务0结构信息"所示。三个位置的对应关系如图5-15所示:

  由于任务0直接包含在内核中,不再需要为其重新分配内存页,它运行时需要的内核态堆栈和用户态堆栈空间也都在内核代码区中,并且由于在内核初始化时(head.s)这些内核页面在页表项中的属性都已经被设置成了0b111,即对应页面用户可读写且存在,因此用户堆栈user_stack[]空间虽然在内核空间中,但任务0仍能对其进行读写操作。

任务1的地址对应关系

  与任务0类似,任务1也是一个特殊任务。它的代码也在内核代码区域中。与任务0不同的是在线性地址空间中系统在使用fork()创建任务1(init进程)时为存放任务1的二级页表而在内存中申请了一页内存区域来存放,并复制了父进程的页目录和二级页表项。因此任务1拥有自己的页目录和页表表项,它把任务1占用的线性空间范围64M-128M(实际上是64M-64M+640KB)也同样映射到物理地址0-640KB处。此时任务1的长度也是640KB,并且其代码段和数据段相重叠,只占用一个页目录项和一个二级页表。另外,系统还会为任务1在主内存区域中申请一页内存来存放它的任务数据结构和用作任务1的内核堆栈空间。任务数据结构中包括任务1的TSS段结构信息,如下图:

  任务1的用户态堆栈空间将直接共享使用处于内核代码和数据区域(线性地址0-640KB)中任务0的用户态堆栈空间user_stack[](参见kernek/sched.c,第67-72行),因此这个堆栈需要在任务1实际使用时保持“干净”,以确保被复制用于任务1的堆栈不含有无用数据,在刚开始创建任务1时,任务0的用户态堆栈user_stack[]与任务1共享使用,但当任务1 开始运行时,由于任务1映射到user_stack[]处的页表被设置成只读,使得任务1在执行堆栈操作时将会引起写页面异常,从而由内核另行分配主内存区页面作为堆栈空间使用。

  其他任务的地址对应关系

  对于被创建的从任务2开始的其他任务,它们的父进程都是init(任务1)进程,我们已经知道,在linux 0.11系统中共可以有64个进程同时存在,下面以任务2为例来说明其他任何任务队地址空间的使用情况。

  从任务2开始如果任务号以nr表示,那么任务nr在线性地址空间中的起始位置被设定在nr*64M处,例如任务2的开始位置=nr*64M=2*64M=128M。任务代码段和数据段的最大长度被设置为64M,因此任务2占有的线性地址空间范围是128M-192M,共占用64M/4M=16个页目录项,虚拟空间中任务代码段和数据段都被映射到线性地址空间中相同的范围,因此它们也会完全重叠。图5-17显示出了任务2的代码段和数据段在三种地址空间中的对应关系。

  在任务2被创建出来之后,将在其中运行execve()函数来执行shell程序,当内核通过复制任务1刚创建任务2时,除了占用线性地址空间范围不同以外(128M-128M+640K),此时任务2的代码和数据在三种地址空间中的对应关系和任务1的类似。当任务2的代码(init())调用execve()系统调用开始加载并执行shell()程序时,该系统调用会释放掉从任务1复制的页目录和页表表项及相应的内存页面,然后为新的执行程序shell重新设置页目录和页表表项。在执行execve()函数时,系统虽然为任务2分配了64M的空间范围,但是内核并不会立刻为其分配和映射物理页面,只有当任务2开始执行时由于发生缺页而引起异常时才会由内存管理程序为其在主内存区中分配并映射一页物理内存到其线性地址空间中,这种分配和映射物理内存的方法称为需求加载(load on demand).

转载于:https://www.cnblogs.com/coderCaoyu/p/3618854.html

5.3.6 虚拟地址、线性地址和物理地址之间的关系相关推荐

  1. 逻辑地址、线性地址和物理地址之间的转换

    首先说明一点,本篇的文章是根据自己的理解总结,但是图可能是在已有的博客中截图的,在此对那些对我理解该部分知识提供帮助的博客博主表示感谢! 在逻辑地址.线性地址和物理地址一节中,已经对逻辑地址.线性地址 ...

  2. c 取地址 虚拟地址 物理地址_通过linux0.11源码理解进程的虚拟地址、线性地址、物理地址...

    进程的地址有三种,分别是虚拟地址(逻辑地址).线性地址.物理地址.在分析之前先讲一下进程执行的时候,地址的解析过程.在保护模式下,段寄存器保存的是段选择子,当进程被系统选中执行时,会把tss和ldt等 ...

  3. 逻辑地址、线性地址、物理地址和虚拟地址初步认识

    早期的内存分配机制 在早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址.当计算机同时运行多个程序时,必须保证这些 ...

  4. linux内核线性地址等于物理地址,Linux 从虚拟地址到物理地址

    我们都知道,动态共享库里面的函数的共享的,这也是动态库的优势所在,就是节省内存.C 编译出来的可执行文件几乎都会用到libc的库,假如没有这个共享的技术,每个可执行文件都要占一份libc库的内存,这将 ...

  5. linux内存管理---虚拟地址、逻辑地址、线性地址、物理地址的区别(一)

    分析linux内存管理机制,离不了上述几个概念,在介绍上述几个概念之前,先从<深入理解linux内核>这本书中摘抄几段关于上述名词的解释: 一.<深入理解linux内核>的解释 ...

  6. CPU中虚拟地址、逻辑地址(有效地址)、线性地址、物理地址

    虚拟地址.逻辑地址(有效地址).线性地址.物理地址 1.虚拟地址 2.逻辑地址(有效地址) 3.线性地址 4.物理地址 5.总结 1.虚拟地址 在实模式下,虚拟地址是指由程序产生的由段选择符和段内偏移 ...

  7. 逻辑地址、虚拟地址、线性地址、物理地址

    逻辑地址.虚拟地址.线性地址.物理地址的区别: 虚拟地址: 在保护模式下,虚拟地址由段选择子+段内偏移量组成.利用段选择子可以获取到段描述符,再从段描述符中取得段的基地址.也就是说虚拟地址就是xxxx ...

  8. (转)逻辑地址,线性地址,物理地址的差别

    段页式内存管理中,逻辑地址,线性地址,物理地址的差别 线性地址是逻辑地址到物理地址变换之间的中间层,是处理器可寻址的内存空间(称为线性地址空间)中的地址.程序代码会产生逻辑地址,或者说是段中的偏移地址 ...

  9. 逻辑地址,线性地址,物理地址

    2019独角兽企业重金招聘Python工程师标准>>> 本人是搞java开发的,但是了解一些底层的东西能帮助我理解一些编程上的东西. linux使用的基本上都是虚拟地址,内核程序中用 ...

最新文章

  1. 模拟IIC与硬件IIC的区别!
  2. 洛谷 - P4568 [JLOI2011]飞行路线(分层图最短路)
  3. NET问答: 如何将 ASP.NET Core WebAPI 中抛出的异常封装成对象?
  4. 论文浅尝 | AAAI2020 - 基于规则的知识图谱组合表征学习
  5. word2vector数据集样式_这样做数据可视化驾驶舱,高端大气,一目了然,领导不点赞都难...
  6. python定义了函数却显示未定义_python
  7. 计算机应用能力power,全国专业技术人员计算机应用能力考试专用教材——PowerPoint 2003中文演示文稿5日通题库版(双色)(附光盘) - 中国考研网...
  8. ASP.NET自动回发的内幕
  9. 欧拉函数之和(51nod 1239)
  10. 解决Eclipse开发工具Debug调试JDK源码无法查看变量值
  11. android连接airprint打印机,AirPrint:iOS的打印机
  12. SAP固定资产业务配置及操作手册
  13. 微信小程序 #项目笔记# | 从0到1实现婚礼邀请函小程序
  14. android 集成x5内核时 本地没有,腾讯X5内核集成一些建议和爬坑记录
  15. 解析torch.norm函数
  16. 如何将App程序发布到苹果App Store
  17. 解决error: invalid operands of types ‘const char [6]‘ and ‘const char [6]‘ to binary ‘operator+‘
  18. html什么用于创建表格的标题,在HTML页面中,()标记用于为表格中的一列指定一个标题(选一项)...
  19. 企业微信小程序-获取员工信息
  20. KeyTweak(笔记本键盘设置工具) V2.20 中文版

热门文章

  1. 自己做的几个小软件(数学工具和游戏),用C/C#制作,用到许多相关的C#技术细节,可以免费提供下载,感兴趣的,来看一下...
  2. hibernate -- HQL语句总结
  3. JavaScript之三:jQuery插件开发(一)
  4. Spring @Transactional (一)
  5. nginx php win平台配置
  6. [转]VS2010安装说明及所有安装出错的解决办法
  7. rpm安装文件制作和使用
  8. redis批量操作及性能分析
  9. Python练习1-文档格式化成html
  10. UVA11722(见面概率)