最近在搞路由器的时候,不小心把CFE给刷挂了,然后发现能通过jtag进行救砖,所以就对jtag进行了一波研究。最开始只是想救砖,并没有想深入研究的想法。变砖的路由器型号为:LinkSys wrt54g v8CPU 型号为:BCM5354Flash型号为:K8D6316UBM首先通过jtagulator得到了设备上jtag接口的顺序。正好公司有一个jlink,但是参试了一波失败,识别不了设备。随后通过Google搜到发现了一个工具叫:
tjtag-pi可以通树莓派来控制jtag,随后学习了一波树莓派的操作。我使用的是rpi3,其接口编号图如下:
或者在树莓派3中可以使用gpio readall
查看各个接口的状态:
rpi3中的Python有一个RPi.GPIO
模块,可以控制这些接口。举个例子:首先是需要进行初始化GPIO的模式,BCM模式对应的针脚排序是上面图中橙色的部门。然后可以对各个针脚进行单独设置,比如上图中,把2号针脚设置为输出,3号针脚设置为输入。使用output函数进行二进制输出使用input函数获取针脚的输入。我们可以用线把两个针脚连起来测试上面的代码。将树莓派对应针脚和路由器的连起来以后,可以运行tjtag-pi程序。但是在运行的过程中却遇到了问题,经常会卡在写flash的时候。通过调整配置,有时是可以写成功的,但是CFE并没有被救回来,备份flash的数据,发现并没有成功写入数据。因为使用轮子失败,所以我只能自己尝试研究和造轮子了。首先是针脚,我见过的设备给jtag一般是提供了5 * 2以上的引脚。其中有一般都是接地引脚,另一半只要知道4个最重要的引脚。这四个引脚一般情况下的排序是:TDI表示输入,TDO表示输出,TMS控制位,TCK时钟输入。
jtag大致架构如上图所示,其中TAP-Controller的架构如下图所示:
根据上面这两个架构,对jtag的原理进行讲解。jtag的核心是TAP-Controller,通过解析TMS数据,来决定输入和输出的关系。所以我们先来看看TAP-Controller的架构。从上面的图中我们可以发现,在任何状态下,输出5次1,都会回到TEST LOGIC RE免费云主机域名SET
状态下。所以在使用jtag前,我们先通过TMS端口,发送5次为1的数据,jtag的状态机将会进入到RESET的复原状态。当TAP进入到SHIFT-IR
的状态时,Instruction Register
将会开始接收TDI传入的数据,当输入结束后,进入到UPDATE-IR
状态时将会解析指令寄存器的值,随后决定输出什么数据。SHIFT-DR
则是控制数据寄存器,一般是在读写数据的时候需要使用。讲到这里,就出现一个问题了,TMS就一个端口,jtag如何知道TMS每次输入的值是多少呢?这个时候就需要用到TCK端口了,该端口可以称为时钟指令。当TCK从低频变到高频时,获取一比特TMS/TDI输入,TDO输出1比特。比如我们让TAP进行一次复位操作:再比如,我们需要给指令寄存器传入0b10:1.复位2.进入RUN-TEST/IDLE状态3.进入SELECT-DR-SCAN状态4.进入SELECT-IR-SCAN状态5.进入CAPTURE-IR状态6.进入SHIFT-IR状态7.输入0b10随后就是进入EXIT-IR -> UPDATE-IR
根据上面的理论我们就可以通过写一个设置IR的函数:把上面的代码理解清楚后,基本就理解了TAP的逻辑。接下来就是指令的问题了,指令寄存器的长度是多少?指令寄存器的值为多少时是有意义的?不同的CPU对于上面的答案都不一样,通过我在网上搜索的结果,每个CPU应该都有一个bsd(boundary scan description)文件。本篇文章研究的CPU型号是BCM5354
,但是我并没有在网上找到该型号CPU的bsd文件。我只能找了一个相同厂商不同型号的CPU的bsd文件进行参考。
bcm53101m.bsd在该文件中我们能看到jtag端口在cpu端口的位置:能找到指令长度的定义:能找到指令寄存器的有效值:当指令寄存器的值为IDCODE
的时候,IDCODE寄存器的输出通道开启,我们来看看IDCODE寄存器:从这里我们能看出IDCODE寄存器的固定输出为:0b00000000000011011111001011111111
那我们怎么获取TDO的输出呢?这个时候数据寄存器DR就发挥作用了。用代码形式的表示如下:因为我也是个初学者,边界扫描描述文件中的内容并不是都能看得懂,比如在边界扫描文件中并不能看出BYPASS指令是做什么的。但是在其他文档中,得知BYPASS寄存器一般是用来做测试的,在该寄存器中,输入和输出是直连,可以通过比较输入和输出的值,来判断端口是否连接正确。另外还有边界扫描寄存器一大堆数据,也没完全研究透,相关的资料少的可怜。而且也找不到对应CPU的文档。当研究到这里的时候,我只了解了jtag的基本原理,只会使用两个基本的指令(IDCODE, BYPASS)。但是对我修砖没任何帮助。没办法,我又回头来看tjtag的源码,在tjtag中定义了几个指令寄存器的OPCODE:照抄着tjtag中flash AMD的操作,可以成功对flash进行擦除,写入操作读取操作。但是却不知其原理。这里分享下我的脚本:
jtag.pyflash 文档:
https://www.dataman.com/media/datasheet/Samsung/K8D6x16UTM_K8D6x16UBM_rev16.pdf接下来将会对该flash 文档进行研究,并在之后的文章中分享我后续的研究成果。
xshell的基础优化:1、终端类型和缓冲区大小1、将终端类型改为:Linux2、更改缓冲区大小:(可以记录多少条命令记录),越大越好2、设置外观 设置游标方便显示当前位置 字体名:最好使用默认的 游标:原本是静止不动的,改动闪烁的,方便知道当前位置 3、设置…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。