字符设备管理 - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki

Table of Contents

字符设备缓存管理

数据结构

自由字符缓存队列

  • 管理空闲的字符缓存

  • 释放字符缓存时,被释放的缓存插入队首
  • 分配字符还粗时,从队首开始分配

I/O字符缓存队列

  • 为 I/O 管理缓存池

  • 输出时取位于队首的字符
  • 输入时将字符输入到队尾

struct tty 结构

  • 用于描述 字符设备(作为终端)
  • 参看 struct tty
  • 使用3个I/O字符缓存队列
    • t_rawq : 原始输入队列
    • t_canq : 非原始输入队列(去除了特殊字符)
      • 特殊字符包括 : "擦除"字符 和 "删除行"字符
    • t_outq : 输出队列

缓存池的改造

  • unix在识别队首缓存中的字符是否全部被用完时采用的方法:
    • 首先使每个字符缓存起始地址的最地三位皆为0(即8的整数倍)
    • 从某一字符缓存中取用一个字符后,c-cf +1 ,此时若发现其低三位为0,说明该块已经被用完,向某一字符缓存送字符时也使用类似操作
  • 由于缓存池的定义说明(见tty.c的 8146行)无法保证字符缓存的起始地址为8的整数倍,故需要对cfree[NCLIST]进行斩头去尾
    • 斩头:即以从cfree[0]开始的第一个地址最低三位皆为0的单元开始形成第一个字符缓存...
    • 去尾:对于最后一个缓存,必须保证其尾部不能超越cfree[NCLIST-1]的尾部
    • 关于斩头去尾的具体操作是在cinit的第8240行实现的
  • 只有当cfree[0]的起始地址恰好为8的整数倍,缓存池无需改造时,缓存池才会包含100个字符缓存(NCLIST值为100),否则改造后的缓存池只能包含99个字符缓存,造成了一定的空间浪费

设备寄存器

  • 每个字符设备 有4个寄存器
    • 接收器状态寄存器
    • 接收器数据缓存寄存器
    • 发送器状态寄存器
    • 发送器数据缓存寄存器

接收器状态寄存器

  • 第0位 : 接收器使能位
  • 第1位 : 数据终端准备就绪位
  • 第6位 : 接收器中断允许位
  • 第7位 : 接收器完成位

接收器数据缓存寄存器

  • 第7-0位 : 接收到的字符
  • 第15位 : 出错位

发送器状态寄存器

  • 第6位 : 发送器中断允许位
  • 第7位 : 发送器发送器准备就绪位

发送器数据缓存寄存器

  • 第7-0位 : 发送的数据

设备驱动函数

内存映射文件

参考

  • 详细说明请参看 参考文献 之 UNIX操作系统教程
⚠️ **GitHub.com Fallback** ⚠️