追逐光的步伐

现代CPU是以光速运行的,以GDK8的RK3328 CPU为例,它的主频是1.5G Hz,这意味着当它以额定频率运行时,每个时钟周期的时间为0.666纳秒。换言之,1纳秒时间里,会有1.5个时钟(clock)。而1纳秒时间里,光只能在真空中行进大约30公分。如果把30公分算作一步距离的话,那么在光行进一步的时间里,RK3328也可以行进1步多。所以,我常常说,现代CPU是以光速运行的。

576d677099dadb1a41ddbd58c043490d.png

正因为如此高的速度,所以,我们让电脑做事情的时候,我们常常感受不到它花时间,瞬间就完成了。

但也正因为这个原因,如果电脑背着我们做坏事情,常常也是我们无法察觉的,比如流氓软件在后台悄悄拉流量;比如恶意软件悄悄窃取信息,通过网络发走;比如黑客远程遥控,把我们的电脑当作他做坏事的替罪羊......

因为有如此多的比如,所以我们需要一种手段,把以光速飞奔的电脑停下来,而且是立刻就停,也就是想叫它啥时停,啥时就要立刻停下来,这个反应时间也要是纳秒级别的,这样才可能抓住上面列举的那些邪恶瞬间。

那么,如何让现代CPU在瞬间骤然停止呢?有没有这样的方法呢?

答案是肯定的。而且有两类方法,一类是软件方法,另一类是硬件方法,软件方法常常是有条件和有局限的,而硬件方法则是更加可靠和通用的。硬件方法就是通常所说的JTAG技术。

去年在研发GDK8时,我花了很多时间在JTAG上,也多次请底层经验丰富的格友来一起来攻击这个难关,在五一假期时曾取得了较大的进展,但因为种种原因,始终没有找到完美的产品级解决方案。于是只好在10月份时,改变计划,先发布不包含JTAG调试的基础版本。

基础版本发布后,如何解决JTAG问题,始终是压在我心上的一块石头。每当有相关的资料或者线索时,我总会再试一下。

元旦前,从事安全研究的老朋友leminis联系我,说他想在GDK8上尝试JTAG调试。我听了后,当然很支持,把我知道的信息都告诉他,帮他找转接板,给他发资料,给他提供切换信号的源代码。

为什么需要这么多东西呢?

问题就在这里。与X86的芯片上有专门的JTAG信号,主板上有支持JTAG的专用XTP端口不同,在ARM上,芯片的JTAG信号是与其它信号复用的,在板子上,也没有专门的JTAG口,也是与其它接口复用的。根本原因还是X86系统的价格贵,不那么在乎几个引脚和一个接口的成本,而ARM上,一切都是低成本,能省就省。

以GDK8为例,芯片的JTAG信号是与GPIO和SD卡复用的,在板子上,JTAG信号是与SD卡的卡槽复用的。

这样的复用节约了成本,但却带来了软硬件两方面的麻烦。软件方面,需要写寄存器来切换信号。硬件方面,需要飞线或者做个转接卡来把JTAG信号转出来。

软件好办一些,我写了个函数:

9a633116f26f5d92ab4c8ff5b3eb69a6.png

将其放在“刘姥姥”驱动里。

然后在GDK8上编译,使用insmod命令加载,然后通过proc虚文件来触发:

echo jtag | sudo tee -a /proc/llaolao

这样,就可以把复用的信号切换为JTAG用途了。

c5dd837d245f998794f904701dc4148c.png

切换后,向SD卡槽插SD卡,系统没有任何反应了。

硬件方面,要麻烦一些,在我的建议下,leminis从网上买了一根SD卡的延长线,然后他又发挥他的电烙铁技艺,飞了三根线。

b76dad26eb169551a0a2658881d216a5.png

对于软件工程师来说,上图这样的电烙铁手艺真的很棒了。

对我来说,因为去年就做这件事情,所以格蠹办公室里早已经做好了一些转接卡。

5cad62b1ac61df3fb5756af3ca6537ca.png

这些转接卡是我请搞硬件的朋友帮忙做的。

不要小看这个小转接板,它里面的花头也挺多的。在来自瑞芯微官方的电子表里,列了SD卡信号与JTAG信号的对应关系,但这个对应关系不是一套对一套,而是一套对多套。

b16df836a3a81158ba03ad035674d89d.png

更捉弄人的是,上面这个表居然没有列出SD信号的7号脚,而我们在去年试验时,恰恰论证出需要信号7,这是为什么上图中有一根白色的飞线。

元旦假期里,leminis多次给我发信息,报告他的进度,这让我很感动。

今天是元旦假期后的第一个工作日,我一大早到办公室后,打开电脑,回复了几封邮件后,我又想到了JTAG的事。

于是我在新一年里的第一个工作日里重整旗鼓,再战JTAG。先恢复之前在GDK7上搭好的工具环境,再找出转接卡,接上一根根跳线。

6668792d7b2332f8d5d6e8b93dc85a87.png

然后像前面说的那样使用llaolao驱动切换JTAG信号,然后启动OpenOCD进行扫描......

起初几次还是No Luck。OpenOCD给出的错误码是-4。

7d4cf08e551dba945e78c9cf6504f5b1.png

在-4错误码上面,有根本性的失败原因。

c38c1e766141dd24fc82ebdec4413fae.png

抄录一下这个关键的错误信息:

SWD ack not OK @ 0 JUNK

SWD是ARM发明的两线JTAG(也是为了低成本)技术代号,ack是通信领域的常用语,代表消息确认。归纳一下,前半句是说SWD的确认信号不OK,最后的JUNK直白到底......

看看搜索引擎给出的结果吧 ^_^

c47ba6361d4f6ac01339b5ac8e6c3d28.png

换句话说,OpenOCD给出上面的信息就代表,调试器这一方发出了信息后,没有收到合适的确认信号,收到的是“垃圾”数据。这意味着JTAG信号没有接通。

是什么导致信号不通呢?我想拿出万用表量一量,但又想先试试别的方法。

我又把转接卡拿起来仔细看电路板上的走线,因为SD信号一共只有8个,而需要的只有两个,即DATA2和DATA3,也就是SD信号的里的1号和2号。我顺着SD卡信号的源头寻找它的走向。

1e967c16550d452e5b7b3acc7c9163ac.png

2号线到另一面了,但是1号线的走向是比较容易看出来的。这一仔细看,发现问题了,转接卡上标注的TMS和TCK根本不是我想要的TMS和TCK。

3b9570f2ca40cbfa5ca5f149796c649b.png

原来硬件工程师是按上面电子表里的对应关系做的板子和标注,而这个对应关系是不固定的,不同芯片不一样,即使都是瑞芯微的芯片,也是不一样的。

找到这个大问题后,忽视卡上的标注,完全靠信号走向推测,重新连线,然后再上电、加载驱动,切换到JTAG,再运行OpenOCD,发起扫描。

这次居然扫描到了。

fad0fedba30aaa85c28134b267f257d3.png

-4错误和JUNK抱怨不见了,取而代之的是我盼望已久的从SoC ROM表里读回来的DAP设备信息。

看到这个成功的信息,我长出了一口气,站起来给调试现场拍了个照,留作纪念。

2123a0250879720b1005c08e22b96140.png

另一个成功的特征是,JTAG扫描仪的红灯反复闪烁,好似拼命的奔跑,它在通过边界扫描方式与目标CPU通信,它很忙碌,因为它在追赶光!

(写文章很辛苦,恳请各位读者点击“在看”,不胜感激)

*************************************************

正心诚意,格物致知,以人文情怀审视软件,以软件技术改变人生

扫描下方二维码或者在微信中搜索“盛格塾”小程序,可以阅读更多文章和有声读物

74e3ebea5b0155a15f7ca8b2c0c66057.png

也欢迎关注格友公众号

b7318237411f7bd29baebb55bc8ad9a4.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值