当前位置: 首页 > news >正文

xv6 附录A

        我们可以把PC抽象为三部分:CPU,内存和I/O设备。

        CPU:负责计算和执行指令

        内存:用于保存计算用的指令和数据

        I/O设备:外部世界,包含键盘,屏幕,硬盘和网卡等。CPU和内存自成一体,它们也需要与外界通信,OS负责充当中介,管理这些外部设备。

        xv6 操作系统,就是一个运行在 CPU 上的、驻留在内存中的程序,它的工作就是管理好 CPU、内存,以及所有的 I/O 设备。


        补一下CPU工作循环相关的硬件的概念:

        程序计数器:一个特殊的寄存器,它的唯一的工作就是保存吓一跳要执行的指令的内存地址。

        内存:存储着成千上万的机器指令和数据。

        指令寄存器:CPU内部的一个临时存储区,用于存放当前正在被解码和执行的指令。

        通用寄存器:CPU内部的极高速存储,它们是 CPU 进行计算时(如加法、减法)存放操作数和结果的地方。

        总线:连接CPU和内存的导线。

        地址总线:CPU用它来指定要访问的内存地址。

        数据总线:用于在CPU和内存之间传输数据或指令。

        控制总线:CPU用它来发送读或写的命令。


        CPU(中央处理单元,或处理器)其实只是在执行一个非常简单的循环。假设程序计数器当前值为0x80100040,这意味着CPU准备好要执行存放在内存地址 0x80100040 处的指令。

1. 取指 (FETCH)

目标: 将位于 0x80100040 地址的“机器指令”从内存(RAM)取回到 CPU 内部。

  1. CPU -> 地址总线: CPU 的控制单元将 0x80100040 这个值(来自 PC)放置到地址总线上。

  2. CPU -> 控制总线: CPU 在控制总线上发出一个“内存读取”(Memory Read) 信号。

  3. 内存响应: 内存(RAM)检测到地址总线上的地址和控制总线上的“读取”信号。它从自己的 0x80100040 存储单元中取出数据(这个数据就是“机器指令”,比如 0x00508093)。

  4. 内存 -> 数据总线: 内存将这个指令(0x00508093)放置到数据总线上。

  5. CPU 接收: CPU 通过数据总线接收到这个指令,并将其存入 CPU 内部的指令寄存器 (IR) 中。

2. 程序计数器增加 (PC Increment)

目标: 让 PC 指向“下一条”指令,为下一次循环做准备。

  • 几乎在取指的同时,CPU 内部的逻辑单元(不是主 ALU)会自动将 PC 的值增加一个指令的长度(例如,在 RISC-V 中是 4 字节)。

  • 计算: PC = 0x80100040 + 4 = 0x80100044

  • 关键: 此时,PC 已经指向了下一条指令 (0x80100044),尽管当前指令 (0x80100040) 甚至还没有开始执行。这确保了循环的连续性。

3. 解码 (DECODE)

目标: 搞清楚 0x00508093 这条指令到底是要“干什么”。

  1. 指令寄存器 (IR) 中的 0x00508093 被送入 CPU 的指令解码器(一个复杂的逻辑电路)。

  2. 解码器根据指令集架构(ISA,如 x86 或 RISC-V)的规则,将这个 32 位数字拆分开。

  3. 例如 (RISC-V): 解码器会识别出:

    • 操作码 (Opcode): 这是 addi 指令(立即数加法)。

    • 源寄存器 (Source): 需要读取 a0 寄存器。

    • 立即数 (Immediate): 需要使用数字 5

    • 目标寄存器 (Destination): 结果要写入 a1 寄存器。

  4. 激活电路: 解码器根据这些信息,向 CPU 的其他部分(如 ALU、寄存器堆)发送控制信号,告诉它们下一步该做什么(“准备好,我们要从 a0 读,要和一个 5 相加,然后把结果写入 a1”)。

4. 执行 (EXECUTE)

目标: 实际执行 addi a1, a0, 5 这个操作。

  1. 读寄存器: 控制单元命令通用寄存器堆,将 a0 寄存器中的值发送到 ALU (算术逻辑单元) 的输入端 A。

  2. 送立即数: 控制单元将解码出的立即数 5 发送到 ALU 的输入端 B。

  3. ALU 计算: 控制单元命令 ALU 执行“加法”操作。ALU 计算出(a0 的值 + 5)的结果。

  4. 写寄存器: 控制单元将 ALU 的计算结果通过内部总线,发送回通用寄存器堆,并命令将其写入a1 寄存器中。

5. 不断反复 (REPEAT)
  • 当“执行”步骤完成后,一个时钟周期(或多个周期)过去了。

  • CPU 的控制单元回到第 1 步 (FETCH)

  • 这一次,它查看 PC (程序计数器),发现 PC 的值已经是 0x80100044(在第 2 步中被更新了)。

  • 于是,CPU 开始从 0x80100044 地址取下一条指令。循环往复。


        寄存器,ALU(算术逻辑单元),CU(控制单元)是构成CPU(中央处理器)的三大核心部件:

部件 (Component)角色 (Role)主要功能 (Primary Function)
寄存器 (Registers)临时存储 (Storage)保存数据:高速保存 CPU 正在处理的单个数据(如变量、地址、指令)。
ALU (算术逻辑单元)执行者 (Execution)执行计算:执行所有数学运算(加、减)和逻辑运算(与、或、非、比较)。
CU (控制单元)指挥官 (Control)指挥协调:解码指令,并生成控制信号,指挥寄存器和ALU在何时、做什么。

三者的协同工作流程

我们以一条简单的 RISC-V 指令 add a1, a0, s0 (意思是:a1 = a0 + s0) 为例,看看它们三者是如何在时钟驱动下协同工作的:

  1. CU (控制单元) - 取指与解码

    • CU 首先执行“取指”操作,从内存(通过程序计数器 pc 寄存器)获取 add a1, a0, s0 这条机器指令。

    • CU 的“解码器”部分识别出:这是一条 R-Type(寄存器-寄存器)加法指令。

    • CU 立即知道它需要指挥以下动作:

      1. a0 读。

      2. s0 读。

      3. 命令 ALU 做加法。

      4. a1 写。

  2. CU (指挥) -> 寄存器 (读)

    • CU寄存器堆发送控制信号,命令它:“在下一个时钟周期,允许读取 a0s0 寄存器的值”。

    • CU 同时配置 ALU:“准备执行‘加法’操作”。

  3. 寄存器 -> ALU (执行)

    • a0 的值被送到 ALU 的输入端 A。

    • s0 的值被送到 ALU 的输入端 B。

    • ALU(在 CU 的“加法”命令下)执行 A + B 的计算,得到结果。

  4. CU (指挥) -> ALU -> 寄存器 (写)

    • ALU 将计算结果放在它的输出端。

    • CU寄存器堆发送控制信号:“在下一个时钟周期,允许写入 a1 寄存器”。

    • ALU 的输出结果(a0 + s0 的值)被送入并存放在 a1 寄存器中。


        然后讨论一下时钟周期的事情吧,其实在网卡那里已经接触过这个概念了,在PC内部,CPU,内存,总线等都连接到同一个系统时钟上,和网卡那里解决的时钟不同步的问题不同,它们共享同一个时钟。当时钟的滴答声响起时,所有时序逻辑的部件(主要是寄存器)会同时采样或锁存它们输入端的数据。在两次滴答声之间,信号正物理地从一个部件传输到另一个部件,比如,ALU这是就忙于计算,它的输出正在从上一次的计算结果变化为这一次的计算结果,到下一次滴答声之前,它可以稳定电压并输出,届时这个电压又会被寄存器的输入端读取。时钟周期的长度,由最慢的哪个单周期工作决定(也有多周期的指令,但是我不管了)。工程师会精确计算出关键路径,然后把时钟周期设定为略大于这个值。


        然后探讨速度和成本的事情(你可能在很多地方看到过,我反正是):数据存放在哪里?

第1层 (塔尖): 寄存器 (Registers)

        寄存器在CPU内部,速度极快(CPU访问寄存器的时间短到可以在一个时钟周期内完成,它和CPU的速度相匹配),但极小(只有几十个)。

第2层 (中间): 缓存 (Cache)

        由于寄存器和主存在读写速度和大小上的巨大差异,大多数处理器,包括 x86,都在芯片上的缓存中保存了最近使用的主存数据,缓存在CPU芯片上,但在核心之外。缓存是主存和寄存器在速度和大小上的折衷。通常 x86 对操作系统隐藏了缓存,所以我们只需要考虑寄存器和主存两种存储器,不用担心主存的层次结构引发的差异(即缓存由硬件全自动管理,操作系统不需要也不能用软件代码区直接控制它)。

第3层 (塔底): 主存 (RAM)

        慢,便宜。CPU和主存之间是最特殊,最快的连接,它不是IO总线,而是通过内存总线(超高速直连通道,当然,高速只是相对于计算核心与其他外部设备通过IO总线连接)


        我们已经知道,在取指的过程中,CPU先读取寄存器中的内存地址,然后把地址放到地址总线上,接着在控制总线上发出“内存读取”的指令,然后内存检测到地址总线上的地址和控制总线上的指令,输出数据。可以看到,地址是CPU用来指定其操作位置的唯一机制

        与此同时,CPU需要读写两个地方,主存和I/O设备,当CPU发出一个请求到地址比如0x3F8时,硬件系统需要知道这个请求是发给主存还是发给I/O设备。为解决这个问题有两个方案。

        方案一端口映射:

  • 概念: 硬件架构(CPU 和芯片组)定义了两个各自独立的地址空间 (Address Spaces)。

    1. 内存地址空间 (Memory Address Space): 一个巨大的地址范围(例如 0 到 4GB)。

    2. I/O 端口空间 (I/O Port Space): 一个额外的、小得多的地址范围(例如 0 到 65535)。

  • 如何区分: 地址 0x3F8 在“内存空间”和“I/O 空间”中同时存在,它们是两个完全不同的物理位置。 CPU 必须使用不同的机器指令来声明它想访问哪个空间:

    • 当 CPU 执行 mov, load, store 指令时,它的控制单元 (CU) 被硬编码(wired)为只访问“内存地址空间”

    • 当 CPU 执行特殊的 inout 指令时,它的 CU 被硬编码为只访问“I/O 端口空间”。(这也是xv6所采用的方案

  • 硬件实现(如文所述): 当 CPU 执行指令时:

    • mov [0x3F8]:CPU 将 0x3F8 放在地址总线上,同时在一条特殊的控制总线引脚上输出信号 1(代表“内存访问”)。主存 (RAM) 会响应这个请求。

    • out 0x3F8, al:CPU 将 0x3F8 放在地址总线上,同时在那条特殊的控制总线引脚上输出信号 0(代表“I/O 访问”)。I/O 设备(串口)会响应这个请求。

        方案二内存映射:

  • 概念: 硬件架构只定义一个统一的地址空间,即内存地址空间

  • 如何区分: 系统不需要区分。系统设计师(硬件层面)在启动时就**“保留” (Reserve)** 了一部分内存地址。

    • 例如,总地址空间是 0 到 64GB。

    • 地址 0x00_0000...0x0F_FFFF... (前 40GB) 被映射 (Mapped) 到物理 RAM 芯片。

    • 地址 0xF0_0000...0xF0_0FFF... (中间的一小块) 被保留,并映射到网卡的控制寄存器。

  • 硬件实现: CPU 只使用 loadstore 指令(RISC-V 根本没有 in/out 指令)。 主板上的地址解码器(Address Decoder,芯片组的一部分)负责“路由”请求:

    • CPU 执行 store (存数据) 到地址 0x08_1234...

    • 地址解码器看到这个地址,“识别出”它属于RAM 的范围,于是将请求转发给主存 (RAM)。

    • CPU 执行 store (存数据) 到地址 0xF0_0008...

    • 地址解码器看到这个地址,“识别出”它属于网卡的保留范围,于是将请求转发网卡,而不是主存 (RAM)。


        

http://www.dtcms.com/a/574202.html

相关文章:

  • 【设计题】如何实现一个线程安全的缓存?
  • 网站透明效果wordpress广告插件中文
  • 网站建设费用进会计什么科目界面设计与制作是做什么的
  • 中小企业网站建设如何c 网站开发教程
  • 深度学习-池化层
  • ruoyi-app学习路线
  • 网站群建设意见网站建设+廊坊
  • 数据库关系模式核心概念详解:候选关键字与无损连接判断
  • 做外贸上哪些网站找客户网页设计收费标准
  • 阿里云ALB可编程脚本示例
  • wordpress网站非常慢网站备案协议书
  • Nginx防御HTTP Host头注入漏洞:实战配置漏洞修复教程
  • 南宁手机网站制作公司软件工程学什么课程
  • HTML - 换行标签的 3 种写法(<br>、<br/>、<br />)
  • 做电影网站需要的服务器配置wordpress程序伪静态
  • 是网站建设专业好做如美团式网站要多少钱
  • RPA概念是什么?和AI有哪些区别?
  • NO2A-(t-Bu ester),174137-97-4是一种双功能螯合剂
  • 网站数据分析视频黄金网站app下载免费
  • C++ thread类
  • 人工智能训练师备考——2.1.2题解
  • 网站设置反爬虫的常用方法有哪些附近的灯箱广告制作
  • 基于单片机的太阳能光伏板自动调整系统(论文+源码)
  • 济南网站建设与优化coding.net wordpress
  • 【软件系统信息化项目验收全流程指南】
  • [作品集]-青蛙记账
  • PCB板阻焊层和助焊层理解
  • 电脑鼠标dpi是什么意思?实用设置教程分享
  • 网站开发开票编码归属石家庄工程造价信息网官网
  • Parasoft C/C++test如何解决在VC6环境中单元测试的LNK2005错误