jyy OS NOTES

Lecture 01 操作系统概述

什么是操作系统

  • 让运行程序变得easy,program之间共享memory,enable I/O,etc.
  • 对单一计算机硬件系统作出抽象、支撑程序执行的软件系统(狭义)
    • 计算机(硬件)
    • 程序(软件)
    • 操作系统(管理软件的软件)

理解操作系统

  • 操作系统服务谁?

    程序 = 状态机
    课程涉及:多线程Linux应用系统

  • 操作系统为程序提供什么服务?

    操作系统= 对象 + API
    课程涉及:POSIX + 部分Linux特性

  • 如何实现操作系统提供的服务?

    操作系统 = C程序

    • 完成初始化后成为 interrupt/trap/fault handler

    课程涉及:xv6,自制迷你操作系统

Lecture 02 操作系统上的程序

状态机

  • 数字电路

    • 状态 = 寄存器保存的值 (flip-flop)
    • 初始状态 = RESET
    • 迁移 = 组合逻辑电路计算寄存器下一周期的值
    #define REGS_FOREACH(_)  _(X) _(Y)
    #define RUN_LOGIC        X1 = !X && Y; \
                            Y1 = !X && !Y;
    #define DEFINE(X)        static int X, X##1;
    #define UPDATE(X)        X = X##1;
    #define PRINT(X)         printf(#X " = %d; ", X);
    
    int main() {
      REGS_FOREACH(DEFINE);
      while (1) { // clock
        RUN_LOGIC;
        REGS_FOREACH(PRINT);
        REGS_FOREACH(UPDATE);
        putchar('\n'); sleep(1);
      }
    }
  • 程序也是状态机

    • 状态 = 堆 + 栈
    • 初始状态 = main的第一条语句
    • 迁移 = 执行一条简单语句
  • 非递归hanoi,手动模拟栈帧

    typedef struct {
      int pc, n;
      char from, to, via;
    } Frame;
    
    #define call(...) ({ *(++top) = (Frame) { .pc = 0, __VA_ARGS__ }; })
    #define ret() ({ top--; })
    #define goto(loc) ({ f->pc = (loc) - 1; })
    
    void hanoi(int n, char from, char to, char via) {
      Frame stk[64], *top = stk - 1;
      call(n, from, to, via);
      for (Frame *f; (f = top) >= stk; f->pc++) {
        switch (f->pc){
          case 0: if (f->n ==1) {printf("%c -> %c \n", f->from, f->to); goto(4);} break;
          case 1: call(f->n - 1, f->from, f->via, f->to); break;
          case 2: call(       1, f->from, f->to, f->via); break;
          case 3: call(f->n - 1, f->via, f->to, f->from); break;
          case 4: ret();
          default: assert(0);
        }
      }
    }
  • 二进制程序

    • 状态 = 内存M + 寄存器R
    • 初始状态 =
    • 迁移 = 执行一条指令

程序的本质

  • 计算
  • 调用操作系统 syscall
    • 把 (M,R)完全交给操作系统,任其修改
    • 实现操作系统中的其他对象交互

操作系统中的一般程序

操作系统收编了所有的硬件/软件资源

  • 只能使用操作系统调用的方式访问操作系统中的对象
  • 这是为“管理多个状态机”必须的

系统中常见的应用程序

  • Core Utilities

    • standard programs for text and file manipulation
    • GNU Coreutils
  • 系统/工具程序

    • bash,binutils,apt,ip,ssh,vim,tmux,jdk,python,...
    • Ubuntu Packages
  • 其他各种应用程序

  • 二进制程序状态机的初始状态是什么?

    • main()之前发生了什么
      • ld-linux-x86-64.so加载了libc
      • 之后libc完成了自己的初始化
    • strace 看到程序执行的系统调用
    strace -f gcc a.c
    strace ./a.out

程序运行

程序 = 状态机 = 计算 -> syscall -> 计算 ->

  • 被操作系统加载
    • 通过另一个进程执行execve设置为初始状态
  • 状态机执行
    • 进程管理: fork,execve,exit,...
    • 文件/设备管理: open,close,read,write,...
    • 储存管理: mmap,brk,...
  • 直到_exit(exit_group)推出

Summary

  • 程序 = 状态机
    • 源代码S:状态迁移 = 执行语句
    • 二进制代码C: 状态迁移 = 执行指令
    • 编译器C = compile(S)
  • 应用视角操作系统
    • 就是一条syscall指令
  • 计算机系统不存在玄学;一切都建立在确定的机制上
    • 理解操作系统的重要工具v: gcc,binutils,gdb,strace

Lecture03 多处理器编程

并发程序的状态

  • existing, happening, or done at the same time. Different parts or units of a program, algorithm, or problem to be executed out-of-order or in partial order, without affecting the final outcome. (系统调用是最早的并发程序)

并发程序的基本单位: 线程

  • 共享内存的多个执行流
    • 执行流拥有独立的栈帧链(局部状态)
    • 共享全部的内存(共享内容/全局变量)

线程库 thread.h

多线程带来的麻烦