目录

  1. 架构

  2. CPU

  3. 内存管理

  4. 进程线程

  5. 文件系统

  6. 目录

  7. 1 CPU结构

    1. 1.1 CPU结构
    2. 1.2 CPU寻址
  8. 2 内存管理

    1. 2.1 内存申请
    2. 2.2 内存寻址
  9. 3 进程管理

    1. 3.1 进程结构
    2. 3.2 进程调度
      1. 一、中断和异常
      2. 二、中断处理
      3. 三、系统调用
    3. 3.2 进程通信
      1. 3.3 锁
  10. 4 文件管理

  11. 5 设备管理

1 CPU结构

1.1 CPU结构

os-1-cpu

1.2 CPU寻址

  • 5种寻址方式
    • 直接寻址 : [1]
    • 寄存器间接寻址 [bx]
    • 寄存器相对寻址 [bx + 1]
    • 基址变址寻址 [bx + si]
    • 相对基址变址寻址 [bx + si + 1]

2 内存管理

2.1 内存申请

  • libc内部free list
  • libc申请新逻辑页
    • 内核使用伙伴算法,分配物理页,插入页表

os-2-1-malloc

2.2 内存寻址

  • 逻辑地址
  • 线性地址
  • 物理地址os-2-2-mem_addr

3 进程管理

3.1 进程结构

os-3-1-process

3.2 进程调度

一、中断和异常

  • 进程状态转换
    • 中断
      • 时钟中断
      • IO中断
      • 硬件故障
    • 异常
      • 陷入:有意识安排,返回下一条指令:系统调用
      • 故障:可恢复错误,返回当前指令:缺页异常、段错误
      • 终止:不可恢复错误、算术溢出、除0、…

二、中断处理

  • 进程状态转换处理流程:
    • 中断:保存当前进度,处理中断,返回下一条指令
      1. cpu 取下一条指令
      2. cpu 执行指令
      3. cpu 执行一条指令后,扫描中断寄存器,查看是否有中断信号
      4. 如果有中断,中断硬件保存现场
      5. 中断硬件将触发器的内容送入PSW对应位置,查找中断向量表,调用中断处理程序
    • 异常:
      • 1.进入异常时:
        • 保存处理器状态
        • 准备高特权级执行环境
        • 选择并执行合适的异常处理代码
      • 2.处理异常时:
        • 获取异常信息(调用参数、原因等)
      • 3.结束异常时:
        • 恢复处理器状态
        • 返回低优先级
        • 继续执行流

三、系统调用

  • 系统调用:用户调用操作系统功能,包括进程管理、文件管理、设备管理等
  • 系统调用方式:c函数库封装系统调用,用户调用c函数库。每个系统调用都有系统调用号
  • 系统调用执行流程:
    1. 中断/异常机制:硬件保护现场,查找中断向量表,调用系统调用入口程序
    2. 系统调用入口程序:保存现场,参数压栈,查找系统调用表,调用系统调用例程或内核函数
    3. 执行系统调用例程
    4. 恢复线程,返回用户程序

3.2 进程通信

进程通信方式:

  1. 信号

    kill(pid_t pid, int signum) /* 发送 */
    signal(int signum, sig_handle_func()) /* 接收: 不阻塞,先恢复信号,再处理 */
    sigaction(int signum, ...) /* 接收:阻塞,先处理,再恢复信号 */
    
  2. 信号量

  • 2.1 无名信号量

    int sem_init(em_t *sem, int pshared, unsigned int value); /* 进程内,线程同步 */
    int sem_wait(sem_t *sem); /* 加锁 */
    int sem_post(sem_t *sem); /* 解锁 */
    
  • 2.2 有名信号量

    sem_t *sem_open(const char *name, int flag);
    
  1. 消息队列

    int msgget(key_t key, int msgflg); /* 创建 */
    int msgsnd(int msqid, const void *data, size_t datasz, int msgflag); /* 发送 */
    ssize_t msgrcv(int msqid, void *data, size_t datasz, long msgtype, int msgflag); /* 接收 */
    
  2. 管道

  • 4.1 无名管道

    int pipe(inf fd[2]); /* 创建:0读1写 */
    int write(int fd, void *data, size_t datasz); /* 发送 */
    int read(int fd, void *data, size_t datasz); /* 接收 */
    
  • 4.2 有名管道

    int mkfifo(const char *file, mode_t mode);  /* 创建 */
    
  1. 共享内存
  2. 套接字

3.3 锁

  • 线程锁
    • 自旋锁
    • 读写锁
  • 线程死锁
    • 预防
      • 避免互斥访问
      • 不允许持有并等待
      • 不允许资源抢占
      • 打破循环等待(按特定顺序获取资源)
    • 解决
      • 银行家算法
        • 获取资源需管理者同意
        • 管理者预演不会造成死锁

4 文件管理

os-4-1-filesys

  • 文件系统崩溃一致性
    • 一致性属性
      • 持久化
      • 原子性
      • 有序性
    • 一致性实现
      • 日志
        • 缺点:日志多次读写占用IO
        • 改进:批量写日志 + 检查点

5 设备管理

  • 分类
    • 字符设备:LED、键盘、串口
      • 顺序访问:内次读取一个字符
      • 通过驱动与设备交互
    • 块设备:内存、磁盘、u盘
      • 随机访问:以块粒度进行读写
      • 系统层增加缓冲区,避免与慢设备频繁交互
    • 网络设备:网卡
      • 面向格式化报文的收发
      • 驱动以上维护多种协议
  • 设备管理
    • 字符抽象:文件系统:open/read/write/close
    • 块抽象:文件系统、mmap
    • 网络抽象:socket、文件系统:sockent/send/recv/close
  • CPU与设备交互
    • 可编程IO:cpu的in/out load/store指令
      • 特点
        • 消耗CPU时钟周期 与 数据量成正比
        • 适合于小型设备
      • 分类
        • PIO (port IO)
          • IO设备具备独立的地址空间
          • 使用特殊指令 in/out
        • MMIO (Memory-mapped IO)
          • 将设备映射到连续物理内存中
          • 使用内存访问指令
            • 行为与内存不完全一样,读写有副作用
    • 直接内存访问 DMA:外设可直接访问总线
      • 特点

        • DMA与内存交互传输数据,无需CPU参与
        • 适合与高吞吐量IO
      • 结构

                          [CPU]
                            |
                        [高速缓存]
                            |
        ----+---------------+--------------+--------- 系统总线
            |                              |
        [DMA控制器]                      [内存]
            |
        ----+---------------------------------------- PCI总线
            |
          [外设]
        
      • 读取步骤

        • 1.CPU中驱动发出请求,将设备数据读取至内存地址x
        • 2.外设初始化DMA传递,将数据传送到数据DMA控制器
        • 3.DMA将数据传送至内存地址x
        • 4.DMA传输完成后,向CPU发出中断
        • 5.PU执行每条指令后,检查中断是否到来