苹果闪电的工作原理





这是我的小文章,描述了(几乎)我了解的有关Apple Lightning接口和相关技术的所有信息:Tristar,Hydra,HiFive,SDQ,IDBUS等。但是,首先要提个警告……



请自担风险阅读本文!该信息基于我对角阅读的许多内部Apple内部材料(数据泄漏,示意图,源代码)。而且,当然,根据我自己的研究。我必须警告您,我从未做过此类研究。因此,本文可能使用了不正确或简单的奇怪术语,而部分或完全不正确!



在深入探讨之前,让我们简要了解一下这些术语:



什么是闪电?







自2012年底以来,Lightning是大多数Apple iOS设备中使用的数字接口。它取代了旧的30针连接器。



上图是连接器插座,下图是其引脚排列:







请注意,在连接器中,连接器两侧的插针未按相同顺序连接。因此,主机设备必须在执行任何操作之前确定电缆的方向。



尽管并非总是如此。我遇到的许多Lightning配件在连接器中都有镜像的引脚排列。



什么是Tristar和Hydra?







Tristar是每个带有Lightning连接器的设备中内置的集成电路。它本质上是一个多路复用器:







除其他事项外,其主要目的是在插入插头后立即连接到Lightning公连接器-确定方向,配件ID并正确布线内部接口(如USB,UART和SWD)。



Hydra是Tristar的新变种,自iPhone 8 / X起就使用。可能最重大的变化是对无线充电的支持,但这仍有待验证:







我知道Tristar / Hydra的五个主要变体:



  • TI THS7383  -iPad mini 1和iPad 4中的第一代Tristar

  • 恩智浦CBTL1608A1  -iPhone 5和iPod touch 5中的第一代Tristar

  • NXP CBTL1609A1  -iPod nano 7中神秘的第一代Tristar- 来源

  • 恩智浦CBTL1610Ax-  第二代TriStar,自iPhone 5C / 5S起使用,并且显然在不支持无线充电的所有其他产品中使用。存在多个世代(x是世代数)

  • 恩智浦CBTL1612Ax  -Hydra与iPhone 8 / X以及显然支持无线充电的所有其他产品一起使用。存在多个世代(x是世代数)


从现在开始,我将仅使用术语TriStar,但请记住,它也代表Hydra,因为它们在本文中涵盖的大多数方面都非常相似。



什么是HiFive?







HiFive是Lightning的子代,即插头连接器。它还包含一个逻辑门-该芯片被称为SN2025 / BQ2025。



什么是SDQ和IDBUS?







这两个术语通常被认为是各种同义词。为了方便起见,我将仅使用术语IDBUS,因为它对我来说似乎更正确(这就是THS7383规范中所称的技术)。



因此,IDBUS是用于Tristar和HiFive之间通信的数字协议。非常类似于Onewire协议



现在我们可以开始



让我们听听Tristar和HiFive的交流。获取一个逻辑分析仪,一个带插孔和公连接器的Lightning转接卡,一个附件(常规的Lightning-to-USB电缆非常有用),当然还有一个带Lightning端口的设备。



首先,将逻辑分析仪通道连接到提升板的两个ID线(引脚4和8),然后将板连接到设备,但仍不连接附件:







此后立即开始采样(2 MHz或更高的任何频率都可以)。您将看到如下内容:







如您所见,Tristar依次轮询每个ID行。但是由于我们没有插入任何附件,所以调查显然失败了。在某个时候,设备会厌倦无休止的故障流并将其停止。现在,让我们看一下轮询过程中到底发生了什么:







首先,我们看到一个很长的间隔(大约1.1毫秒),当该级别很高时,却什么也没发生:







显然,该时间用于为内部HiFive电容器充电-然后,来自其的能量将用于为内部逻辑芯片供电。



接下来会发生更多有趣的事情:







显然,这是一些数据的流。但是如何解释呢?如何解密?让我们实际上将其划分为最小的重要部分-我所说的单词







实际上,一个单词是由下降到上升,下降到下降的组合:







  • 内容阶段 -确定单词含义的时间间隔

  • 恢复阶段 -在接收方处理内容阶段和/或在发送阶段准备下一个字显然需要的时间间隔


这是一张上面我们讨论过的两个阶段的著名单词及其间距的表(所有单位以微秒为单位):



内容 复苏
典型值 最高 典型值
打破 12 十四 十六 2.5 4.5
唤醒 22 24 27 1100?
6 7 8 3
之一 1个 1.7 2.5 8.5
零和停止* 6 7 8 十六
一站式* 1个 1.7 2.5 21
*当它是字节中的最后一位时使用STOP。使用



上面的表,我们现在可以构建一个简单的协议解码器:







如您所见,主机首先发送一个BREAK-当Tristar要发送新请求时,主机始终以该字开头。然后进入数据传输阶段。请注意,字节的最后(第8个)位具有更长的恢复阶段。数据传输阶段结束后,主机将发送另一个BREAK。然后,孩子必须发送响应(在至少2.5微秒的延迟后-参见表)。 Tristar将等待约2.2毫秒以做出响应。如果在此时间段内未给出响应,Tristar将尝试询问另一个ID行。



现在让我们使用上面的示例-在数据阶段0x74 0x00 0x02 0x1f



  • 0x74 -请求/响应的类型。对于请求始终为偶数,对于响应始终为奇数(请求类型+1)

  • 0x00 0x02 -事实数据。可能是空的

  • 0x1f -这是请求类型字节和所有数据的CRC8(多项式-0x31,初始值-0xff)


让我们将一些附件连接到我们的钻机上,看看会发生什么。我将使用Apple原来的Lightning-to-USB电缆:







这是0x74请求后IDBUS上显示的内容:







HiFive回答了!如果进一步滚动,则会看到许多其他请求/响应对:







某些请求不需要响应:







解释IDBUS请求和响应



最重要的IDBUS请求是0x74,它用于两个目的:告诉HiFive打开全电压和安培数(如果附件支持),询问电缆支持的插针配置以及其他一些元数据。



对于0x75响应数据的编码方式知之甚少。但是旧的Tristar规范中有一些可用的位:



第一个响应数据字节0x75

7 6 4 3 2 1个 0
ACCx Dx 数据[43:40]


在ID0上找到ID时的ACCx配置

ACCx [1:0] ACC1 ACC2 HOST_RESET
00 Hi-Z(IDBUS) 高Z 高Z
01 UART1_RX UART1_TX 高Z
JTAG_DIO JTAG_CLK 高Z
十一 高Z 高Z


在ID1上找到ID时的ACCx配置

ACCx [1:0] ACC1 ACC2 HOST_RESET
00 高Z Hi-Z(IDBUS) 高Z
01 UART1_RX UART1_TX 高Z
JTAG_DIO JTAG_CLK 高Z
十一 高Z 高Z


在ID0上找到ID时的Dx配置

Dx [1:0] DP1 DN1 DP2 DN2
00 高Z 高Z 高Z 高Z
01 USB0_DP USB0_DN 高Z 高Z
USB0_DP USB0_DN UART1_TX UART1_RX
十一 高Z 高Z 高Z 高Z


在ID1上找到ID时的Dx配置

Dx [1:0] DP1 DN1 DP2 DN2
00 高Z 高Z 高Z 高Z
01 高Z 高Z USB0_DP USB0_DN
USB0_DP USB0_DN UART1_TX UART1_RX
十一 高Z 高Z 高Z 高Z


使用这些表,10 0C 00 00 00 00考虑到ID线位于ID0引脚上的事实,我们来解密电缆的ID():



0x75电缆响应的第一个字节

7 6 4 3 2 1个 0
ACCx Dx 数据[43:40]
0 0 0 1个 0 0 0 0


因此,ACCx为00,这意味着ID0引脚仅与IDBUS相连,而Dx = 01意味着DP1 / DN1引脚被配置为USB0_DP / USB0_DN。正是我们对标准USB电缆的期望。



现在让我们截取一些更有趣的东西:



附件 ID(主机ID = 1)
DCSD 20 00 00 00 00 00
KongSWD(无Astris运行) 20 02 00 00 00 00
KongSWD(运行Astris) A0 00 00 00 00 00
KanziSWD(不运行Astris) 20 0E 00 00 00 00
KanziSWD(运行Astris) A0 0C 00 00 00 00
Haywire(HDMI) 0B F0 00 00 00 00
充电UART 20 00 10 00 00 00
闪电到3.5毫米/带有闪电的EarPods 04 F1 00 00 00 00


这是来自@spbdimka的IDBUS请求的完整(?)列表







提示1:您可以使用accctl轻松获取附件的属性,包括其ID:





这是NonUI / InternalUI程序集附带的内部Apple实用程序。但是您可以在越狱后在任何设备上轻松运行它。



提示2:您可以使用诊断轻松获得电缆的引脚配置:



tristar -p




请注意,此命令仅在iOS 7+上可用。



提示3:通过将debugenv var 设置为3,您可以轻松跟踪SWD探针生成的0x74 / 0x75请求/响应



astrisctl setenv debug 3


然后在电缆上的虚拟COM上,您将看到以下内容:





主机名



在上面的表之一中,您可以看到提到的某个HOSTID。这是在0x74请求中传递的16位值。看起来它也影响了HiFive的答案。至少如果将其设置为无效值(是的,可能是通过诊断),HiFive将停止使用它:





但是,KongSWD / KanziSWD固件具有环境变量disableIdCheck,您可以将其配置为忽略无效的HOSTID。



重要说明: Kong和Kanzi没有HiFive作为专用的非可编程芯片。这些配件可通过微控制器和/或FPGA对其进行仿真,从而易于更新/重新编程。


唤醒



在上面的附件ID表中,您可以看到Kong和Kanzi根据Astris是否正在运行发送不同的响应,这是Apple的内部软件,用于使用SWD探针(或多个探针)进行调试。如果使用上表对这些答案进行解密,则会发现当Astris无法启动时,探针的行为将与DCSD-D1线上的USB和D2线上的UART完全相同。但是,在运行调试软件时,ACCID线会切换到SWD。



但是,如果我们想在探针已连接到设备后启动Astris,该怎么办?电缆会做什么?如何在ACC到SWD线之间切换?这是WAKE发挥作用的地方! HiFive(或模拟它的设备)可以启动唤醒  -IDBUS枚举过程将再次开始:Tristar将发送请求0x74,Kong / Kanzi将使用新ID进行响应,Tristar将进行确认并将ACC线路发送到SWD扩展(当然,SoC必须在物理级别支持此功能)。





电源握手



我要看的最后一件事是电源握手。这是Tristar内核驱动程序在允许附件充电之前使用的IDBUS请求/响应算法。



当Lightning电缆仅位于某个地方,已连接至充电器/计算机,但未连接至设备时,HiFive会将PWR上的电流限制为一个很小的值(根据我的测量,约为10-15 mA)。要启用全电流,必须由Tristar发出请求0x74,并由HiFive处理。对于SecureROM / iBoot,这已足够,但是在加载内核时必须采取其他步骤:



  1. TriStar发出两个0x70请求

  2. HiFive处理完第二个请求并发送响应后,它将立即关闭当前的所有内容约20毫秒

  3. Tristar 0x70, 0x80 . HiFive

  4. , Tristar,


: , . , . ,



ESN Tristar I2C



我想谈谈Tristar的另一个功能是ESN。这是Tristar在其EEPROM(在CBTL1610A2及更高版本中)存储的EEPROM中的一个小斑点。可以使用序列号读取器电缆通过IDBUS(或Kanzi,它们基本相同,除了不同的USB-PID和略有不同的外壳)可以



获取。简单地说,将这个Blob发送到ttrs.apple.com,您可以获得设备的序列号... Apple Store / Apple Premium Reseller员工使用此机制从死机中检索SN(如果Tristar仍然存在):







收到ESN时IDBUS在IDBUS上发生的情况,@ spbdimka记录如下:





训练



“固件»ESN的过程要求进行Tristar 培训(配置)。它通过接收方的EzLink分三步在设备端进行诊断



您可以使用诊断来检查状态:



tristar --prov_stat




...并获得ESN:



tristar --esn




顺便说一句,诊断程序通常具有丰富的Tristar命令集(自iOS 7起可用):





三星I2C



Tristar在I2C总线上可用(地址0x34用于写入,0x35用于读取)。这就是diag和内核驱动程序与之交互的方式。



有关注册表的公开信息并不多。可以从泄漏的iBoot源代码(仅适用于THS7383-似乎与CBTL1608-和​​CBTL1610向后兼容)中获取有关寄存器映射本身的很多信息,但是要获得任何有趣的结果,在那里需要写的内容并不多。



另一个知识来源是来自诊断程序的Tristar模块(运行时可通过SWD轻松检索)。例如,我能够撤销配置和ESN读取算法。然后,我将其实现为iBoot负载Lina的补充







我也尝试更改ESN写入算法,但失败了-该机制对我来说太复杂了。但是,此处提供Lina的代码段



Tristar的电气特性



Tristar本身由1.8V电源供电,根据我的示波器,IDBUS的线路可承受3.0V的电压:







因此,如果没有电平转换电路,最好不要尝试使用5V耐压的设备(例如某些Arduino模型)与IDBUS进行通信...



All Articles