SATA协议基础:链路层、传输层、命令层简介

做SATA测试这些年,我有个很深的体会——不了解协议的三层架构,热插拔测试就只能是瞎蒙。链路层管物理连接,传输层管数据包装,命令层管真正的读写操作。这三层各有各的脾气,也各有各的坑。

咱们一层一层来看。

SATA 协议三层架构 命令层 (Command Layer) 核心功能:ATA/ATAPI 命令集解析与执行 关键命令:IDENTIFY DEVICE | READ DMA | WRITE DMA | SET FEATURES 热插拔相关:命令超时处理 | 设备重枚举 传输层 (Transport Layer) 核心功能:FIS(帧信息结构)封装与解析 FIS 类型:Register FIS | Data FIS | DMA Setup FIS | X_RDY 热插拔关注点:FIS 交换完整性 | 超时重传机制 链路层 (Link Layer) 核心功能:OOB 信号序列 | 8b/10b 编码 | CRC 校验 OOB 序列:COMINIT → COMWAKE → COMRESET 热插拔核心:信号完整性 | 去抖时间 | 速率协商 应用层 封装层 物理层

链路层:热插拔的第一道门槛

链路层是整个SATA通信的物理基础。说白了,它就是负责两根设备能不能说上话。

我习惯把链路层的工作分成两步:

  • 建链阶段:通过OOB(带外)信号握手,完成速率协商。
  • 传输阶段:用8b/10b编码保证DC平衡,用CRC保证数据不出错。

热插拔时,链路层是第一个感知到变化的。设备插进去,先产生COMINIT信号;主机收到后回复COMWAKE,然后双方商定速率——1.5Gbps、3Gbps或者6Gbps。

我的习惯:测试热插拔时,一定要用示波器抓OOB信号序列。COMINIT的脉宽是106.7ns,一旦偏差超过±5%,链路就可能建不起来。我在项目里遇到过好几次因为PCB走线太长导致信号衰减,COMINIT被误判为噪声的情况。

传输层:包装数据的艺术

链路层把物理通道打通了,传输层就该干活了。它的核心任务:把命令和数据装进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:强制写回缓存,热拔出前必须保证数据不丢。

命令层的执行流程大概是:

  1. 主机通过Register FIS下发命令。
  2. 设备解析命令,准备数据或执行操作。
  3. 设备通过Register FIS返回状态(比如BSY=忙,DRQ=请求数据)。
  4. 数据传输(如果是读写命令,走Data FIS)。
  5. 命令完成,设备返回正常状态。
热插拔测试的重灾区:命令超时。热拔出时,如果主机正在等待数据,设备突然消失(SOF突然中断),传输层不会知道链路断了,它会一直等。直到命令层超时——这个超时值在SATA规范里建议是10秒,但很多芯片默认设得很短(比如3秒)。我曾经测试过一款SSD,热拔出后3秒内主机就报设备不存在,但实际链路层还没完全断开,导致后续重连时状态混乱。

三层之间的协同

你看,这三层不是各干各的。链路层建链,传输层打包,命令层执行。任何一个层出问题,热插拔就失败。

我的经验是:测试热插拔时,不能只看现象。比如设备识别失败,问题可能出在链路层(OOB没握手成功),可能出在传输层(FIS被CRC丢弃),也可能出在命令层(IDENTIFY DEVICE超时)。

所以我做测试的时候会同时抓三样东西:

  • 示波器看链路层OOB和信号质量。
  • SATA协议分析仪看传输层FIS交换。
  • 主机端驱动日志看命令层状态机。

三样一对照,问题大概率能定位。嗯,这就是后面几节课要展开的实战内容了。