个字节,段信息无法直接存放在段寄存器中(段寄存器只有2字节)。Intel的设计是段描述符集中存放在GDT或LDT中,而段寄存器存放的是段描述符在GDT或LDT内的索引值(index)。

Linux中逻辑地址等于线性地址。为什么这么说呢?因为Linux所有的段(用户代码段、用户数据段、内核代码段、内核数据段)的线性地址都是从 0x00000000 开始,长度4G,这样 线性地址=逻辑地址+ 0x00000000,也就是说逻辑地址等于线性地址了。

这样的情况下Linux只用到了GDT,不论是用户任务还是内核任务,都没有用到LDT。GDT的第12和13项段描述符是 __KERNEL_CS 和__KERNEL_DS,第14和15项段描述符是 __USER_CS 和__USER_DS。内核任务使用__KERNEL_CS和__KERNEL_DS,所有的用户任务共用__USER_CS 和__USER_DS,也就是说不需要给每个任务再单独分配段描述符。内核段描述符和用户段描述符虽然起始线性地址和长度都一样,但DPL(描述符特权级)是不一样的。__KERNEL_CS 和__KERNEL_DS 的DPL值为0(最高特权),__USER_CS 和__USER_DS的DPL值为3。

用gdb调试程序的时候,用info reg 显示当前寄存器的值:

cs             0x73     115

ss             0x7b     123

ds             0x7b     123

es             0x7b     123

可以看到ds值为0x7b, 转换成二进制为 00000000 01111011,TI字段值为0,表示使用GDT,GDT索引值为 01111,即十进制15,对应的就是GDT内的__USER_DATA 用户数据段描述符。

从上面可以看到,Linux在x86的分段机制上运行,却通过一个巧妙的方式绕开了分段。

Linux主要以分页的方式实现内存管理。

位的线性地址被分成3个部分:

最高10位 Directory 页目录表偏移量,中间10位 Table是页表偏移量,最低12位Offset是物理页内的字节偏移量。

页目录表的大小为4k(刚好是一个页的大小),包含1024项,每个项4字节(32位),项目里存储的内容就是页表的物理地址。如果页目录表中的页表尚未分配,则物理地址填0。

页表的大小也是4k,同样包含1024项,每个项4字节,内容为最终物理页的物理内存起始地址。

每个活动的任务,必须要先分配给它一个页目录表,并把页目录表的物理地址存入cr3寄存器。页表可以提前分配好,也可以在用到的时候再分配

还是以 mov    0x80495b0, %eax 中的地址为例分析一下线性地址转物理地址的过程。

前面说到Linux中逻辑地址等于线性地址,那么我们要转换的线性地址就是0x80495b0。转换的过程是由CPU自动完成的,Linux所要做的就是准备好转换所需的页目录表和页表(假设已经准备好,给页目录表和页表分配物理内存的过程很复杂,后面再分析)。

内核先将当前任务的页目录表的物理地址填入cr3寄存器。

线性地址 0x80495b0 转换成二进制后是 0000 1000 0000 0100 1001 0101 1011 0000,最高10位0000 1000 00的十进制是32,CPU查看页目录表第32项,里面存放的是页表的物理地址。线性地址中间10位00 0100 1001 的十进制是73,页表的第73项存储的是最终物理页的物理起始地址。物理页基地址加上线性地址中最低12位的偏移量,CPU就找到了线性地址最终对应的物理内存单元。

我们知道Linux中用户进程线性地址能寻址的范围是0 - 3G,那么是不是需要提前先把这3G虚拟内存的页表都建立好呢?一般情况下,物理内存是远远小于3G的,加上同时有很多进程都在运行,根本无法给每个进程提前建立3G的线性地址页表。Linux利用CPU的一个机制解决了这个问题。进程创建后我们可以给页目录表的表项值都填0,CPU在查找页表时,如果表项的内容为0,则会引发一个缺页异常,进程暂停执行,Linux内核这时候可以通过一系列复杂的算法给分配一个物理页,并把物理页的地址填入表项中,进程再恢复执行。当然进程在这个过程中是被蒙蔽的,它自己的感觉还是正常访问到了物理内存。

Linux0.11 中对地址的管理的更多相关文章

  1. 从linux0.11中起动部分代码看汇编调用c语言函数

    上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...

  2. 对Linux0.11 中 进程0 和 进程1分析

    1. 背景 进程的创建过程无疑是最重要的操作系统处理过程之一,很多书和教材上说的最多的还是一些原理的部分,忽略了很多细节.比如,子进程复制父进程所拥有的资源,或者子进程和父进程共享相同的物理页面,拥有 ...

  3. 在Linux-0.11中实现基于内核栈切换的进程切换

    原有的基于TSS的任务切换的不足 进程切换的六段论 1 中断进入内核 2 找到当前进程的PCB和新进程的PCB 3 完成PCB的切换 4 根据PCB完成内核栈的切换 5 切换运行资源LDT 6 利用I ...

  4. Linux0.11中对文本文件进行修改的策略

    现在,假设 hello.txt 是硬盘上已有的一个文件,而且内容为 "hello, world" ,在文件的当前指针设置完毕后,我们来介绍 sys_read , sys_write ...

  5. linux0.11改进之四 基于内核栈的进程切换

    这是学习哈工大李治军在mooc课操作系统时做的实验记录.原实验报告在实验楼上.现转移到这里.备以后整理之用. 完整的实验代码见:实验楼代码 一.tss方式的进程切换 Linux0.11中默认使用的是硬 ...

  6. Linux0.11启动过程

    从开机加电,到执行main函数之前的过程 好吧,这里应该是有执行3个汇编的文件,但是我不太了解.囧 从main函数,到启动OK(即可以响应用户操作了) 这个步骤做了3件事情: 创建进程0,使之具备在主 ...

  7. x01.os.20: compile linux-0.11 on the ubuntu

    为什么学习 linux 正如不能依靠美国的 GPS 为我们的导弹指示目标一样,很难想像用运行 windows 的电脑去同美国进行信息战.而朝鲜的网络崩溃,再次警示国人,信息战.网络战离我们并不遥远.l ...

  8. Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析

    Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...

  9. linux0.11内核源码剖析:第一篇 内存管理、memory.c【转】

    转自:http://www.cnblogs.com/v-July-v/archive/2011/01/06/1983695.html linux0.11内核源码剖析第一篇:memory.c July  ...

随机推荐

  1. windows pe

    下载adk https://www.microsoft.com/en-us/download/details.aspx?id=30652 安装 C:\Program Files (x86)\Windo ...

  2. 大规模WebGL应用引发浏览器崩溃的几种情况及解决办法

    一般的Web应用基本上不会导致浏览器崩溃,写Javascript代码也不需要管理内存资源,基本也不需要考虑内存"泄露"的问题.随着H5的崛起,越来越多的原本在桌面端的软件也改头换面 ...

  3. Redis之(六)配置详解

    进入Redis的安装包,里面的"redis.conf"就是默认的配置文件,启动Redis Server的时候,可以指定加载某个路径下的配置文件"redis-server ...

  4. ScrollView嵌套ListView后,进入页面不从顶部开始显示的问题解决

    ScrollView嵌套ListView后,进入页面不从顶部开始显示的问题解决 首先,正常情况下,如果在ScrollView里嵌套ListView后,会发现ListView只显示1条数据 那么,为了解 ...

  5. 使用Linux脚本更新Weblogic部署的应用程序

    在利用Jenkins实现Weblogic应用自动部署的功能时,如何通过Shell 脚本自动更新Weblogic部署的应用程序呢? 可以使用weblogic.jar包中的weblogic.Deploye ...

  6. wget 常用参数释义

    wget 大法好啊,废话不多说,下面开始wget之旅吧. 下载限速 wget命令有一个内建的选项可以先顶下载任务占有的最大的带宽,从而保证其他应用程序的流畅运行. 具体使用--limit-rate 数 ...

  7. Dynamics CRM2013 在Visual Studio中开启脚本的Xrm.Page智能提示

    前面篇博文http://blog.csdn.net/vic0228/article/details/49663751提到了通过引用XrmPage-vsdoc.js文件来启用Xrm.Page的智能提示, ...

  8. CUSTOM.PLL的使用

    在开发中对系统标准form的修改一般不建议修改系统原有FORM,对所需要修改的内容一般写在CUSTOM.PLL里即可,应为每个form运行的时候都会调用CUSTOM.PLL具体概念性东西可参考网上资料 ...

  9. 2.7、Android Studio使用翻译编辑器本地化UI

    如果你的应用支持多语言,你需要合理的管理你的翻译的string资源.Android Studio 提供了翻译编辑器来使查看和管理翻译的资源更加容易. 关于翻译编辑器 翻译后的资源在你的项目里保存在不同 ...

  10. Spark技术内幕:Master基于ZooKeeper的High Availability(HA)源码实现

    如果Spark的部署方式选择Standalone,一个采用Master/Slaves的典型架构,那么Master是有SPOF(单点故障,Single Point of Failure).Spark可以 ...