上海网站开发设计培训,山西建设厅报名网站,广告设计怎么做,设置网站域名解析和网站主机绑定(2021) 23 [持久化] I/O设备与驱动
南京大学操作系统课蒋炎岩老师网络课程笔记。 视频#xff1a;https://www.bilibili.com/video/BV1HN41197Ko?p23 讲义#xff1a;http://jyywiki.cn/OS/2021/slides/13.slides#/ 背景
很多人 (你们的同学们、家长们) 都有一个认识…(2021) 23 [持久化] I/O设备与驱动
南京大学操作系统课蒋炎岩老师网络课程笔记。 视频https://www.bilibili.com/video/BV1HN41197Ko?p23 讲义http://jyywiki.cn/OS/2021/slides/13.slides#/ 背景
很多人 (你们的同学们、家长们) 都有一个认识“计算机系就是装 (修) 电脑的”因为大家对电脑的印象只有 I/O 设备。但上了计算机系发现根本不是这么回事啊根本没有直接教怎么 “修电脑”。
但不应该是这样的
学 “计算机” 的人不仅会修电脑还会造电脑
只要我们有一个设备的手册或者文档等充足的信息就可以结合自己在操作系统等课程上的知识来查找并修复问题。
本次课的内容和目标
理解 “I/O 设备是什么”
键盘磁盘中断控制器总线DMAGPU
学习 I/O 设备在操作系统中的抽象
设备 可以读、写、控制的对象“设备驱动程序”
常见 I/O 设备
孤独的CPU
CPU 只是 “无情的指令执行机器”不断地从内存上进行取指令、译码、执行。
我们是通过各种各样IO设备实现与CPU的交互的。
CPU眼中的IO设备
I/O 设备是一个能与 CPU 交换数据的接口 通俗来讲
就是 “几组线” 每一组线有约定的功能 (RTFM)CPU 通过握手信号从线上读出/写入数据 每一组线有自己的地址 CPU 可以直接使用指令 (in/out/MMIO) 和设备交换数据
在CPU看来与常见的IO设备的交互就是按照特定的规则RTFM来读写一组寄存器。比如下面介绍的键盘控制器和磁盘控制器。
键盘控制器
IBM PC/AT 8042 PS/2 (Keyboard) Controller
“硬编码” 到两个 I/O port: 0x60 (data), 0x64 (status/command)
Command ByteUse说明0xEDLED 灯控ScrollLock/NumLock/CapsLock0xF3设置重复速度30Hz - 2Hz; Delay: 250 - 1000ms0xF4/0xF5打开/关闭N/A0xFE重新发送N/A0xFFRESETN/A
参考 AbstractMachine 的键盘部分实现
磁盘控制器
ATA (Advanced Technology Attachment)
IDE (Integrated Drive Electronics) 接口磁盘 primary: 0x1f0 - 0x1f7; secondary: 0x170 - 0x177
void readsect(void *dst, int sect) {waitdisk();out_byte(0x1f2, 1); // sector count (1)out_byte(0x1f3, sect); // sectorout_byte(0x1f4, sect 8); // cylinder (low)out_byte(0x1f5, sect 16); // cylinder (high)out_byte(0x1f6, (sect 24) | 0xe0); // driveout_byte(0x1f7, 0x20); // command (write)waitdisk();for (int i 0; i SECTSIZE / 4; i )((uint32_t *)dst)[i] in_long(0x1f0); // data
}总之以上这些IO设备在CPU看来就是按照特定的规则RTFM来读写一组寄存器。
特殊的IO设备
中断控制器
我们的设备中通常有许多IO设备那我们只想在这些IO设备有有意义的数据/信号时CPU才回去处理这些数据而在平时IO设备没有数据时不要打扰CPU的其他正常工作。这就要通过中断来实现。
CPU有一个中断引脚收到某个特定的电信号会触发中断
保存 5 个寄存器 (cs, rip, rflags, ss, rsp)跳转到中断向量表对应项执行 CPU有且只有一个中断引脚如图中6502的4号引脚 IRQˉ\bar{IRQ}IRQˉ。那CPU是怎样管理各种不同的中断以及不同中断到来时的处理优先级的呢这就要用到一个特殊的IO设备中断控制器。
系统中的其他设备可以向中断控制器连线。从而实现上面提到的中断优先级的判断、中断屏蔽等功能。
Intel 8259 PICprogrammable interrupt controller微机原理中也介绍过配合8086可以设置中断屏蔽、中断触发等……APIC (Advanced PIC)现代CPU中使用的中断控制器 local APIC每个CPU内部的中断管理: 中断向量表, IPI, 时钟, ……I/O APIC外部IO的中断管理: 其他 I/O 设备
总线
想法
如果你只造 “一台计算机”随便给每个设备定一个端口/地址用 mux 连接到 CPU 就行。
但如果你希望给未来留点空间
想卖大价钱的 “大型机” IBM, DEC, … 车库里造出来的 “微型机” 名垂青史的梦想家 都希望接入更多 I/O 设备 甚至是未知的设备即可扩展性
在多个IO设备时每个IO设备中的每个寄存器都有一个自己的地址那肯定不能将这些寄存器全部直连到CPU上。
总线介绍
总线提供地址到设备的转发。把从CPU传来的地址总线地址和数据转发到相应的设备上按照上面说的每个设备中的每个寄存器的地址。例如 port I/O 的端口就是总线上的地址IBM PC 的 CPU 其实只看到这一个 I/O 设备。
这样 CPU 只需要直连一个总线 (例如今天的 PCI总线 (Peripheral Component Interconnect) 就行了
总线可以负责IO设备寄存器的地址编址总线可以桥接其他总线 (例如 PCI → USB)lspci -tv 和 lsusb -tv: 查看系统中总线上的设备概念简单实际非常复杂 电气特性、burst 传输、中断……
例子PCI Device Probe
DMADirect Memory Access
想法
假设程序希望写入 1 GB 的数据到磁盘
即便磁盘已经准备好依然需要非常浪费缓慢的循环out 指令写入的是设备缓冲区需要去总线上绕一圈 cache disable; store 其实很慢的
for (int i 0; i 1 GB / 4; i) {outl(PORT, ((u32 *)buf)[i]);
}能否把 CPU 从执行循环中解放出来
比如在系统里加一个 CPU专门复制数据?好像 memcpy_to_port(ATA0, buf, length);
DMA介绍 DMA可以理解为一个只能执行memcpy这一条指令的迷你处理器它只负责直接将内存上的内容搬运的磁盘。而不需要真正的CPU的参与不需要占用真正的CPU时间。实际实现直接把 DMA 控制器连接在总线和内存。 由于DMA处理器只进行memcpy这样一条指令因此它的实现比通用的真正的CPU简单得多。 DMA不仅可以完成内存和设备之间的内容搬运而也可以是内存和内存之间。即可以有 memory → memorymemory → device (register)device (register) → memory PCI 总线支持 DMA即PCI中自带DMA这就是为什么 CPU 会有 PCIe lanes。
GPU
在CPU眼中显卡GPU也是一种IO设备通过读写某些寄存器来交互。
一切皆可计算
for (int i 1; i H; i) {for (int j 1; j W; j)putchar(j i ? * : );putchar(\n);
}难办的是性能
NES: 6502 1.79Mhz; IPC 0.43 屏幕共有 256 x 240 61K 像素 (256 色)60FPS → 每一帧必须在 ~10K 条指令内完成 如何在有限的 CPU 运算力下实现 60Hz
既然能做一个只专注于 memcpy 的硬件DMA为什么不能做一个画图的硬件在输出图形时可以认为对每个像素点做的是相同的计算指令不同的数据的计算因此可以认为是一种并行计算。因此我们也可以用一个专注于处理并行计算的非通用功能的处理器GPU只用来处理图形相关的这类并行计算。
现代GPU一个通用计算设备
一个完整的众核多处理器系统
注重大量并行相似的任务 程序使用例如 OpenGL, CUDA, OpenCL, … 书写 程序保存在内存 (显存) 中 nvcc: 把 main 编译/链接成 ELF; kernel 编译成 GPU 指令 数据也保存在内存 (显存) 中 可以输出到视频接口 (DP, HDMI, …)也可以通过 DMA 传回系统内存
gpgpu通用图形处理器
通过对处理图形显示这类并行计算任务的推广出现了通用图形处理器。它们不再只关注图形处理而是可以针对更广范围的并行计算比如神经网络的计算、矩阵计算。
通用图形处理器General-purpose computing on graphics processing units简称GPGPU是一种利用处理图形任务的图形处理器来计算原本由中央处理器处理的通用计算任务。这些通用计算常常与图形处理没有任何关系。由于现代图形处理器强大的并行处理能力和可编程流水线令流处理器可以处理非图形数据。特别在面对单指令流多数据流SIMD且数据处理的运算量远大于数据调度和传输的需要时通用图形处理器在性能上大大超越了传统的中央处理器应用程序。
I/O设备的抽象
I/O设备是操作系统中的对象文件
无论何种 I/O 设备都是可以读 (read) 写 (write) 的字节序列 (流或数组)。 I/O设备应该是操作系统中怎样的对象操作系统最简单或者说最不负责任的做法当然是可以直接将IO设备的寄存器或者PCI总线的控制寄存器暴露给应用程序。微内核的操作系统就是这么做的微内核的系统只做最少、最必要的部分。
但如果操作系统再负责一点将我们的每个IO设备比如键盘、磁盘等都抽象成操作系统中的一个对象。
操作系统设备 支持以下三种操作的对象 (文件)
read: 从设备某个指定的位置读出数据write: 向设备某个指定位置写入数据ioctl: 读取/设置设备的状态
而以上这三种操作恰恰就是文件系统中一个文件应该支持的操作。 Everything is a file !
设备驱动程序实现抽象
设备驱动程序把对设备的 read/write/ioctl 系统调用 “翻译” 成设备的寄存器命令序列。
以 “面向对象” 的方式访问 I/O 设备设备 支持 read, write, ioctl, … 功能的对象。
例子/dev 中的对象
/dev/pts/[x] - pseudo terminal/dev/zero - “零” 设备/dev/null - “null” 设备一般不想要的输出可以直接重定位到这个设备。/dev/random/dev/urandom- 随机数生成器
未必一定要有物理设备
设备驱动程序将设备抽象为一个对象和操作未必一定要有物理设备比如/dev/null, /dev/urandom。就是操作系统中不需要物理设备的一种设备/文件/对象的抽象。
试一试 试一试执行命令head -c 512 [device] | xxd并观察它们的strace来查看访问设备的系统调用。 tty查看当前终端输出/dev/pts/3即当前终端是3号终端。 如果我们再打开一个终端并向之前的3号终端输出是可以直接出现在3号终端上的echo Hello /dev/pts/3。 也就是说每个打开的终端也被看做是在设备目录/dev下的一个设备。
存储设备的抽象
磁盘 (存储设备) 的访问特性与其他的设备的读写略有不同是以块为单位的。
以数据块 (block) 为单位访问传输有 “最小单元”块内不支持任意随机访问大吞吐量使用 DMA 传送数据。应用程序不直接访问 访问者通常是文件系统 (维护磁盘上的数据结构)大量并发的访问 (操作系统中的进程都要访问文件系统)
对比一下终端和 GPU的确是很不一样的设备
终端小数据量、直接流式传输GPU大数据量、DMA 传输
总结
本次课内容与目标
理解 “什么是 I/O 设备” 终端、键盘、鼠标、总线、DMA、GPU…… 理解 “I/O 设备在操作系统中的抽象” 可以读/写/控制的对象
Takeaway messages
如果你 “自己造一台计算机”你会发现这一切都是自然的 “不容易理解” 的部分是随时间积累的复杂性