USB4 和 Thunderbolt¶
USB4 是基于 Thunderbolt 3 协议的公共规范,但在寄存器级别和其他方面存在一些差异。连接管理器是在主机路由器(主机控制器)上运行的实体,负责枚举路由器并建立隧道。连接管理器可以在固件或软件中实现。通常,PC 配备用于 Thunderbolt 3 和早期支持 USB4 的系统的固件连接管理器。另一方面,Apple 系统使用软件连接管理器,后来的 USB4 兼容设备也遵循这种做法。
Linux Thunderbolt 驱动程序同时支持这两种实现,并且可以在运行时检测要使用哪种连接管理器实现。为了安全起见,Linux 中的软件连接管理器还宣传 user
安全级别,这意味着默认情况下禁用 PCIe 隧道。以下文档适用于这两种实现,但软件连接管理器仅支持 user
安全级别,并且预计会伴随基于 IOMMU 的 DMA 保护。
安全级别以及如何使用它们¶
这里提供的接口不是为最终用户设计的。相反,应该有一个用户空间工具来处理所有底层细节,维护授权设备数据库,并提示用户建立新连接。
有关 Thunderbolt 设备的 sysfs 接口的更多详细信息,请参见 ABI 文件测试/sysfs-bus-thunderbolt。
那些只想连接任何设备而无需任何手动操作的用户可以将以下行添加到 /etc/udev/rules.d/99-local.rules
ACTION=="add", SUBSYSTEM=="thunderbolt", ATTR{authorized}=="0", ATTR{authorized}="1"
这将自动授权所有出现的设备。但是,请记住,这会绕过安全级别,并使系统容易受到 DMA 攻击。
从 Intel Falcon Ridge Thunderbolt 控制器开始,有 4 个安全级别可用。 Intel Titan Ridge 增加了一个安全级别(usbonly)。原因是连接的设备可以是 DMA 主设备,从而可以在 CPU 和操作系统不知情的情况下读取主机内存的内容。可以通过设置 IOMMU 来防止这种情况,但由于各种原因,IOMMU 并非始终可用。
一些 USB4 系统具有禁用 PCIe 隧道的 BIOS 设置。 这被视为另一个安全级别 (nopcie)。
安全级别如下
- none
所有设备都由固件自动连接。 不需要用户批准。 在 BIOS 设置中,这通常称为传统模式。
- user
询问用户是否允许连接设备。 基于通过
/sys/bus/thunderbolt/devices
提供的设备识别信息,用户可以做出决定。 在 BIOS 设置中,这通常称为唯一 ID。- secure
询问用户是否允许连接设备。 除了 UUID 之外,设备(如果它支持安全连接)还会收到一个挑战,该挑战应与基于写入
key
sysfs 属性的随机密钥的预期挑战相匹配。 在 BIOS 设置中,这通常称为一次保存密钥。- dponly
固件自动为 Display Port 和 USB 创建隧道。 不执行 PCIe 隧道。 在 BIOS 设置中,这通常称为仅显示端口。
- usbonly
固件自动在扩展坞中为 USB 控制器和 Display Port 创建隧道。 所有扩展坞下游的 PCIe 链路都将被删除。
- nopcie
PCIe 隧道已从 BIOS 中禁用/禁止。 在一些 USB4 系统中可用。
当前的安全级别可以从 /sys/bus/thunderbolt/devices/domainX/security
读取,其中 domainX
是主机控制器管理的 Thunderbolt 域。 每个 Thunderbolt 主机控制器通常有一个域。
如果安全级别显示为 user
或 secure
,则必须先由用户授权连接的设备,然后才能创建 PCIe 隧道(例如,出现 PCIe 设备)。
每个插入的 Thunderbolt 设备都将出现在 /sys/bus/thunderbolt/devices
下的 sysfs 中。 设备目录包含可用于识别特定设备的信息,包括其名称和 UUID。
利用 IOMMU 进行 DMA 保护¶
从 2018 年开始及以后的带有 Thunderbolt 端口的最新系统可能本机支持 IOMMU。 这意味着 Thunderbolt 安全由 IOMMU 处理,因此连接的设备无法访问驱动程序为其分配的内存区域之外的内存区域。 当 Linux 在此类系统上运行时,如果用户尚未启用 IOMMU,则会自动启用 IOMMU。 可以通过从 /sys/bus/thunderbolt/devices/domainX/iommu_dma_protection
属性读取 1
来识别这些系统。
在这种情况下,驱动程序不会执行任何特殊操作,但是由于 DMA 保护由 IOMMU 处理,因此安全级别(如果已设置)是冗余的。 因此,某些系统在将安全级别设置为 none
的情况下发货。 其他系统将安全级别设置为 user
,以便支持降级到旧操作系统,因此希望在启用 IOMMU DMA 保护时自动授权设备的用户可以使用以下 udev
规则
ACTION=="add", SUBSYSTEM=="thunderbolt", ATTRS{iommu_dma_protection}=="1", ATTR{authorized}=="0", ATTR{authorized}="1"
升级 Thunderbolt 设备、主机或中继器上的 NVM¶
由于大多数功能是在主机控制器或设备上运行的固件中处理的,因此重要的是可以升级固件到最新的版本,其中已修复了其中的可能错误。 通常,OEM 会从其支持站点提供此固件。
还有一个中心站点,其中包含用于下载某些机器的固件的链接
在升级设备、主机或中继器上的固件之前,请确保它是合适的升级。 如果不这样做,可能会使设备处于无法再正常使用的状态,而无需特殊工具!
不支持在 Apple Mac 上进行主机 NVM 升级。
下载 NVM 映像后,您需要插入 Thunderbolt 设备,以便主机控制器出现。 连接哪个设备无关紧要(除非您正在升级设备上的 NVM - 那么您需要连接该特定设备)。
请注意,OEM 特定的控制器加电方法(“强制加电”)可能适用于您的系统,在这种情况下,无需插入 Thunderbolt 设备。
之后,我们可以将固件写入主机或设备的 NVM 的非活动部分。 例如,以下是如何升级 Intel NUC6i7KYK (Skull Canyon) Thunderbolt 控制器 NVM 的方法
# dd if=KYK_TBT_FW_0018.bin of=/sys/bus/thunderbolt/devices/0-0/nvm_non_active0/nvmem
操作完成后,我们可以触发 NVM 身份验证和升级过程,如下所示
# echo 1 > /sys/bus/thunderbolt/devices/0-0/nvm_authenticate
如果未返回任何错误,则主机控制器会很快消失。 驱动程序在返回后会注意到它,并启动完整的电源周期。 过一段时间后,主机控制器再次出现,此时它应该是完全可以正常使用的。
我们可以通过运行以下命令来验证新的 NVM 固件是否已激活
# cat /sys/bus/thunderbolt/devices/0-0/nvm_authenticate
0x0
# cat /sys/bus/thunderbolt/devices/0-0/nvm_version
18.0
如果 nvm_authenticate
包含除 0x0 以外的任何内容,则它是上次身份验证周期的错误代码,这意味着 NVM 映像的身份验证失败。
请注意,NVMem 设备的名称 nvm_activeN
和 nvm_non_activeN
取决于它们在 NVMem 子系统中注册的顺序。 名称中的 N 是 NVMem 子系统添加的标识符。
在没有连接电缆的情况下升级板载中继器 NVM¶
如果平台支持,即使没有连接到 USB4 端口,也可以升级中继器 NVM 固件。 在这种情况下,usb4_portX
设备具有两个特殊属性:offline
和 rescan
。 升级固件的方法是首先将 USB4 端口置于离线模式
# echo 1 > /sys/bus/thunderbolt/devices/0-0/usb4_port1/offline
此步骤可确保端口不响应任何热插拔事件,并确保中继器已通电。 下一步是扫描中继器
# echo 1 > /sys/bus/thunderbolt/devices/0-0/usb4_port1/rescan
这将枚举并添加板载中继器。 现在可以像连接电缆一样升级中继器 NVM(请参阅上一节)。 但是,中继器未断开连接(因为我们处于离线模式),因此在将 1
写入 nvm_authenticate
之后,应等待 5 秒或更长时间,然后再再次运行重新扫描
# echo 1 > /sys/bus/thunderbolt/devices/0-0/usb4_port1/rescan
如果一切顺利,则可以将端口恢复到正常工作状态
# echo 0 > /sys/bus/thunderbolt/devices/0-0/usb4_port1/offline
在主机控制器处于安全模式时升级 NVM¶
如果现有的 NVM 未经过正确身份验证(或丢失),则主机控制器将进入安全模式,这意味着唯一可用的功能是刷新新的 NVM 映像。 在此模式下,读取 nvm_version
会因 ENODATA
而失败,并且缺少设备识别信息。
要从此模式恢复,需要以与上一章中相同的方式将有效的 NVM 映像刷新到主机控制器。
隧道事件¶
当 thunderbolt_domain
中发生隧道更改时,驱动程序会将 KOBJ_CHANGE
事件发送到用户空间。 通知携带以下环境变量
TUNNEL_EVENT=<EVENT>
TUNNEL_DETAILS=0:12 <-> 1:20 (USB3)
<EVENT>
的可能值为
- activated
隧道已激活(创建)。
- changed
此隧道中发生了更改。 例如,带宽分配已更改。
- deactivated
隧道已拆除。
- low bandwidth
隧道没有获得最佳带宽。
- insufficient bandwidth
当前隧道要求没有足够的带宽。
仅当隧道已知时才提供 TUNNEL_DETAILS
。 例如,对于固件连接管理器,此信息缺失或未提供完整的隧道信息。 对于软件连接管理器,这包括完整的隧道详细信息。 当前的格式与驱动程序记录时使用的格式匹配。 随着时间的推移,这可能会发生变化。
通过 Thunderbolt 电缆进行网络连接¶
Thunderbolt 技术允许通过 Thunderbolt 电缆连接的两个主机之间进行软件通信。
可以通过 Thunderbolt 链路隧道传输任何类型的流量,但目前我们仅支持 Apple ThunderboltIP 协议。
如果另一台主机运行的是 Windows 或 macOS,则您唯一需要做的就是在两台主机之间连接 Thunderbolt 电缆; thunderbolt-net
驱动程序会自动加载。 如果另一台主机也是 Linux,则应在一台主机上手动加载 thunderbolt-net
(哪一台主机无关紧要)
# modprobe thunderbolt-net
这会自动触发另一台主机上的模块加载。 如果驱动程序已构建到内核映像中,则无需执行任何操作。
驱动程序将为每个 Thunderbolt 端口创建一个虚拟以太网接口,这些接口的名称类似于 thunderbolt0
等。 从这一点开始,您可以要么使用标准的 用户空间工具(例如 ifconfig
)来配置接口,要么让您的 GUI 自动处理它。
强制加电¶
许多 OEM 都包含一种方法,可用于强制 Thunderbolt 控制器的电源进入“开启”状态,即使未连接任何设备。 如果您的计算机支持,则将通过 WMI 总线公开此功能,并带有一个名为“force_power”的 sysfs 属性。
- 例如,intel-wmi-thunderbolt 驱动程序在以下位置公开此属性
/sys/bus/wmi/devices/86CCFD48-205E-4A77-9C48-2021CBEDE341/force_power
要强制电源开启,请将 1 写入此属性文件。 要禁用强制电源,请将 0 写入此属性文件。
注意:目前无法查询平台的强制电源状态。