个字节,段信息无法直接存放在段寄存器中(段寄存器只有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. 2016-wing的年度总结

    大神们都爱写总结,为了早日成为大神,我也来写一波. 2016 有很多事情发生. 从日常生活来讲,生活水平得到了一定提升,从600一个月的村子搬到了800一个月的村子(/捂脸); 从就业环境来讲,许多人 ...

  2. springMVC源码分析--ViewResolver视图解析器(一)

    SpringMVC用于处理视图最重要的两个接口是ViewResolver和View.ViewResolver的主要作用是把一个逻辑上的视图名称解析为一个真正的视图,SpringMVC中用于把View对 ...

  3. win10+ubuntu双系统安装方案

    网上有很多教程,大多是win7,win8的,我折腾了一天,今天终于都安装好了,折腾的够呛,很多人都说挺简单的,嗯其实的确很简单,很多人回复说安装不成功,很有可能就是电脑安全权限的问题,我用的是华硕的电 ...

  4. 百度编辑器UEditor常用设置函数

    最近在研究UEditor的使用,下面是附上传送门: 这是API文档http://ueditor.baidu.com/doc/ 这是下载地址http://ueditor.baidu.com/websit ...

  5. Dynamics CRM2016 Web API之Use custom FetchXML

    CRM2016中新增的web api支持fetch xml了,之前使用FetchXML的场景是在后天代码中通过组织服务的retrieve multiple方法,但实际的应用效果有多大,还需要在实际的项 ...

  6. octave installation on RHEL6.4

    octave installation on RHEL6.4 rhel6.4上安装octave GNU Octave 是一种高级语言,主要设计用来进行数值计算,它是 MathWorks 出品的 Mat ...

  7. MyBatis Generator For Eclipse 插件安装

    由于在ORM框架MyBatis中,实现数据表于JavaBean映射时,配置的代码比较的复杂,所以为了加快开发的效率,MyBatis官方提供了一个Eclipse的插件, 我izuoyongjiushis ...

  8. Android实现横屏以及全屏的小技巧

    分享两个安卓的实用小技巧,那就是横屏和全屏的实现. 首先是横屏的实现 首先是在清单文件中实现 <activity android:name=".MainActivity" a ...

  9. 人类创造未来的思想先锋:这些 TED 演示深深震撼着我们

    今年亮点之一是谷歌创始人拉里佩奇的演讲.他有一个核心观点:特别成功的公司,是那些敢于想象未来,并付出行动创造未来的公司.这听上去是老生常谈,但又确实是个真理.他实际上想说预测未来的最好方式就是创造它, ...

  10. Dynamics CRM 2015 Online Update1 UI界面的更新变化

    听说出  Dynamics CRM 2015 Online  Update1了,立马跑去申请了个30天试用版简单的看了下,UI上的变化还是让人耳目一新的,也可能是被CRM2013的UI蹂躏太久了没 ...