设备相关的数据结构以及根据逻辑设备名分配设备的具体流程
1. 设备控制表 (DCT)
字段名称 | 说明 | 典型内容/示例 |
---|---|---|
设备标识符 (Device ID/Name) | 唯一标识该设备的名称或编号。 | 打印机P1 , 磁盘D0 , 鼠标 |
设备类型 (Device Type) | 描述设备的类别。 | 字符设备 , 块设备 , 专用设备 , 共享设备 |
设备状态 (Device State) | 反映设备当前的可用性。 | 空闲 (Idle) , 忙碌 (Busy) , 脱机 (Offline) , 故障 (Faulty) |
设备特性表指针 | 指向一个包含设备详细技术参数的区域。 | 指向内存中存储设备速率、容量、寻道时间等信息的地址 |
设备等待队列头指针 | 指向等待使用该设备的进程请求队列的队首。 | 指向一个设备请求块 (DRB) 链表的头结点 |
占有设备进程ID | 如果设备当前忙碌,记录当前占用该设备的进程的PID。 | PID = 1234 |
缓冲区地址 | 对于某些设备,可能需要专属的I/O缓冲区地址。 | 0xABCDEF00 (缓冲区起始地址) |
COCT指针 | 指向其所属的设备控制器对应的控制器控制表 (COCT)。 | 指向内存中该控制器COCT的地址 |
2. 控制器控制表 (COCT)
字段名称 | 说明 | 典型内容/示例 |
---|---|---|
控制器标识符 (Controller ID) | 唯一标识该控制器的编号。 | 磁盘控制器C1 , 打印机控制器C2 |
控制器类型 (Controller Type) | 描述控制器的功能或所连接的设备类型。 | 磁盘控制器 , 网络控制器 , 通用I/O控制器 |
控制器状态 (Controller State) | 描述控制器自身的当前状态。 | 空闲 (Idle) , 忙碌 (Busy) , 故障 (Faulty) |
连接设备列表/DCT指针集合 | 包含一个列表或一组指针,指向所有连接到该控制器上的设备控制表 (DCT)。 | 包含 DCT_P1 , DCT_D0 , DCT_D1 等指针 |
当前处理I/O请求指针 | 指向控制器当前正在处理的I/O请求或对应的DCT。 | 指向当前正在进行I/O的设备的DCT地址 |
控制器中断向量 | 控制器完成I/O或发生错误时,向CPU发出的中断的地址。 | 中断向量号 32 |
CHCT指针 | 指向其所属的通道对应的通道控制表 (CHCT)。 | 指向内存中该通道CHCT的地址 |
3. 通道控制表 (CHCT)
字段名称 | 说明 | 典型内容/示例 |
---|---|---|
通道标识符 (Channel ID) | 唯一标识该I/O通道的编号。 | 通道0 , 通道1 |
通道类型 (Channel Type) | 区分通道的工作模式。 | 选择通道 (Selector Channel) , 多路复用通道 (Multiplexer Channel) |
通道状态 (Channel State) | 描述通道自身的当前状态。 | 空闲 (Idle) , 忙碌 (Busy) , 故障 (Faulty) |
通道程序地址 | 指向通道当前正在执行的通道程序(由一系列通道指令字CCW组成)的内存起始地址。 | 0x10002000 (通道程序起始地址) |
连接控制器列表/COCT指针集合 | 包含一个列表或一组指针,指向所有连接到该通道上的控制器控制表 (COCT)。 | 包含 COCT_C1 , COCT_C2 等指针 |
中断处理信息 | 包含通道完成或异常时生成中断的相关信息。 | 中断处理例程地址 , 通道状态字 |
数据计数器 | 记录当前I/O操作已传输的数据量。 | 1024 (已传输字节数) |
状态字 | 通道执行状态和错误信息的集合。 | 0x0000 (正常完成), 0x8001 (设备错误) |
4. 系统设备表 (SDT)
字段名称 | 说明 | 典型内容/示例 |
---|---|---|
设备列表/数组 | SDT通常以数组或链表的形式组织,存储系统中所有设备的条目。 | 一个由多个条目构成的数组或链表 |
指向DCT的指针集合 | 列表中每个条目都包含一个指向对应设备控制表 (DCT) 的指针。 | 包含 DCT_P1 的地址, DCT_D0 的地址, DCT_MOUSE 的地址等 |
设备ID到DCT指针的映射 | 支持通过设备ID作为索引或键来快速查找对应的DCT指针。 | 内部查找表或哈希表实现,例如 map["打印机P1"] = DCT_P1的地址 |
系统设备总数 | 记录当前系统中物理设备的数量。 | 5 (表示系统中有5个物理设备) |
依据逻辑设备名分配设备的具体例子
在这个例子中,我们假设一个用户进程 P1 需要使用一台打印机来打印文档,但它不关心具体是哪一台物理打印机。它只请求一个名为“我的打印机
”的逻辑设备。
场景设定:
-
进程 P1:需要打印一份文档,发出I/O请求,指定逻辑设备名为“
我的打印机
”。 -
系统配置:
-
系统中有两台物理打印机:打印机P1 和 打印机P2。
-
打印机P1 连接到 打印机控制器C2,而 控制器C2 连接到 通道CH0。
-
打印机P2 连接到 打印机控制器C3,而 控制器C3 也连接到 通道CH0。
-
系统中维护着一个逻辑设备表 (LDT),用于将逻辑设备名映射到物理设备名。
-
-
逻辑设备表 (LDT) 示例:
逻辑设备名 (Logical Device Name) | 物理设备名 (Physical Device Name) | 状态/备注 |
---|---|---|
我的打印机 |
打印机P1 |
优先分配,可轮换 |
我的打印机 |
打印机P2 |
备用,可轮换 |
文档扫描仪 |
扫描仪S1 |
唯一映射 |
-
初始系统状态(假设):
-
打印机P1 及其控制器C2、通道CH0都处于空闲状态。
-
打印机P2 及其控制器C3、通道CH0也处于空闲状态。
-
设备分配步骤详解及示例:
1. 解析逻辑设备名,查找逻辑设备表 (LDT) 确定物理设备名
-
进程P1的请求:进程P1执行
print("文档内容", "我的打印机")
这样的系统调用,将“我的打印机
”作为参数传递给操作系统。 -
操作系统操作:
-
操作系统接收到P1的请求,识别到逻辑设备名“
我的打印机
”。 -
它会立即查找内存中的逻辑设备表 (LDT)。
-
在LDT中,“
我的打印机
”映射到了**打印机P1
** 和打印机P2
。 -
操作系统会根据某种策略(例如,轮询、负载均衡、或简单的查找顺序),选择一个可用的物理设备。
-
示例:假设操作系统首先尝试分配**
打印机P1
。此时,操作系统已将逻辑设备名“我的打印机
”映射到了物理设备名“打印机P1
**”。
-
2. 查找系统设备表 (SDT) 定位设备控制表 (DCT)
-
操作系统操作:
-
获得物理设备名“
打印机P1
”后,操作系统会去查找系统设备表 (SDT)。 -
在SDT中,根据“
打印机P1
”这个物理设备名,找到对应的打印机P1的设备控制表 (DCT_P1) 的内存地址。
-
3. 判断设备状态并尝试分配设备(DCT操作)
-
操作系统操作:
-
操作系统访问 DCT_P1,检查其设备状态字段。
-
示例情况A:物理设备
打印机P1
空闲-
假设
DCT_P1.设备状态
当前为空闲
。 -
操作系统将
DCT_P1.设备状态
更新为忙碌
。 -
将
DCT_P1.占有设备进程ID
设置为P1
。 -
成功分配物理设备
打印机P1
给进程P1。
-
-
示例情况B:物理设备
打印机P1
忙碌 (回溯或尝试其他设备)-
如果
DCT_P1.设备状态
当前为忙碌
。 -
操作系统会回到步骤1,重新查找LDT,尝试分配映射到“
我的打印机
”的下一个物理设备,即打印机P2
。-
它会继续查找
打印机P2
对应的 DCT_P2,并重复步骤3的检查和分配流程。 -
如果所有映射的物理设备都忙碌:此时,进程P1的PCB(或DRB)会被添加到逻辑设备“
我的打印机
”对应的逻辑等待队列中(一个抽象的队列,可能由操作系统统一管理,或最终分散到实际物理设备的等待队列中,但此处逻辑上先等待逻辑设备空闲)。P1进入等待状态。
-
-
-
-
接续示例(假设
打印机P1
空闲,分配成功):-
操作系统已成功将物理设备
打印机P1
分配给进程P1。 -
接下来,操作系统会通过
DCT_P1
中存储的COCT指针
,找到并访问与打印机P1相连的打印机控制器C2的控制器控制表 (COCT_C2)。
-
4. 判断控制器状态并尝试分配控制器(COCT操作)
-
操作系统操作:
-
操作系统访问 COCT_C2,检查其控制器状态字段。
-
示例情况A:控制器C2空闲
-
假设
COCT_C2.控制器状态
当前为空闲
。 -
操作系统将
COCT_C2.控制器状态
更新为忙碌
。 -
成功分配控制器C2给进程P1。
-
-
示例情况B:控制器C2忙碌 (回溯)
-
如果
COCT_C2.控制器状态
当前为忙碌
。 -
由于控制器忙碌意味着当前尝试的物理设备(打印机P1)及其路径都不可用,操作系统会回溯到步骤1,再次通过LDT尝试分配“
我的打印机
”对应的下一个物理设备(打印机P2
)。 -
如果所有物理设备及其控制器都忙碌,进程P1将进入等待状态。
-
-
-
接续示例(假设控制器C2空闲,分配成功):
-
操作系统已成功将控制器C2分配给进程P1。
-
接下来,操作系统会通过
COCT_C2
中存储的CHCT指针
,找到并访问与控制器C2相连的通道CH0的通道控制表 (CHCT_CH0)。
-
5. 判断通道状态并尝试分配通道(CHCT操作)
-
操作系统操作:
-
操作系统访问 CHCT_CH0,检查其通道状态字段。
-
示例情况A:通道CH0空闲
-
假设
CHCT_CH0.通道状态
当前为空闲
。 -
操作系统将
CHCT_CH0.通道状态
更新为忙碌
。 -
成功分配通道CH0给进程P1。
-
-
示例情况B:通道CH0忙碌 (回溯)
-
如果
CHCT_CH0.通道状态
当前为忙碌
。 -
由于通道是整个I/O路径的“瓶颈”(所有通过此通道的设备都会受其影响),通道忙碌意味着当前尝试的物理设备(打印机P1)及其路径都不可用。操作系统会回溯到步骤1,再次通过LDT尝试分配“
我的打印机
”对应的下一个物理设备(打印机P2
)。 -
注意:在这个例子中,
打印机P1
和打印机P2
都连接到通道CH0
。如果CH0
忙碌,那么无论尝试P1
还是P2
,都会遇到通道忙碌的问题。在这种情况下,进程P1最终将进入等待状态,直到CH0
空闲。
-
-
分配成功与后续操作
在上述例子中,如果打印机P1 (或P2)、控制器C2 (或C3)、通道CH0 三者都成功分配给了进程P1,那么这次设备分配才算真正成功。
-
启动I/O操作:操作系统为进程P1的打印请求构建通道程序,并将通道程序的起始地址写入
CHCT_CH0.通道程序地址
字段,然后启动通道CH0。 -
数据传送:通道CH0独立执行,控制对应的控制器(C2或C3)驱动物理打印机(P1或P2)进行打印。
-
I/O完成与释放:打印任务完成后,通过中断通知操作系统。操作系统会依次将
CHCT_CH0.通道状态
、COCT_C2/C3.控制器状态
和DCT_P1/P2.设备状态
重新设置为空闲
。同时,检查各自的等待队列,唤醒任何在等待使用这些资源的进程。
这个例子强调了:
-
逻辑设备独立性:用户进程无需知道具体的物理设备名,提高了程序的通用性和可移植性。
-
灵活性:操作系统可以动态选择可用的物理设备,提高了设备利用率和系统吞吐量。
-
回溯机制:当尝试分配某个物理设备路径失败时(设备、控制器或通道忙碌),操作系统可以智能地尝试其他备用物理设备。