对于一个操作系统来说,如果下面的硬件环境千差万别,就会很难集中精力做出让用户易用的产品。比较天天适配不同的平台就很头大了。因此,就出现了x64架构这样一个开放的平台。

计算机的工作模式是什么样的

计算机是由一堆硬件组成的:

  • 对一台计算机来讲,最核心的就是CPU(Central Processing Unit,中央处理器),这是计算机的大脑,所有的设备都围绕它展开(CPU是一条计算机中真正干活的设备)
  • CPU和其他设备连接,要靠一种叫做总线(Bus)的东西,其实就是主板上密密麻麻的集成电路,这些东西组成了CPU和其他设备的高速通道。
  • 在这些设备中,最重要的是内存(memory)。因为单靠CPU是没办法完成计算任务的,很多复杂的计算任务都需要将中间结果保存下来,然后基于中间结果进行进一步的计算。CPU本身没办法保存这么多的中间结果,这就要依赖内存了
  • 当然总线上还有一些其他设备,比如显卡会连接显示器、磁盘控制器会连接硬盘、UDB控制器会连接键盘和鼠标等等

计算机是怎么工作的?

  • CPU有三个部分组成:运算单元、数据单元和控制单元

    • 运算单元只管计算,比如做加法、做位移等等。但是,它不知道应该算哪些数据,运算结果应该放在哪里
    • 运算单元计算的数据如果每次都要经过总线,到内存里面现拿,这样就太慢了,所以就有了数据单元。数据单元包括CPU内部的缓存和寄存器组,空间很小,但是速度很快,可以暂存数据和计算结果
    • 有了放数据的地方,也有了算的地方,还需要有个指挥到底做什么运算的地方,这就是控制单元。控制单元是一个统一的指挥中心,它可以获得下一条指令,然后执行这条指令。这个指令会指导运算单元取出数据单元中的某几个数据,计算出结果,然后放在数据单元的某个地方。

  • 进程一旦运行,比如上图中的进程A和进程B,会有独立的内存空间,相互隔离,程序会分布加载到进程A和进程A的内存空间里面,形成各自的代码段。 程序运行过程中要操作的数据和产生的计算结果,都会被放到数据段里面。那CPU是怎么执行这些程序,操作这些数据,产生一些结果,并写回内存呢?

    • CPU的控制单元里面,有一个指令指针寄存器,它里面存放的是下一条指令在内存中的地址。控制单元会不停的将代码段的指令拿进来,先放入指令寄存器
    • 当前指令分为两部分,一部分是做什么操作,比如是加法还是位移,一部分是操作哪些数据。
    • 要执行这条指令,就要把第一部分交给运算单元,第二部分交给数据单元。
    • 数据单元根据数据的地址,从数据段里读到数据寄存器里,就可以参与运算了。运算单元做完运算,产生的结果会暂存在数据单元的数据寄存器中。最终,会有指令将数据写回内存。
    • 补充:CPU是如何同时运行两个进程的
      • CPU里面有两个寄存器,专门保存当前处理进程的代码段的起始地址,以及数据段的起始地址
      • 当地址为进程A的地址,那么当前执行的就是进程A的指令,等切换成进程B,就会执行B的指令了。这个过程叫做进程切换
  • CPU和内存来来回回传输数据,靠的都是总线。其实总线上主要有两类数据:
    • 一个是地址数据,也就是我想拿内存中哪个位置的数据,这种总线叫做地址总线(address bus)
    • 一个是真正的数据,这类总线叫做数据总线(data bus)
  • 所以所有,总线就好比连接CPU和内存这两个设备的高速公路,说总线到底是多少位,就类似说高速公路有几个车道。但是这两种总线的位数意义是不同的。
    • 地址总线的位数,决定了能访问的地址范围有多广。比如只有两位,那CPU就只能认00、01、10、11这四个位置,超过四个位置,就区分不出来了。位数越多,能够访问的位置就越多,能管理的内存的范围也就越广
    • 数据总线的位置,决定了一次能拿多少个数据进来2。比如只有两位,那CPU就只能从内存拿两位数。要想拿八位,就要拿四次,一次拿的数据绝越多,访问速度也就越快。

x86 成为开放平台历史中的重要一笔

那CPU中总线的位数有没有个标准呢?如果没有标准,那操作系统作为软件就很难办了,因为软件层没办法实现通用的运算逻辑。CPU架构不一样,就没法形成统一的体系,就不会有我们现在的通用计算机,更别提什么云计算、大数据这些统一的大平台了。

随着市场的发展,因特网的PC机占据了大部分份额,又公开了一些技术,于是出现了无数IMP-PC兼容机公司的出现,于是, 英特尔的技术成为了行业的开放事实标准。由于这个系列开端于8086,因此统称为x86架构,历史将 x86 平台推到了开放、统一、兼容的位置

从8086的原理说起

x64中最经典的一款处理器叫做8086处理器,虽然它已经很老了,但是操作系统中很多特性都和它相关,并且一直保持兼容。

我们把CPU里面的组件放大之后来看:

  • 我们先来看数据单元

    • 为了暂存数据,8086处理器内部有8个16位的通用寄存器,分别是 AX、BX、CX、DX、SP、BP、SI、DI。
    • 这些寄存器比较灵活,其中AX、BX、CX、DX 可以分成两个 8 位的寄存器来使用,分别是 AH、AL、BH、BL、CH、CL、DH、DL,其中 H 就是 High(高位),L 就是 Low(低位)的意思。
    • 这样,比较长的数据也能暂存(16位),比较短的数据也能暂存。
  • 接下来是数据单元
    • IP寄存器就是指令控制寄存器(Instruction Pointer Register),指向代码段中下一条指令的位置。CPU会根据它来不断的将指令从内存的代码段中,加载到CPU的指令队列中,然后交给运算单元去执行。
    • 如果需要切换进程呢?每个进程都分代码段和数据段,为了指向不同进程的地址空间,有4个 16 位的段寄存器,分别是 CS、DS、SS、ES。
    • CS就是代码段寄存器(Code Segment Register),通过它可以找到代码在内存中的位置;DS是数据段寄存器,通过它可以找到数据在内存中的位置
    • SS是栈寄存器(Stack Register)。栈是程序运行中一个特殊的数据结构,数据的存取只能从一端进行,秉承后入先出的原则,push就是入栈、pop就是出栈
    • 凡是和函数调用相关的操作,都和栈紧密相关。
      • 比如,A调用B,B调用C
      • 当A调用B的时候,要执行B函数的逻辑,因而A运行的相关信息就会被push到栈里面。
      • 当B调用C的时候,B相关的信息也会被push到栈里面,然后才运行C函数的逻辑
      • 当C运行完毕的时候,先pop出来的是B,B就接着调用C之后的指令运行下去
      • B运行完了,在pop出来的就是A,A接着运行,直到结束
    • 如果运算中需要加载内存中的数据,需要通过DS找到内存中的数据,加载到通用寄存器中,应该如何加载呢?对于一个段,有一个起始地址,而段内的具体位置,叫做偏移量。例如 8 号会议室的第三排,8 号会议室就是起始地址,第三排就是偏移量。
    • 在CS和DS中都存放这一个段的起始地址。代码段的偏移量在IP寄存器,数据段的偏移量在通用寄存器
    • 这时候问题来了,CS和DS都是16位的,也就是说,起始地址都是 16 位的,IP 寄存器和通用寄存器都是 16 位的,偏移量也是 16 位的,但是 8086 的地址总线地址是 20 位。怎么凑够这 20 位呢?方法就是“起始地址 *16+ 偏移量”,也就是把 CS 和 DS 中的值左移 4 位,变成 20 位的,加上 16 位的偏移量,这样就可以得到最终 20 位的数据地址。
    • 从这个计算方式可以看出,无论真正的内存是多么大,对于只有20位的地址总线的8086来说,能够区分出的地址也就是2^20=1M,超过这个空间就访问不到了。因为如果你想访问1M+X的地方,这个位置就已经超过20位了,由于地址总线只有20位,在总线上超过20位的部分根本是发布出去的,所以发出去的还是X,最后还是会访问1M内的X的位置。
    • 那一个段最大能都大呢?因为偏移量只能是16位的,所以一个段最大是2^16=64K
    • 也就是对8086CPU,最多只能访问1M的内存空间,还要分成多个段,每个段最多64K

关于32位处理器

后来,随着计算机的发展,内存越来越大,总线也越来越宽。在 32 位处理器中,有 32 根地址总线,可以访问 2^32=4G 的内存。使用原来的模式肯定不行了,但是又不能完全抛弃原来的模式,因为这个架构是开放的。

“开放”,意味着有大量其他公司的软硬件是基于这个架构来实现的,不能为所欲为,想怎么改怎么改,一定要和原来的架构兼容,而且要一直兼容,这样大家才愿意跟着你这个开放平台一直玩下去。如果你朝令夕改,那其他厂商就惨了。

如果是不开放的架构,那就没有问题。硬件、操作系统,甚至上面的软件都是自己搞的,你想怎么改就可以怎么改。

那在开发的架构上,怎么保持兼容呢?

  • 首先,通用寄存器有扩展,可以将8个16位的扩展到8个32位的,但是依然可以保留16 位的和 8 位的使用方式。
  • 其中,执行下一条指令的指令寄存器IP,被扩展为32位的,同样也兼容16位
  • 而改动比较大,有点不兼容的就是段寄存器(Segment Register)。
    • 因为原来的模式其实有点不伦不类,因为它没有把16位当成一个段的起始位置,也没有按照8位或者16位扩展的形式,而是根据当时的硬件,弄了一个不上不下的20位的地址。这样每次都要左移两位,也就意味着段的起始地址不能是任何一个地方,只是能整除16的地方。
    • 如果新的段寄存器都改成32位的,明明4G的内存全部都能访问到,还左移不左移呢?
    • 因此我们索性就重新定义一把。CS、SS、DS、ES仍然是16位的,但是不再是段的起始地址。段的起始地址放在内存的某个地方。这个地方是一个表格,表格中的一项一项是段描述符。这里面才是真正的段的起始地址。而段寄存器里面保存的是在这个表格中的哪一项,叫做选择子
    • 这样,将一个从段寄存器直接拿到的段起始地址,就变成了先间接地从段寄存器找到表格中的一项,再从表格中的一项中拿到段起始地址
    • 这样段起始地址就会很灵活了。当然为了快速拿到段起始地址,段寄存器会从内存中拿到CPU的描述符高速缓存中
    • 这样就不兼容了,咋办呢?好在后面这种模式灵活度非常高,可以保持将来一直兼容下去。前面的模式出现的时候,没想到自己能够成为一个标准,所以设计就没这么灵活。
    • 因此,到了32为的系统架构下,我们将前一种模式叫做实模式(Real Pattern),后一种模式叫做保护模式(Protected Pattern)
    • 当系统刚刚启动的时候,CPU是出于实模式的。当需要更多内存的时候,你可以遵循一定的规则,进行一系列的操作,然后切换到保护模式,就能够用到32位的CPU更强大的能力。也就是说,不能无缝兼容,但是可以通过切换模式兼容

linux操作系统:x86架构,一个良好的运营环境相关推荐

  1. 禾瑞亚USB接口电阻触摸屏控制卡QNX 6.5 RTOS操作系统x86架构驱动安装与配置方法

    禾瑞亚USB接口电阻触摸屏控制卡QNX 6.5 RTOS操作系统x86架构驱动安装与配置方法 前提条件:安装QNX 6.5 RTOS操作系统的主板的USB接口必须能够被操作系统识别,否则连接不到触摸屏 ...

  2. Linux编译x86架构内核出现_stack_chk_guard未定义错误

    背景 android模拟器运行于virtualbox中,而virtualbox运行于x86架构的pc端,所以android及其Linux内核都编译成x86架构.当virtualbox的vt未开启的情况 ...

  3. 如何给Linux操作系统(CentOS 7为例)云服务器配置环境等一系列东西

    1.首先,你得去购买一个云服务器(这里以阿里云学生服务器为例,学生必须实名认证) 打开阿里云,搜索学生服务器点击进入即可 公网ip为连接云服务器的主机 自定义密码为连接云服务器是需要输入的密码 购买即 ...

  4. linux也是x86架构吗,linux下X86架构IDT解析

    一.中断描述符表IDT 1.中断描述符表IDT是一个系统表,它与每一个中断或异常向量相联系,每一个向量在表中有相应的中断或异常处理程序的入口地址.内核在允许中断发生前,必须适当的初始化IDT. 2.I ...

  5. linux内核tor03,Linux内核x86架构引导协议4(翻译)

    字段名称:    type_of_loader 类型:           write (obligatory) 偏移/大小:   0x210/1 协议:    2.00+ 内核加载程序的ID号.这个 ...

  6. x86架构linux内核引导过程分析,Linux内核x86架构引导协议7(翻译)

    运行内核 内核的跳转指令在相对于内核实模式部分为0x20的内存段处.也就是说,如果你把内核的实模式部分加载到了0x90000处,那么内核入口应该在0x9020:0000处. 在进入内核前,ds.es. ...

  7. 【Linux操作系统课堂笔记1】小白入手——环境配置安装

    文章目录: 界面展示: 扩展: 资源: 第一步:创建虚拟机 第二步:虚拟机设备配置 第三步:开始安装系统 界面展示:  扩展: 1.Windows 系统是宿主机,而 VMware 安装的 Linux ...

  8. Linux 操作系统原理 — 内核态与用户态

    目录 文章目录 目录 Linux 的内核态与用户态 系统调用(System Call) Shell 用户态和内核态的切换 进程的用户空间和内核空间的内存布局 内核空间 用户空间 Linux 的内核态与 ...

  9. Linux 操作系统原理 — PCIe 总线标准

    目录 文章目录 目录 总线系统 PCIe 总线 PCIe 总线的传输速率 PCIe 总线的架构 PCIe 外设 PCIe 设备的枚举过程 PCIe 设备的编址方式 BDF(Bus-Device-Fun ...

最新文章

  1. linux大爱版本Vinux 盲人也能用的OS
  2. 233网校java_java辅导:使用java模拟登陆考试大
  3. IEC61850电能质量1~50次谐波有效值建模
  4. 网页中显示flash的时候部分显示红色叉好,而有的能够正常显示
  5. phoenix客户端操作hbase已经存在的表
  6. sqlserver2008未将对象引用设置到对象的实例_JVM | Java对象的创建、存储和访问详解...
  7. Leetcode130.被围绕的区域
  8. 安徽信息技术初中会考上机考试模拟_初中信息技术会考模拟试题
  9. 单引号、双引号和不加引号区别
  10. Eclipse 模板使用
  11. 微信公众号开发相关流程及功能介绍
  12. 自动化办公学习笔记(风变编程)
  13. 数码相框(十六、LCD显示JPG格式图片)
  14. unity3D制作拼图游戏
  15. win7 开wifi 关wifi
  16. java竖线_JAVA 竖线|转义字符 | | 学步园
  17. Win10系统打不开图片
  18. 分享几个免费高清图片素材网站---已解决
  19. 软件测试自我评价模版,软件测试工程师简历自我评价
  20. LVGL学习笔记1 - 准备

热门文章

  1. 最好懂的IC芯片制造流程详解,值得收藏!
  2. 浙大PTA基础编程题目集:7-1 厘米换算英尺英寸
  3. 运动想象脑电数据分享
  4. 手把手教你学Dapr - 7. Actors
  5. 视杯和视盘分割及分类方法对青光眼诊断的探讨
  6. 蓝桥杯之未名湖边的烦恼-递归极简版(c++实现)
  7. #FreeFortnite的卑鄙本质
  8. java 项目打包jar 的配置(springboot )
  9. Spring Aop源码学习--Advice通知
  10. Sawyer机器人助力ASM印刷电路板处理