5.1-操作系统的状态机模型

2023-11-13

复习

  • 并发……就这么……讲完了……
    • 理解的方式:“玩一玩” 示例代码

本次课回答的问题

  • Q: 听说操作系统也是程序。那到底是鸡生蛋还是蛋生鸡?

本次课主要内容

  • 软件和硬件的桥梁
  • 操作系统的加载和初始化
  • AbstractMachine 代码导读

一、自己动手写操作系统

时事热评

小学生写了三个月的操作系统是什么样的?

  • 看到 i386 就知道了嘛
img

本学期的 OSLabs

热身实验

  • Lab0 (amgame): 熟悉代码框架

正经实验

  • Lab1 (pmm): Physical memory management
    • 多处理器 (bare-metal) 上的 kalloc/free
  • Lab2 (kmt): Kernel multi-threading
    • 中断和异常驱动的上下文 (线程) 切换
  • Lab3 (uproc): User processes
    • 虚拟地址空间、用户态进程和系统调用
  • Lab4 (vfs): Virtual file system
    • devfs, procfs, 简单的文件系统;ELF 加载器
img

实现操作系统:到底有多难?

心路历程

  • 曾经的我:哇!这也可以?
  • 现在的我:哦。呵呵呵。

img韩寒:“被小学生支配的恐惧,而我也曾对那种力量,一无所知。”

  • 「护球像梅西,射门像贝利」的金山区齐达内,满怀期待地去和儿童预备队比赛,结果被灌了 20 多球。

Bill Gates: 我选择退学。

大学的真正意义

将已有的知识和方法重新消化,为大家建立好 “台阶”,在有限的时间里迅速赶上数十年来建立起的学科体系。

今天的学术界可比 Bill Gates 的时代卷多了

  • 学术界基本没啥是需要一个毛头小伙子来教的

例子:破除 “写操作系统很难”、“写操作系统很牛” 的错误认识

  • 操作系统真的就是个 C 程序
  • 你只是需要 “被正确告知” 一些额外的知识
    • 然后写代码、吃苦头
    • 从而建立正确的 “专业世界观”

例子

“专业世界观” 的例子 (这些都没啥,paper 都发不了)

  • 写 x86 模拟器的时候,不知道哪条指令错了,怎么办?

    • 做操作系统实验的时候,如果遇到神秘 CPU Reset,怎么办?
  • 做实验做不下去的时候,该实现什么工具?


“专业世界观” 的学习方法

  • 经典研究论文 (OSDI, SOSP, ATC, EuroSys, …)
  • 久经考验的经典教学材料 (xv6, OSTEP, CSAPP, …)
  • 海量的开源工具 (GNU 系列, qemu, gdb, …)
  • 第三方资料,慎用 (tutorials, osdev wiki, …)

二、硬件和软件的桥梁

C 程序

我们已经知道如何写一个 “最小” 的 C 程序了:

  • minimal.S
  • 不需要链接任何库,就能在操作系统上运行
#include <sys/syscall.h>

.globl _start
_start:
  movq $SYS_write, %rax   // write(
  movq $1,         %rdi   //   fd=1,
  movq $st,        %rsi   //   buf=st,
  movq $(ed - st), %rdx   //   count=ed-st
  syscall                 // );

  movq $SYS_exit,  %rax   // exit(
  movq $1,         %rdi   //   status=1
  syscall                 // );

st:
  .ascii "\033[01;31mHello, OS World\033[0m\n"
ed:
# 编译链接
gcc -c minimal.S && ld minimal.o && file a.out
# a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

# 查看汇编代码
objdump -d a.out | less 

a.out:     文件格式 elf64-x86-64
Disassembly of section .text:
0000000000401000 <_start>:
  401000:       48 c7 c0 01 00 00 00    mov    $0x1,%rax
  401007:       48 c7 c7 01 00 00 00    mov    $0x1,%rdi
  40100e:       48 c7 c6 2e 10 40 00    mov    $0x40102e,%rsi
  401015:       48 c7 c2 1c 00 00 00    mov    $0x1c,%rdx
  40101c:       0f 05                   syscall 
  40101e:       48 c7 c0 3c 00 00 00    mov    $0x3c,%rax
  401025:       48 c7 c7 01 00 00 00    mov    $0x1,%rdi
  40102c:       0f 05                   syscall 

# gdb调试
gdb a.out 
starti
layout src
layout asm
si

[Inferiprocess 28230 In: _startted with code 01]                          L??   PC: 0x40101c
0x0000000000401000 in _start ()
0x0000000000401007 in _start ()
0x000000000040100e in _start ()
0x0000000000401015 in _start ()
0x000000000040101c in _start ()
Hello, OS World
0x000000000040101e in _start ()
0x0000000000401025 in _start ()
0x000000000040102c in _start ()
[Inferior 1 (process 27863) exited with code 01]

“程序 = 状态机” 没问题

  • 带来更多的疑问
    • 但谁创建的这个状态机???
      • 当然是操作系统了……呃……
    • 这个程序可以在没有操作系统的硬件上运行吗?
      • “启动” 状态机是由 “加载器” 完成的
      • 加载器也是一段程序 (状态机)
      • 这个程序由是由谁加载的?

Bare-metal 与程序员的约定

为了让计算机能运行任何我们的程序,一定存在软件/硬件的约定

  • CPU reset 后,处理器处于某个确定的状态
    • PC 指针一般指向一段 memory-mapped ROM
      • ROM 存储了厂商提供的 firmware (固件)
    • 处理器的大部分特性处于关闭状态
      • 缓存、虚拟存储、……
  • Firmware (固件,厂商提供的代码)
    • 将用户数据加载到内存
      • 例如存储介质上的第二级 loader (加载器)
      • 或者直接加载操作系统 (嵌入式系统)

x86 Family: CPU Reset 行为

CPU Reset (Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A/3B)

  • 寄存器会有初始状态

    • EIP = 0x0000fff0

    •   CR0 = 0x60000010
      
      • 16-bit 模式
    •   EFLAGS = 0x00000002
      
      • interrupt disabled
  • TFM (5,000 页 by 2019)

    • 最需要的 Volume 3A 只有 468 页

CPU Reset 之后:发生了什么?

《计算机系统基础》:不仅是程序,整个计算机系统也是一个状态机

  • 从 PC (CS:IP) 指针处取指令、译码、执行……
  • 从 firmware 开始执行
    • ffff0 通常是一条向 firmware 跳转的 jmp 指令

img

Firmware: BIOS vs. UEFI

  • 都是主板/主板上外插设备的软件抽象
    • 支持系统管理程序运行
  • Legacy BIOS (Basic I/O System)
  • UEFI (Unified Extensible Firmware Interface)

Legacy BIOS: 约定

Firmware 必须提供机制,将用户数据载入内存

  • Legacy BIOS 把第一个可引导设备的第一个扇区加载到物理内存的 7c00 位置
    • 此时处理器处于 16-bit 模式
    • 规定 CS:IP = 0x7c00, (R[CS] << 4) | R[IP] == 0x7c00
      • 可能性1:CS = 0x07c0, IP = 0
      • 可能性2:CS = 0, IP = 0x7c00
    • 其他没有任何约束

能不能看一下代码?

Talk is cheap. Show me the code. ——Linus Torvalds

有没有可能我们真的去看从 CPU Reset 以后每一条指令的执行?

计算机系统公理:你想到的就一定有人做到。

  • 模拟方案:QEMU
  • 真机方案:JTAG (Joint Test Action Group) debugger
    • 一系列 (物理) 调试寄存器,可以实现 gdb 接口 (!!!)

调试 QEMU: 确认 Firmware 的行为

亲眼确认 Firmware 到底是不是会加载启动盘第一个扇区到 0x7c00 内存位置!

调试 QEMU 模拟器

  • 查看 CPU Reset 后的寄存器
    • info registers
  • 查看 0x7c00 内存的加载
    • watch *0x7c00 - 《计算机系统基础》的良苦用心
    • 查看当前指令 x/i ($cs * 16 + $rip)
    • 打印内存 x/16xb 0x7c00
  • 进入 0x7c00 代码的执行
    • b *0x7c00, c (撒花!我们一会再回来)

鸡和蛋的问题解决

有个原始的鸡:Firmware

  • 代码直接存在于硬件里
  • CPU Reset 后 Firmware 会执行
    • 加载 512 字节到内存 (Legacy Boot)
    • 然后功成身退

Firmware 的另一用处

  • 放置一些 “绝对安全的代码”
    • BIOS 中断 (Hello World 是如何被打印的)
    • ARM Trusted Firmware
      • Boot-Level 1, 2, 3.1, 3.2, 3.3
      • U-Boot: the universal boot loader

小插曲:Firmware 的病毒 (1998)

Firmware 通常是只读的 (当然……)

  • Intel 430TX (Pentium) 芯片组允许

    写入 Flash ROM

    • 只要向 Flash BIOS 写入特定序列,Flash ROM 就变为可写
      • 留给 firmware 更新的通道
    • 要得到这个序列其实并不困难
      • 似乎文档里就有
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

5.1-操作系统的状态机模型 的相关文章

  • Java 中等效的并行扩展

    我在 Net 开发中使用并行扩展有一些经验 但我正在考虑在 Java 中做一些工作 这些工作将受益于易于使用的并行库 JVM 是否提供任何与并行扩展类似的工具 您应该熟悉java util concurrent http java sun
  • java.lang.NoClassDefFoundError:org.apache.batik.dom.svg.SVGDOMImplementation

    我在链接到我的 Android LibGDX 项目的 Apache Batik 库时遇到了奇怪的问题 但让我们从头开始 在 IntelliJ Idea 中我有一个项目 其中包含三个模块 Main Android 和 Desktop 我强调的
  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • 如何使用 Java 和 Selenium WebDriver 在 C 目录中创建文件夹并需要将屏幕截图保存在该目录中?

    目前正在与硒网络驱动程序和代码Java 我有一种情况 我需要在 C 目录中创建一个文件夹 并在该文件夹中创建我通过 selenium Web 驱动程序代码拍摄的屏幕截图 它需要存储在带有时间戳的文件夹中 如果我每天按计划运行脚本 所有屏幕截
  • 如何默认将 Maven 插件附加到阶段?

    我有一个 Maven 插件应该在编译阶段运行 所以在项目中consumes我的插件 我必须做这样的事情
  • Java中反射是如何实现的?

    Java 7 语言规范很早就指出 本规范没有详细描述反射 我只是想知道 反射在Java中是如何实现的 我不是问它是如何使用的 我知道可能没有我正在寻找的具体答案 但任何信息将不胜感激 我在 Stackoverflow 上发现了这个 关于 C
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • 无法捆绑适用于 Mac 的 Java 应用程序 1.8

    我正在尝试将我的 Java 应用程序导出到 Mac 该应用程序基于编译器合规级别 1 7 我尝试了不同的方法来捆绑应用程序 1 日食 我可以用来在 Eclipse 上导出的最新 JVM 版本是 1 6 2 马文 看来Maven上也存在同样的
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 如何在桌面浏览器上使用 webdriver 移动网络

    我正在使用 selenium webdriver 进行 AUT 被测应用程序 的功能测试自动化 AUT 是响应式网络 我几乎完成了桌面浏览器的不同测试用例 现在 相同的测试用例也适用于移动浏览器 因为可以从移动浏览器访问 AUT 由于它是响
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will

随机推荐

  • windows中将sqlmap添加到环境变量中

    在windows下每次使用sqlmap进行sql注入测试时 都要先进到sqlmap py的目录中 然后执行python sqlmap py url 而作为未来的渗透大佬 怎么能够允许这么low的事情出现 1 添加环境变量 电脑右键属性 高级
  • 【读书笔记】周志华 机器学习 第六章 支持向量机

    第六章 支持向量机 1 间隔和支持向量 2 核函数 3 软间隔和正则化 4 参考文献 1 间隔和支持向量 对上图所示的数据集 有多个超平面可以划分 直观上来说 最中间加粗的那个超平面是最好的 因为离两类数据都比较远 离两类数据都比较远 的好
  • 2020-01-03

    注册 登陆 当进入一个网站时首先进行注册 注册时会提示输入手机号 利用阿里大鱼接口发送一条短信验证码到当前号码并将短信验证码保存到redis 注册时会提示输入邮箱账号 当点击注册时会给当前邮箱发送一条激活码给用户激活 注册成功后会跳转到登陆
  • Netty4之编解码

    本文是基于Netty4 1 x 一般在使用Netty作为网络框架进行开发时 编解码框架是我们应该注意的一个重要部分 应用从网络层接收数据需要经过解码 Decode 将二进制的数据报转换从应用层的协议消息 这样才能被应用逻辑所识别 同样 客户
  • html标题、段落、换行与字符实体

    html标题 通过 h1 h2 h3 h4 h5 h6 标签可以在网页上定义6种级别的标题 6种级别的标题表示文档的6级目录层级关系 比如说 h1 用作主标题 最重要的 其后是 h2 次重要的 再其次是 h3 以此类推 搜索引擎会使用标题将
  • 虚拟数字人类型的形象分为四种

    虚拟人应用类型 虚拟人根据应用场景分为四种 1 虚拟偶像 打造粉丝经济 受到品牌青睐 爱奇艺今年以虚拟偶像新艺打的综艺 跨次元新星 B站推出的跨人团体VirtuaRealReal参加上海时装周 将虚拟与现实连接 拓展多元化应用场景 创造更多
  • UE4官方文档链接记录

    创建并使用自定义高度图和图层 https docs unrealengine com latest CHN Engine Landscape Custom index html 点击打开链接 自发光材质照亮场景 https docs unr
  • 基于 React 和 Redux 开发一个任务管理应用,支持添加任务、编辑任务、完成任务和删除任务等功能

    以下是一个基于 React 和 Redux 的任务管理应用的简单实现 支持添加任务 编辑任务 完成任务和删除任务等功能 javascript import React useState from react import createSto
  • 数字信号处理2-截止频率

    截止频率 2013 10 07 23 50 04 转载 在物理学和电机工程学中 一个系统的输出信号的能量通常随输入信号的频率发生变化 频率响应 截止频率 英语 Cutoff frequency 1 是指一个系统的输出信号能量开始大幅下降 在
  • 学习python爬虫看一篇就足够了之爬取《太平洋汽车》论坛及点评实战爬虫大全

    前言 这也是一篇毕业论文的数据爬虫 我第一次看见 太平洋汽车 的点评信息时 检查它的网页元素 发现并没有像 汽车之家 那样的字体反爬技术 所以就初步判断它没有很强的反爬虫技术 大不了就使用selenium库自动化实现爬虫呗 但是我确因为这样
  • 电脑如何查看及开启虚拟化

    什么是虚拟化 Intel Virtualization Technology就是以前众所周知的 Vanderpool 技术 简称VT 中文译为虚拟化技术 这种技术可以让一个CPU工作起来就像多个CPU并行运行 从而使得在一部电脑内同时运行多
  • 华为OD机试 - 最小循环子数组(Python)

    题目描述 给定一个由若干整数组成的数组nums 请检查数组是否是由某个子数组重复循环拼接而成 请输出这个最小的子数组 输入描述 第一行输入数组中元素个数n 1 n 100000 第二行输入数组的数字序列nums 以空格分割 0 nums i
  • Rsa 加密和解密

  • java 锁 Lock接口详解

    一 java util concurrent locks包下常用的类与接口 lock是jdk 1 5后新增的 1 Lock和ReadWriteLock是两大锁的根接口 Lock代表实现类是ReentrantLock 可重入锁 ReadWri
  • python数组处理方法

    一 数组对象的属性 数组的大小 元素个数 array size 数组的维度 array ndim 数组元素的数据类型 array dtype 数组的形状 array shape 数组中每个元素占用的内存空间 array itemsize 数
  • 模拟电路设计(31)---功率放大器简介

    在电子设备中 放大器的末级通常要带动一定的负载 例如 使扬声器发出洪亮的声音 推动电动机旋转 将微弱的无线电信号发射出去等 为了达到以上要求 末级电路不但要求能输出较大幅度的电压 同时还要求输出较大幅度的电流 即要求放大器能向负载输出足够大
  • tensorflow2.0手势识别出错记录

    1 TypeError len is not well defined for symbolic Tensors packed 2 0 Please call x shape rather than len x for shape info
  • css的浮动及高度塌陷

    一 高度塌陷 一般情况 我们的父元素是不设置高度的 让其被内容自动撑开 如果子元素设置浮动了 子元素会脱离文档流 就不能再撑开父元素的高度 从而导致父元素的高度丢失 导致页面布局的混乱 这就是高度塌陷问题 这个问题也必须要解决 解决高度塌陷
  • 小贷、p2p项目上线的基本流程

    一套成熟的流程 我可以简单地介绍一下 目前在服务项目筛选阶段 我们是有多个部门来协同完成的 相关理财服务项目设计部门会把接收和遴选后的各类型投资服务进行初选 我们财富风险管理部是对初选后的服务项目进行第二次筛选 再由公司核心管理层组成的风险
  • 5.1-操作系统的状态机模型

    复习 并发 就这么 讲完了 理解的方式 玩一玩 示例代码 本次课回答的问题 Q 听说操作系统也是程序 那到底是鸡生蛋还是蛋生鸡 本次课主要内容 软件和硬件的桥梁 操作系统的加载和初始化 AbstractMachine 代码导读 一 自己动手