< 返回博客

网件4300v2无限重启救砖 - USB2TTL & UBoot


问题和方案

半年前买了个网件4300路由器,挺好用的。后来因为PicoVR的PC串流需要Wifi6,换成了小米ax3000,ax3000到手后才发现不能刷openwrt,所以现在内网里面的DNS还是用的网件4300。

前段时间不知道干了啥,经过一次停电之后,4300就再也启动不起来了,一直无限重启,tftp刷机模式也进不去。在网上看到4300有个UART接口,这个接口可以通过USB转接头来串口连接到电脑上,连上之后可以进入到uboot来恢复系统。

物理连接

USB转接头在淘宝上买的,十几块钱一个,大概长这样(淘宝搜索“USB TTL”大概就能搜到):

USB TTL

然后把路由器拆开,在一个角落会有四个露出来的引脚:

uart

把这些引脚放到左下角,引脚朝上,那这四个引脚从上到下的顺序分别是:OPENTXRXGND(这里的OPEN脚这次用不到)。

然后可以用杜邦线把转接头和UART引脚连接起来,连接方式为GND-GNDRX-TXTX-RXOPEN脚不连。这里连的时候一定要注意,两边的RX和TX是反着的。

conn

连好之后把USB插到电脑上就可以下一步了。

连接串口

这一步主要是在电脑上配置,网上目前Windows平台的教程居多,这次我摸索着在Linux弄好了。

(这种方法比较麻烦,如果想省事可以看下面的 连接串口 - picocom 一节)

首先是需要几个程序:

  • screen:也就是GNU Screen,用来连接tty设备
  • baud:这个是为了修改波特率的

连接tty

USB接口连到电脑上之后,会出现一个新的tty设备/dev/ttyUSB0,通过对这个设备进行读写,我们就可以和路由器进行交流。这需要借助一些终端软件,这次我使用的是screen

用法也很简单,sudo screen /dev/ttyUSB0即可。

如果需要断开,可以使用ctrl-a K然后按y的组合键来关闭screen。

修改波特率

打开screen之后启动路由器,这时候会发现终端里面可能是乱码的,这是因为波特率没有设置好。

mojibake

参考这篇文章,4300这个芯片在引导的时候(uboot阶段),波特率需要是116600~126300之间的值,这里我们用117200。

如果有乱码,确定杜邦线本身没坏,针脚没接错,那一般情况是波特率的问题,测波特率要用示波器。我操作到这一步时就是乱码,但是我没有示波器,某电商网站上的报价是一两千块钱一台,我这一台二手路由器才百元左右,为它买个示波器不值啊。于是乎,借助万能的搜索引擎和自己的尝试,我发现波特率设置为116600~126300之间的值时,是不会乱码的,取个117200,OK。

在Linux下设置波特率一般使用stty命令,但是117200不是一个标准波特率,没法用stty设置。我在github上面找到了一个小程序可以自定义波特率,看了下原理然后自己再写了一份,加了查看波特率以及错误检查之类的,也放到了github上面,如果有需要的话可以下载下来自行编译。

这里设置非标准波特率的具体方法也很简单,就是使用了struct termios2这个结构,这个结构可以自定义波特率;而stty用的是旧的struct termios,只支持一些预定义的波特率。Python的termios标准库也是一样,没办法自定义。

struct termios2的说明可以通过man ioctl_tty查看,搜索termios2即可。

termios2

解决问题

不出意外的话,调整波特率之后重启路由器就可以看到不乱码的输出了。

从这里的输出就可以看到无限重启的原因是一个mtd分区挂载失败,导致内核崩溃了。截图我忘记留了,但是和openwrt社区的这个帖子几乎一模一样:Kernel Panic - not syncing: VFS,可以作为参考。

解决方式就是帖子二、三楼的老哥说的,需要从openwrt的initramfs重新格式化一下分区。

进入uboot命令行

在系统启动过程中,会出现这样一串字符:

autoboot

这里会倒计时三秒,在三秒期间按回车就可以而进入uboot的命令行,这里的ath> 就是提示符。

tftpboot

接下来我们需要通过uboot的tftp启动到openwrt的initramfs里头,首先需要从这里下载镜像,找netgear_wndr4300-v2-initramfs-kernel.bin这个文件即可。

然后在uboot中输入tftpboot,就可以看到它已经在等待tftp服务器了:

tftpboot

根据这里的提示,我们需要在ip为192.168.1.101的设备上通过tftp服务提供一个叫做0101A8C0.img的文件。

首先设置网络,通过网线将路由器的lan口(四个黑色中的一个)和电脑连上,然后在电脑上配置静态路由,ip为192.168.1.101,网关为192.168.1.1,设置好之后确保可以ping通192.168.1.1。

然后开启tftp服务,这里我用的是uftpduftpd -n -o ftp=0,tftp=69 .即可,需要注意最后一个参数指定的路径里面要有一个名字为0101A8C0.img的文件,这个文件就是之前下载的initramfs-kernel.bin重命名之后得来的。

一切顺利的话,这时候查看uboot那边,路由器应该已经在下载镜像了。下载完成之后,输入bootm就可以启动到openwrt里,这个环境可以理解为一个类似PE/LiveCD的维护环境。

(提示:除了tftpboot,应该也可以通过bootm命令来等待tftp客户端传递镜像,这样子电脑上只需要tftp客户端就可以了,会更好操作一些。)

这时候我发现现有的117200波特率会导致无法正确输入,所以又需要通过上面那个程序把波特率改成标准的115200。这里我推测是内核启动起来之后,波特率就需要变成115200,而uboot中都需要使用117200。这一点很坑,弄了很长时间。

sysupgrade

在这个维护环境中,我们可以通过sysupgrade命令安装真实的openwrt镜像。

首先在openwrt的网件4300v2的页面上下载最新版本的镜像包,得到squashfs-sysupgrade.bin文件。

然后可以在路由器的openwrt中通过scp把电脑上的文件复制过来,当然前提还是路由得先配置好,检查下电脑和路由器是否能ping通。

文件复制到之后,sysupgrade xxx-squashfs-sysupgrade.bin就可以开始写入镜像了,这个过程会把所有分区都重新格式化,因此可以解决上面mtd挂载失败的问题。等待完成后自动重启,一切就大功告成了,就算路由器重启也不会再出现崩溃了。

连接串口 - picocom

(这一节作为上面连接串口的补充。)

上面提供的screen+baud的方式总的来说比较麻烦,后来我发现了picocom这个工具,支持自定义波特率。安装之后只需要picocom -b 117200 /dev/ttyUSB0一行命令即可,其中的-b参数就是指定波特率的,之后任意波特率。

参考