总线设备
不同的设备通过各自的总线挂载到系统上,总线协议定义了硬件设备与 CPU、内存之间的通信规则,包括数据传输、设备发现、资源分配等生命周期的内容。这是硬件层面的内容,但它也提示了操作系统,应当以怎样的逻辑来管理这个总线上的硬件。
总线上的设备通过一个特殊的硬件,总线控制器来管理,这是硬件层面的协议,操作系统可以通过总线控制的驱动来管理总线控制器,从而通过总线控制器来管理这条总线上的所有设备。
目前的硬件总线主要包括:PCI、USB、I2C 等,对于部分设备无挂载总线——一般称为平台设备,使用自定义的方式进行注册。总线设备依赖于总线控制器进行工作,而总线控制器本身也是平台设备,需要使用额外的机制进行发现,ACPI 或者设备树。
硬件行为
总线协议规定了一种设备的行为模型,通过行为模型确定了该类设备如何和总线控制器交互,同时操作系统如何通过总线控制器来管理该类型的设备。
- 设备探测:操作系统识别系统中存在硬件设备的过程,通过扫描总线来发现设备,支持热插拔特性,即支持动态探测;探测解决的问题是在物理内存地址空间上的哪一段上存在着一个怎样的设备?
- 设备枚举:为设备分配总线唯一标识(如地址、设备号),一般是设备探测后的进一步过程,在此之后,操作系统才能初始化这个设备,给这个设备绑定驱动,使其可被操作系统和驱动使用。
- 资源配置:设置设备寄存器、分配资源,通常在设备枚举完成后,由总线驱动或内核在设备初始化(probe 阶段)时执行,包括:
- 中断号(IRQ)
- 内存映射 I/O(MMIO)地址
- I/O 端口
- DMA 通道
- 设备拔出:总线设备支持热插拔,即在操作系统不重启的情况下,动态添加和移除硬件设备;
- 电源管理:控制设备电源状态,使得设备进入休眠状态;
- 数据传输:设备成功配置,设备进入工作阶段,通过驱动程序中的数据传输函数进行数据读写数据;
- 中断处理:主要用于监听硬件事件,实现硬件级别的异步回调机制,包括数据接收、DMA 功能、错误处理等;
总线控制器的角色
总线控制器是连接 CPU 和总线设备的桥梁。从 CPU 的角度看,总线控制器本身是一个平台设备,它的寄存器通过 MMIO 访问。但从总线设备的角度看,总线控制器是总线协议的仲裁者和转发者。
以 I2C 控制器为例,CPU 通过 MMIO 配置 I2C 控制器的时钟频率、从设备地址、数据缓冲等。I2C 控制器根据这些配置,在 I2C 总线上产生启动条件、发送地址、读写数据、产生停止条件。I2C 设备只能看到总线上的时序,不知道 CPU 的存在。
这种分层设计简化了 CPU 的工作。CPU 不需要关心 I2C 总线的时序细节,只需要配置总线控制器。同样地,总线设备不需要知道 CPU 的架构,只需要实现总线协议。总线控制器作为中间层,屏蔽了双方的差异。
DMA 传输
对于高速总线设备,每次传输都经过 CPU 会成为瓶颈。直接内存访问 (DMA) 机制允许设备直接访问系统内存,无需 CPU 干预。DMA 控制器是总线设备的重要组成部分,它可以在设备和内存之间搬运数据。
DMA 传输的典型流程是:CPU 配置 DMA 控制器,设置源地址、目的地址和传输长度。DMA 控制器向总线申请控制权,获得控制权后开始数据搬运。传输完成后,DMA 控制器通过中断通知 CPU。
DMA 的优势在于释放 CPU 资源和降低传输延迟。CPU 可以在 DMA 传输的同时执行其他任务,提高了系统的并发能力。DMA 控制器通常使用硬件实现专门的搬运逻辑,其效率远高于软件拷贝。
但 DMA 也有复杂性。缓存一致性问题需要特别处理,设备写入内存的数据可能停留在 CPU 缓存中,导致 CPU 读取到旧数据。现代处理器通过缓存一致性协议 (如 MESI) 和 DMA 缓冲区管理来解决这个问题。
总线事务
总线设备通信的基本单位是事务。不同总线的事务格式不同,但都包含地址阶段、数据阶段和完成阶段。
PCIe 事务包含事务层包 (TLP)、数据链路层包 (DLLP) 和物理层包 (PLP)。TLP 携带地址、数据和属性信息,DLLP 提供链路可靠性和流控,PLP 负责物理传输。TLP 分为内存读写、IO 读写、配置读写、消息等类型,不同类型对应不同的操作。
USB 事务包含令牌包、数据包和握手包。令牌包指定事务类型和设备地址,数据包携带实际数据,握手包表示传输状态。USB 的批量传输、中断传输、同步传输和等时传输使用不同的事务格式和调度策略。
从驱动开发的角度看,理解总线事务有助于调试通信问题。当设备无法响应时,可能是事务格式错误、时序不满足、电气连接问题等。使用逻辑分析仪捕获总线信号,对照总线协议分析事务流程,是定位问题的有效手段。