SATA协议基础:链路层、传输层、命令层简介
做SATA测试这些年,我有个很深的体会——不了解协议的三层架构,热插拔测试就只能是瞎蒙。链路层管物理连接,传输层管数据包装,命令层管真正的读写操作。这三层各有各的脾气,也各有各的坑。
咱们一层一层来看。
链路层:热插拔的第一道门槛
链路层是整个SATA通信的物理基础。说白了,它就是负责两根设备能不能说上话。
我习惯把链路层的工作分成两步:
- 建链阶段:通过OOB(带外)信号握手,完成速率协商。
- 传输阶段:用8b/10b编码保证DC平衡,用CRC保证数据不出错。
热插拔时,链路层是第一个感知到变化的。设备插进去,先产生COMINIT信号;主机收到后回复COMWAKE,然后双方商定速率——1.5Gbps、3Gbps或者6Gbps。
传输层:包装数据的艺术
链路层把物理通道打通了,传输层就该干活了。它的核心任务:把命令和数据装进FIS(Frame Information Structure)里。
FIS长什么样?我列一个典型的帧结构:
| 字段 | 长度 | 说明 |
|---|---|---|
| SOF(Start of Frame) | 1 Dword | 帧起始定界符 |
| FIS Type | 1 Byte | 标识FIS类型:27h=Register FIS,46h=Data FIS |
| Payload | 可变 | 命令参数或数据 |
| CRC | 1 Dword | 对整个帧做CRC32校验 |
| EOF(End of Frame) | 1 Dword | 帧结束定界符 |
这里面有个关键点:FIS类型决定了解析方式。热插拔时最常打交道的是Register FIS(用于发送命令)和Data FIS(用于传输数据)。
避坑指南:我曾经遇到一个案例,设备热插入后,主机发出去的Register FIS得不到回应。抓包一看,FIS里的CRC字段算错了。设备收到后直接丢掉,根本不回ACK。后来发现是测试板上的时钟抖动太大,CRC计算逻辑被干扰。从那以后,我每次做热插拔测试都会先确认CRC计算的稳定性。
命令层:真正的读写从这里开始
传输层把FIS包装好发到链路层,最终是为了执行命令。命令层就是干这个的——它负责解析ATA/ATAPI命令,调用对应的驱动逻辑。
常用的命令有这些:
- IDENTIFY DEVICE:查询设备能力,热插拔后主机第一件事就是发这命令。
- READ DMA / WRITE DMA:带DMA的数据读写,效率最高。
- SET FEATURES:配置设备特性,比如电源管理、设备休眠。
- FLUSH CACHE:强制写回缓存,热拔出前必须保证数据不丢。
命令层的执行流程大概是:
- 主机通过Register FIS下发命令。
- 设备解析命令,准备数据或执行操作。
- 设备通过Register FIS返回状态(比如BSY=忙,DRQ=请求数据)。
- 数据传输(如果是读写命令,走Data FIS)。
- 命令完成,设备返回正常状态。
三层之间的协同
你看,这三层不是各干各的。链路层建链,传输层打包,命令层执行。任何一个层出问题,热插拔就失败。
我的经验是:测试热插拔时,不能只看现象。比如设备识别失败,问题可能出在链路层(OOB没握手成功),可能出在传输层(FIS被CRC丢弃),也可能出在命令层(IDENTIFY DEVICE超时)。
所以我做测试的时候会同时抓三样东西:
- 示波器看链路层OOB和信号质量。
- SATA协议分析仪看传输层FIS交换。
- 主机端驱动日志看命令层状态机。
三样一对照,问题大概率能定位。嗯,这就是后面几节课要展开的实战内容了。