OS Virtual Memory Management
历史最早期的计算机系统 硬件: 物理内存容量小 软件 单个应用程序 + (简单)操作系统 直接面对物理内存编程 各自使用物理内存的一部分 多道编程时代 多用户多程序: 计算机很昂贵,多人同时使用(远程连接) 分时复用 CPU 资源: 保存恢复寄存器速度很快 分时复用物理内存资源: 将全部内存写入磁盘开销太高 多个进程同时使用、各占一部分物理内存: 没有安全性(隔离性) IBM 360 内存隔离: Protection Key 机制 内存被划分为一个个大小为 2KB 的内存块(Block) 每个内存块有一个 4-bit 的 key,保存在寄存器中 1MB 内存需要 256 个保存 key 的寄存器,占 256-Byte 内存变大,则需要改 CPU 以增加 key 寄存器 每个进程对应一个 key CPU 用另一个专门的寄存器,保存当前运行进程的 key 不同进程的 key 不同 当一个进程访问一块内存时 CPU 检查进程的 key 与内存的 key 是否匹配 不匹配则拒绝内存访问 缺点: 不具有可扩展性,随着内存扩大,需要的 key 寄存器太多,无法实现 可...
Linux RISC-V Boot 流程
硬件初始化两种启动方式: 定制化的主板(常见的 RISC-V 开发板,通常不再扩展其他设备) 通用主板(常见如 PC,通常需要再插入其他设备) 嵌入式设备启动 需要初始化具体主板相关硬件如 GPIO 和内存等 从 devicetree 获知有哪些设备 操作系统中需要很多设备相关的驱动 通常与设备强相关 ROM 通常是闭源的 早期启动流程通常是厂商提供的代码 缺点:对可插拔外设的兼容性 如 RISC-V 嵌入式设备支持 PCIe 外设,需要操作系统内核包含具体硬件上的 PCIe 控制器驱动 RISC-V嵌入式平台常见组合: ROM code(在ROM):主板厂商私有 Bootloader(在SD卡或 SPI flash):如u-boot(非必须) Linux kernel(在SD卡) 以常用的基于 U-Boot 和 OpenSBI 的启动流程为例: 从 ROM 中开始执行代码 SoC 芯片内部包含一块 ROM 保存了一些简单的驱动 从 SD 卡或 flash 加载 U-Boot SPL 到一块小内存中(单独的 SRAM 或 L2 cache-as-RAM) ...
Linux Boot 过程
参考: 中国科学院大学 2025年秋《高级操作系统教程》课件 Linux 启动流程 BIOS : 硬件检测,查找加载磁盘上的 MBR MBR : 存储 bootloader 信息,加载 Grub Grub : 查找并加载 kernel kernel : 装载驱动,挂载 rootfs, 执行 /sbin/init init : OS 初始化,执行 runlevel 相关程序 runlevel: 启动指定级别的服务 GrubLinux 上最常用的 bootloader (GNU GRUB: 来自 GNU 项目的启动引导程序) GRUB 允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统 GRUB 可通过链式引导来引导 Windows 系统 支持所有的 Linux 文件系统,也支持 Windows 的 FAT 和 NTFS 文件系统 支持图形界面,可定制启动菜单和背景图片,支持鼠标 拥有丰富的终端命令,用户可以查看硬盘分区的细节,修改分区设置,临时重新映射磁盘顺序,从任何用户定义的配置文件启动 ...
操作系统初始化
参考: 中国科学院大学 2025年秋《高级操作系统教程》课件 计算机启动启动流程: 从上电到内核的第一行代码:BIOS -> bootload任务: 硬件初始化 (BIOS) 初始化 BIOS 检查 CPU 寄存器 检查 BIOS 代码的完整性 检查 DMA, timer, interrupt controller 检查系统内存 检查系统总线和外部设备 跳转到下一级 BIOS (如 VGA-BIOS ) 执行并返回 识别可以启动的设备(CD-ROM? USB? HDD?) 加载内核代码到内存 (bootloader) BIOS (Basic Input/Output System,基本输入输出系统)存放于 BIOS 芯片(ROM)中 三大任务: 初始化硬件 在计算机开机时对系统各组件进行检查 启动操作系统 加载引导程序(bootloader)或操作系统 提供硬件的软件抽象 向操作系统提供系统配置信息 向操作系统提供硬件访问接口,向操作系统隐藏硬件的变化 现代操作系统会忽略 BIOS 提供的抽象层并直接访问硬件 BIOS 中的主...
操作系统:Interupt, Exception, Syscall
参考: 中国科学院大学 2025年秋《高级操作系统教程》课件 中断 Interrupt中断控制器不同 ISA 采用的中断控制器不同: x86: ARM: RISC-V: PLIC(Platform-level Interrupt Controller) 中断控制器需要考虑的问题: 如何指定不同中断的优先级 低优先级中断处理中,出现了高优先级的中断 嵌套中断 中断交给谁处理 如何与软件协同 中断控制器的主要功能:将中断分发给不同的核(对称或非对称)进行处理 分发:管理所有中断、 决定优先级、路由 CPU接口:给每个CPU核有对应的接口 中断处理 中断处理没有进程上下文 中断(和异常相比)和具体的某条指令无关 和中断时正在跑的进程、用户程序无关 中断处理程序不能睡眠 不能调用schedule()调度 不能释放信号或调用可能睡眠的操作 不能和用户地址空间交换数据 Linux 中断处理 在中断处理中做尽量少的事 推迟非关键行为 结构:Top half & Bottom half Top half: 做最少的工作后返回 Bottom half:推迟处...
OOO CPU Issue Stage: Issue Queue
发射队列 (Issue Queue) / 保留站 (Reservation Station) J. Abella, R. Canal, and A. González. Power- and Complexity-Aware Issue Queue Designs. IEEE Micro, 23(5):50–58, September–October 2003. doi:10.1109/MM.2003.1240212 任务:保存已被重命名但未被送到功能单元执行的指令 集中式 (Centralized) or 分布式 (Distributed)实例: reservation stations IBM Power6H.Q. Le, W.J. Starke, J.S. Fields, F.P. O’Connell, D.Q. Nguyen, B.J. Ronchetti, W.M. Sauer, E.M. Schwarz, and M.T. Vaden. IBM POWER6 Microarchitecture. IBM Journal of Research...
OOO CPU Issue Stage: Wake Up
任务:将功能单元计算出的结果通知到发射队列当中所有等待该数据的指令 Tomasulo 算法唤醒当指令执行完之后才将相关指令进行唤醒。 back-to-back 背靠背执行唤醒对于单周期指令 被仲裁电路选中的指令将其目的寄存器编号发送的对应的总线上广播 (tag bus) 发射队列当中的所有指令将 tag bus 上的编号和自己的源寄存器编号对比,如匹配则标记为 ready 通过旁路网络获得寄存器值(这样才能背靠背执行) 发射队列当中的指令如果源操作数均 ready ,则可以向仲裁电路发出请求 一条指令可以轮流向多个仲裁电路发送请求,直到找到愿意响应的仲裁电路(平衡负载) 仲裁电路对所有发送请求的指令进行仲裁选择发射 未发射的指令需要在下个 cycle 继续发送请求 发射的指令会收到仲裁电路的响应信号,并将其目的寄存器编号广播(第 1 步)不会马上离开发射队列:对于访存指令而言可能出现访存违例 发射队列对单周期指令唤醒电路的影响: 如果使用多个小容量的发射队列(分布式) 由于总容量并不变,所以 tag bus 总体的复杂度不变(由于布局布线的问题,可能复杂度会上升)...
OOO CPU Issue Stage: Select/Arbiter
任务:从发射队列中选择出 n 个 ready 的指令送到功能单元中 最优目标: oldest-first 对于压缩式发射队列:仲裁电路实现简单,只需选择发射队列最下面的 n 个 entry 对于非压缩式发射队列:对于分布式发射队列:采用 1-of-M 仲裁每周期从发射队列的 M 个 entry 中选出 1 条指令送到功能单元 识别出发射队列中的哪些指令是 oldest 的? 需要指令的年龄信息:可以利用 ROB 的地址 ROB 本质是 FIFO ,存在读写指针翻转的问题 给 ROB 的每个 entry 增加一位位置位表明是否翻转 当位置位相同时, ROB 的地址值越小,对应的指令越旧 当位置位不同时, ROB 的地址值越大,对应的指令越旧 指令的年龄信息需要写入发射队列(即发射队列每个 entry 需要 Age field ) 屏蔽掉未 ready 的指令? 发射队列中每个 entry 增加一位 ready 位 仲裁电路根据 ready 位和年龄信息进行比较 如何比较年龄信息选出最 oldest 的指令? 多级比较电路:对于容量为 N 的发射队列,需要的比较电路级数...
OOO CPU Issue Stage: Allocation
任务:从发射队列中找出 n 个空闲的 entry 写入 (from 重命名之后的指令) 属于 Dispatch 阶段, Issue 阶段之前 对于压缩式发射队列分配电路实现简单:只需选择发射队列最上面的 n 个 entry 对于非压缩式发射队列方案一: 拆分并行查找 需要多级处理电路 延时: 正比于发射队列容量,每周期写入的指令数 方案二: free list 记录查找 借鉴 free list 使用 FIFO 记录发射队列中所有空闲 entry 的编号 实现有一定的复杂度和延时 方案三: 分段查找 把发射队列分成 m 个段,每个段内采用方案一或方案二进行查找 延时: 为一个段内的查找延时 适用于折中式/分布式发射队列:各个段之间本身互相独立, 段的划分可以同功能单元发射队列的划分一致 对于集中式发射队列,存在的问题:同一个段内的所有空闲 entry 只能找出一个,可能出现“一个段全空闲,其他段全不空闲”的情况
OOO CPU Issue Stage
InOrder Issue Logic 指令需要等待所有先前的指令都发射后才可以发射 实现简单:仅需要 scoreboarding a data dependence table: 每个 entry 代表一个寄存器是否 available a resource table: 追踪所有功能单元的状态 特殊的顺序处理器: VLIW processors Out-Of-Order Issue Logic 往往是处理器流水线的关键路径 发射阶段 (Issue Stage) 的任务:接收来自重命名之后的指令(顺序),乱序地送到功能单元去执行 主要电路: 发射队列 (Issue Queue) / 保留站 (Reservation Station) 分配 (Allocation) 电路 选择 (Select) 电路 / 仲裁 (Arbiter) 电路 唤醒 (Wake-up) 电路 流水线发射队列中的指令被仲裁电路选中执行的条件: 源操作数均已准备好 仲裁电路允许发射 可以从寄存器堆 / payload RAM / 旁路网络中获得源...