xym-ee
  • 计算机与嵌入式开发学习
  • 1-1.编程基础
    • C 语言
      • C 中的数据
      • C 语言基础
      • 字符输入输出
      • 函数
      • 数组和指针
      • 字符串处理
      • 存储类别
      • 文件 I/O
      • 复杂数据类型
      • 位操作
      • 预处理和 C 库
    • 数据结构和算法入门
    • leetcode 刷算法题
      • 递归与栈
      • 二叉树与递归
      • 回溯问题
      • 动态规划 1
    • 基本工具和使用
      • shell
      • shell 脚本
      • vim 编辑器
      • 命令行数据整理
      • 命令行环境和配置
  • 1-2.计算机系统基础(CSAPP)
    • 1.计算机基础
    • 2.数据的表示
    • 3.加减运算
    • 4.乘除运算
    • 5.程序的表示转换和链接
    • 6.IA32指令
    • 7.过程调用
    • 10.程序的链接
  • 1-3.数字电路、计算机组成
    • 1.数字电路、virtual circuit board
    • 2.计算机组成/steam:Turing Complete
    • 3.微机原理与接口技术(8086)
  • 1-4.计算机网络
    • 1.从浏览器开始
    • 2.协议栈和网卡
    • 3.网络设备
    • 4.运营商、接入网
    • 5.服务器
    • 6.数据返回浏览器
    • socket编程
  • 1-5.操作系统
    • 0.绪论
      • 1.应用视角的操作系统
      • 2.硬件视角的操作系统
      • 3.数学视角的操作系统
      • 4.状态机模型的应用
    • 1.并发
      • 1.并发 bug 的解决思路
      • 2.互斥
      • 3.同步
      • 4.信号量
      • 5.真实并发
      • 6.调试技巧
      • 7.os kernel 实现
    • 2.虚拟化
      • 1.操作系统上的进程
      • 2.进程的地址空间
      • 3.系统调用和unix shell
      • 4.C 标准库的实现
      • 5.linux 操作系统
      • 6.可执行文件和加载
      • 7.动态链接和加载
      • 8.内核的实现
      • 9.fork 的应用
    • 3.持久化
      • 1.存储设备的原理
      • 2.输入输出设备模型
      • 3.设备驱动程序
      • 4.文件系统 API
      • 5.fat 和 unix 文件系统
      • 6.持久数据的可靠性
    • 总结
  • 2-1.嵌入式裸机开发
    • 嵌入式系统通信接口与协议
    • cortex-m 内核芯片裸机开发
    • MPU
  • 2-2.中等规模系统开发
    • LVGL 图形库
    • 裸机开发的软件框架
    • 基于 rtos 开发
  • 2-3.armv7-m架构与 rtos 原理
    • armv7-m 架构
    • rt-thread 内核实现
    • rt-thread 驱动开发
  • 3-1.linux 应用开发基础
  • 3-2.linux 镜像构建
    • uboot 使用
    • uboot 适配
    • uboot 启动分析
    • uboot 自定义命令
    • linux 内核适配
    • linux 内核启动分析
    • busybox 根文件系统构建
  • 3-3.linux 驱动开发
    • 驱动开发基础
    • sysfs
    • led 驱动
    • 设备树
    • pinctrl 和 gpio 子系统
    • 并发控制
由 GitBook 提供支持
在本页
  • Everything is a State Machine
  • 状态机:建模理解我们的世界

这有帮助吗?

  1. 1-5.操作系统
  2. 0.绪论

4.状态机模型的应用

虚拟化的最后两课,强化思想,看看状态机到底如何帮我们深入理解操作系统。

应用视角的操作系统。

在第二讲第一次接触状态机模型和 minimal.S 的时候,有同学会对 “为什么这么做” 感到困惑;但随着课程的深入,状态机不断帮助我们以原理性的思路去理解操作系统这个复杂、承载了计算机发展历史的概念。

从课程的角度讲,状态机对于理解是有好处的。但是到底还有什么应用呢?使得这门操作系统课如此强调状态机这个东西。这里再顺着状态机往前走一点点。

本讲内容:回顾操作系统对象、API 上是如何构建应用程序世界的:

  • 操作系统和应用程序的状态机模型

  • 状态机模型的应用

Everything is a State Machine

操作系统课的一个思路:一切都是状态机。

遇到的第一个状态机

#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:

启示:状态机是有初始状态的。程序是有初始状态的,代码是由指令组成的,不管是什么指令,对于底层机器来说,状态有内存和寄存器组成。每一次状态的迁移就是执行一条指令。指令有两类,一种是改变寄存器和内存状态的计算指令,还有一种是特别的 syscall 把状态机的执行交给操作系统的指令,操作系统可以帮装填机完成进程本身无法完成的事情如访问输入输出设备,获得时间等。

我们花了相当多的时间,把上面这段话展开来学习。其中也遇到了很多有意思的问题,如什么是初始状态。

对于 minimal.S 来说,指令载入内存,然后把起始地址放入 PC,这就能正常运行了。

更复杂的,比如静态链接的 ELF 用调试器 starti 调试第一条指令。动态链接的 ELF,有个 interpreter 来解析依赖库,可以用 ldd 命令查看。他们各自都描述了状态机初始状态的一部分,此外初始状态还有一部分是由 main 函数的参数 argc argv envp ,这几个参数是由 execve 系统调用传给进程的,这些都可以从手册上看到。ABI 手册上甚至规定了初始的栈上应该有什么,用这些规范告诉操作系统、libc、应用程序的实现者,只要遵循规范,自己写的程序就可以启动起来。

第2个状态机,非递归汉诺塔,C程序也是状态机,这个事情不显然。其状态是所有数据。C 的迁移,单步调试的每一步,只要能调试起来,就有个状态机模型。更进一步,能想清楚什么是函数调用。

我们把编程语言、编译器、计算机体系结构、二进制代码,全部连接起来了,连接的东西就是状态机。可以试着用状态机解释再 linux 里遇到的一切东西。

比如 linux 里的进程,我们可以看到内存里的各种东西 cat /proc/,我们可以对状态机做任何事情,状态机里所有的东西都是看得见摸得着的。

从应用的角度看操作系统,并不是那么困难。

第3个状态机,多线程程序,共享内存、独立堆栈的状态机。每一步可以任选一个线程往前走一步。多线程带来的新现象:状态的迁移变得不确定了,这带来了理解并发程序上的困难。

从简单的状态机,慢慢的建立起整个计算机系统的概念。从状态机出发,我们还可以理解系统调用。

系统调用:把一个外面的状态往状态机里送,或者改变状态机外部世界的状态。从这个角度,对操作系统另一种理解:操作系统是一个状态机的管理者。状态机瞬时状态的集合,提供 syscall 这样的状态迁移。这就是操作系统,操作系统是应用的容器,体现了操作系统虚拟化的属性。

应用发起 syscall ,不仅可以读写数据,还可以管理操作系统里的状态机,如 fork,execve,这就很容易理解了。在状态机的视角下,fork 一句话就讲清楚了:所以内存和寄存器的原样复制。

到这里,从应用视角的角度已经可以比较好的理解什么是操作系统了。

我们严格的知道了什么是程序,什么是系统调用,原则上只需要去看手册,就可以完整的写成想要实现的任何程序。

学完操作系统,在编程的方面就可以毕业了,这个世界上别人能实现出来的程序,我们都有办法实现了。当然,工程量如果太大,可能没时间,但是功能全部都是可以实现的了的。

比如,想要实现一个即时的编译器,,动态生成一段可以执行的代码,解释执行的模拟器性能会稍微差一点,有没有可能像编译器一样,把执行的指令,编译成本地的x86指令,不要像解释器一样,解释执行。

编译器做的事情是输入一段文本,转化一下,输出成另一段文本。当然实现起来,还是会有很多困难。总的来说,目前已经掌握了足够多的工具,游戏修改器,java虚拟机。

状态机:建模理解我们的世界

上一页3.数学视角的操作系统下一页1.并发

最后更新于11个月前

这有帮助吗?