猫棒刷机研究笔记(教程)
TTL刷机(MA5671A):
自制TTL刷机工具或购买成品,建议购买JUPLINK 2.5G光纤收发器,自带TTL刷机接口,可分别用于华为、诺基亚猫棒TTL刷机。
USB转TTL串口模块,建议选择FT232RL或者CH341、CH340芯片的模块或带插针的编程器,理论上所有TTL模块均能使用。
将模块上的RX,TX,GND插针用跳线连接JUPLINK 2.5G光纤收发器上的对应插针,收发器上有两排插针,分别对应华为和诺基亚,注意区分,VCC(3.3V)插针不要连接。
然后将模块usb插入电脑,安装模块驱动,成功后设备管理器中会出现虚拟的COM口(如果串口模块插入电脑后,无响应,则可能TX,RX连接有误,可尝试 TX-RX RX-TX ,交叉连接)。
接下有两种操作方式,第一种先插入光纤收发器电源,再插入猫棒;第二种先插入猫棒,再插入光纤收发器电源,这两种操作方式的区别是接下来的调试中,是来回拔插猫棒,还是来回拔插电源,取决于你的个人爱好(我一直是拔插猫棒)。
另外,还有一种方法,就是不使用收发器电源,而是使用TTL模块上提供的VCC(3.3V)电源插针,这样的话,你接下来的选择就是来回拔插猫棒,还是来回拔插VCC(3.3V)的插针。
这种方法更适合自制的刷机工具,而不是成品收发器,毕竟自制工具没有独立供电。不过这种方法我试过没有成功,可能!可能!可能!跟我用的是CH340芯片的模块有关,其他教程使用的是FT232RL芯片的模块,模块我买了没到货,因此无法测试。也可能是跟收发器电路有关,不兼容,谁知道呢。
理论上模块芯片越新传输固件的速度越快,我模块买的早,当时是为了刷硬改过的TL-WR340G+、TL-MR11U、HAME MPR-A1等路由器,后来一直配合PN532复制门禁卡用,总之可以用就行了,没有必要买新模块,我是嫌拔来拔去太麻烦才买的FT232RL。
确保设备管理器中识别到虚拟的COM口后,接下来使用Tera Term,或者MobaXterm等终端工具进行操作,我用的是Tera Term 4.106,这个工具需要安装,可能有免安装版本的,我没找,也没用。
至于MobaXterm,功能很强大,但按下Ctrl+C无法中断猫棒启动,具体原因未知,因为Tera Term可以用,我就没有继续研究这个工具。但是SSH刷机时需要用这个工具,而且比Tera Term好用。
TTL刷机我主要用Tera Term工具,点击菜单里的文件-新建连接,选择串口模式,选择虚拟出的串口,点击确定;然后点击菜单里的设置-串口,将比特率设置为115200,这样就设置好了(此时可以点击菜单中的设置-保存配置,直接保存,这样下次打开就不用再重新设置了),此时窗口因该是黑的,除左上角光标外无任何显示。
按住Ctrl+C后插入棒子(如果棒子先插入了,这时就插入电源),此时窗口中是黑的没有回显跑码,所有输入都不会显示。但是操作成功的话已经停在Uboot了。
如果使用自制工具刷机,按住Ctrl+C后连接TTL模块和自制工具的VCC(3.3V)插针(如果VCC(3.3V)插针先连接了,这时就插入棒子),至于自制工具网上有教程,不在本文章讨论范围内。
一定要先按住Ctrl+C再进行插入操作,因为猫棒启动时的检测时间非常短,如果先插入再按太考验手速了,而且都是摸黑操作(窗口黑屏无任何信息显示),先按住成功率很高!
摸黑输入(或者可以用宏):
setenv bootdelay 5 #启动延迟5秒
setenv asc 0
setenv asc0 0
setenv preboot "gpio input 105;gpio input 106;gpio input 107;gpio input 108;gpio set 3;gpio set 109;gpio set 110;gpio clear 423;gpio clear 422;gpio clear 325;gpio clear 402;gpio clear 424"
setenv committed_image 0 #从分区0引导
saveenv #保存参数
输入这些变量以永久解锁引导加载程序。
有些商家已经刷好的棒子,很有可能已经进行了上述操作,棒子启动过程中可以回显所有启动信息,你就不需要上述操作了,不过商家为了棒子启动快一些,一般都会关闭回显和等待,自己刷完建议也可以这样做。
也有一些固件启动后会只回显U-Boot信息:
ROM: V1.1.4
ROM: CFG 0x00000006
ROM: SFLASH-4
hw fuse format 1
U-Boot 2011.12-lantiq-gpon-1.2.24 (Nov 03 2014 - 22:46:28), Build: falcon_sfp_linux
Board: SFP
DRAM: 64 MiB
Now running in RAM - U-Boot at: 83fc8000
SF: Detected W25Q128 with page size 4 KiB, total 16 MiB
然后就没有显示了,这样的棒子也需要进行上述操作。
上述操作完成后,插拔猫棒,如果上述操作成功会回显类似如下信息:
ROM: V1.1.4
ROM: CFG 0x00000006
ROM: SFLASH-4
hw fuse format 1
U-Boot 2011.12-lantiq-gpon-1.2.24 (Nov 03 2014 - 22:46:28), Build: falcon_sfp_linux
Board: SFP
DRAM: 64 MiB
Now running in RAM - U-Boot at: 83fc8000
SF: Detected W25Q128 with page size 4 KiB, total 16 MiB
Chip: FALCON-S (A22)
Bootmode: 0x06
Reset cause: Software
CPU Clock: 400 MHz
Net: SGMII, SERDES [PRIME]
gpio: pin 105 (gpio 105) value is 0
gpio: pin 106 (gpio 106) value is 1
gpio: pin 107 (gpio 107) value is 1
gpio: pin 108 (gpio 108) value is 1
gpio: pin 3 (gpio 3) value is 1
gpio: pin 109 (gpio 109) value is 1
gpio: pin 110 (gpio 110) value is 1
gpio: pin 423 (gpio 423) value is 0
gpio: pin 422 (gpio 422) value is 0
gpio: pin 325 (gpio 325) value is 0
gpio: pin 402 (gpio 402) value is 0
gpio: pin 424 (gpio 424) value is 0
Press SPACE to delay and Ctrl-C to abort autoboot in 5 seconds
此时uboot启动就会有5秒延迟等待,有充足的时间可以按Crtl+C中断启动。成功中断后,会有FALCON=>回显,如果回显的是FALCON => < INTERRUPT >,是因为Crtl+C没有及时松手或按多了,不碍事。
能否终止uboot启动,出现FALCON=>回显,是能否接下来操作的关键。
如果操作没有成功继续重复上述操作直到成功。如果还是不行,尝试更换usb口,3.0的口,2.0的口都试试;尝试更新模块驱动,不同模块兼容性不同,我是在Win11下用的CH340模块,可以说是很老的一个模块,驱动我用的是CH341SER.INF 01/18/2022, 3.7.2022.01,插得是usb3.1的口,完全没有兼容性问题;也可以尝试禁用或卸载其他所有COM口;也有可能是输入法影响Crtl+C的输入,尽量切回英文输入法,或者打开输入法兼容性;更换Tera Term软件版本、以管理员身份启动、设置软件兼容性;再不行就是重装系统;更换系统;更换电脑,总之全看你的人品,一般不会遇到这么恶略的情况,至少我没有遇到。
成功终止启动过程,显示FALCON=>回显以后,我们就可以准备开始刷固件了。
输入loadb 0x80800000(进入文件接收状态),准备从内存地址0x80800000处开始接收固件
点击Tera Term工具菜单中的文件->传输->Kermit->发送(注意不是文件->发送文件!!!),选择要刷的固件上传,过程持续10分到1小时不等,等待时间全看TTL模块的连接速度。
在弹出的对话框中选择要刷的固件然后点击打开,这时固件就开始传输。
注意!不要因为等待时间长就去干别的事,因为传输完毕后长时间不操作,猫棒会自动重启,之前传输的就白传输了!
传输完成后要尽快输入命令来写入固件,这里知识点比较多。除了命令以外,接下来更多的是针对命令本身作用的讲解。
固件传输完成后会显示如下回显信息:
FALCON => loadb 0x80800000
## Ready for binary (kermit) download to 0x80800000 at 115200 bps...
## Total Size = 0x00740000 = 7602176 Bytes
## Start Addr = 0x80800000
FALCON =>
接下来需要输入的刷机命令是:
sf probe 0
sf erase C0000 740000
sf write 80800000 C0000 740000
setenv committed_image 0
saveenv
每一行输入都需要等待运行完成后再输入下一行。
(推荐)也可以简化成下面这个样子一起输入:
sf probe 0&&sf erase C0000 740000&&sf write 80800000 C0000 740000&&setenv committed_image 0&&saveenv
这些命令具体作用是:
sf probe 0 #用于初始化spi flash
在使用sf read sf write之前,一定要调用sf probe
sf erase C0000 740000 #用于擦除spi falsh(image0分区)
擦除spi flash中 0xC0000 处 0x740000 长度的数据,擦除后内容全1
sf erase命令的作用是擦除指定位置,指定长度的flash内容,擦除后内容全1
sf write 80800000 C0000 740000 #用于将内存中的数据写入到设备falsh中(image0分区)
把内存地址0x80800000处0x740000长的的数据烧写到 flash的C0000偏移地址
刚才不是已经把固件接收到了这个内存地址处吗,现在要将内存中的固件写入到Flash中,至于为什么要写入到0xC0000这个偏移地址,下面我们会讲到。
setenv committed_image 0 #用于默认启动image0分区
很关键的参数,直接决定了系统从哪个分区启动,从不同分区启动会直接影响到分区结构和对应名称。至于什么是主要固件分区(image0)、备用固件分区(image1),下面我们会讲到。
saveenv #作用是将内存中的环境变量的值同步保存到Flash中环境变量的分区
这就是所有命令的作用,也可以在这些命令最后添加reset命令,这样刷完以后可以自动重启猫棒,省的拔插。
名词解释(SPI Flash):SPI是串行接口设备,flash是存储设备,可以理解为电脑的硬盘。spi flash 就是通过串行接口进行操作的flash存储设备,flash按照内部存储结构不同,分为两种:nor flash和nand flash。spi flash 属于nor flash,读写较慢,擦写次数有限制(10万次),一般用于不经常更改的存储,简单说就是刷多了不好。
名词解释(偏移地址):偏移地址就是计算机里的内存分段后,在段内某一地址相对于段首地址(段地址)的偏移量。
上述命令执行完毕后,猫棒就刷写完毕了。猫棒重启后(猫棒启动大约需要1分钟左右),将电脑ip设置为跟猫棒一个网段,用浏览器访问192.168.1.10,接下来就是猫棒的设置使用了,跟刷机没关系了,这里就不做介绍了。
刷写完固件的回显信息参考:
FALCON => sf probe 0&&sf erase C0000 740000&&sf write 80800000 C0000 740000&&setenv committed_image 0&&saveenv
SF: Detected W25Q128 with page size 4 KiB, total 16 MiB
SF: 7602176 bytes @ 0xc0000 Erased: OK
Saving Environment to SPI Flash...
SF: Detected W25Q128 with page size 4 KiB, total 16 MiB
Erasing SPI flash...Writing to SPI flash...done
Valid environment: 1
FALCON =>
下面解释下为什么这么刷,以及我刷被某些教程误导走的弯路!
首先是猫棒的官方固件默认分区(committed_image 0的情况下):
root@SFP:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00010000 "uboot"
mtd1: 00080000 00010000 "uboot_env"
mtd2: 00740000 00010000 "linux"
mtd3: 006191d8 00010000 "rootfs"
mtd4: 00400000 00010000 "rootfs_data"
mtd5: 00800000 00010000 "image1"
root@SFP:~#
这些是在SSH下使用cat /proc/mtd命令获取到的,可以看到猫棒默认分了6个区,mtd0至mtd5,名字列表后面都有写,我们分别说说每个分区的作用:
mtd0就是uboot分区,大小是0x40000,这个分区存储着uboot的启动文件,绝对不能动,勿刷绝对变砖!!
mtd1就是uboot_env分区,大小是0x80000,这个分区存储着SN序列号、MAC地址、光学校准配置等,这个分区一定要保证是原厂配置,否则猫棒不能用!!!
mtd2就是linux分区,大小是0x740000,这个分区存储着猫棒的固件,也是猫棒的主要固件分区(image0)。我们主要刷写的就是这个分区。
mtd5就是image1分区,大小是0x800000,这个分区同样存储着猫棒的固件,是猫棒的备用分区(image1)。通过环境参数committed_image可以决定猫棒从哪个分区启动,所以建议这个分区也刷入同样的固件。
现在猫棒的固件普遍具备web sysupgrade功能,通过网页刷新固件,其原理是,将新固件刷入image1分区,然后通过committed_image命令将启动分区设置为1,这样再启动就是新固件了,如果这时再次刷机,就会把固件刷回image0分区,再用committed_image命令将启动分区设置为0,循环往复。
“erasesize”是最小擦除大小,所有分区最小擦除大小都是0x10000,用不到,这里就不讲了,感兴趣可以去网上查。
还有诸如0x740000、0x800000这些地址范围,具体对应多少KB、MB的存储空间涉及内存地址换算,感兴趣的可以去网上查。猫棒分区中常用的大小及对应关系,我会在下面列出。
在猫棒启动过程中,TTL窗口中会跑码显示linux启动信息,其中也会出现分区信息,像是这样:
[ 0.288000] 0x000000000000-0x000000040000 : "uboot"
[ 0.292000] 0x000000040000-0x0000000c0000 : "uboot_env"
[ 0.300000] 0x0000000c0000-0x000000800000 : "linux"
[ 0.304000] 0x0000001e7f89-0x000000800000 : "rootfs"(不要在意这个分区)
[ 0.336000] 0x0000004b0000-0x000000800000 : "rootfs_data"(不要在意这个分区)
[ 0.344000] 0x000000800000-0x000001000000 : "image1"
从这里我们可以了解到各分区储存位置及大小:
uboot 分区的起始地址为0x00,分区大小是 0x40000 - 0x00 = 0x40000
uboot_env 分区的起始地址为0x40000,分区大小是0xC0000 - 0x40000 = 0x80000
linux 分区的起始地址为0xC0000,分区大小是 0x800000 - 0xC0000 = 0x740000
image1 分区的起始地址为0x800000,分区大小是 0x1000000 - 0x80000 = 0x800000
结合SSH中查询出的分区信息:
uboot 分区就是mtd0分区,分区大小是0x40000
uboot_env 分区就是mtd1分区,分区大小是0x80000
linux 分区就是mtd2分区,分区大小是0x740000
image1 分区就是mtd5分区,分区大小是0x800000
通过对应我们最终可以了解到:
uboot 分区= mtd0分区,起始地址为0x00,分区大小0x40000 = 256kb
uboot_env 分区= mtd1分区,起始地址为0x40000,分区大小0x80000 = 512kb
linux 分区= mtd2分区,起始地址为0xC0000,分区大小0x740000 = 7.25mb
image1 分区= mtd5分区,起始地址为0x800000,分区大小0x800000 = 8mb
全部相加正好是猫棒16mb的flash大小。
此外,我们还知道mtd2除了就是名叫linux的分区外,同时也是uboot环境变量中committed_image 0对应的分区,也就是说mtd2、linux、image0指的是同一个分区。
在反观刷写命令:
sf erase C0000 740000
其作用就是擦除image0整个分区
sf write 80800000 C0000 740000
其作用就是把内存地址0x80800000处0x740000长的数据烧写到image0分区中。
不管擦除还是写入都正好是image0分区的大小!
也有教程的写入命令是:
sf erase C0000 800000
sf write 80800000 C0000 800000
这是错的!错的!错的!这会把image1分区破坏掉!!!
这是我学习猫棒刷机,从网上找教程遇到的最大弯路,有教程把这个写入命令理解或误写成了写入image1分区,也就是备用分区的命令。这导致我刷写完成后一切换启动分区就出问题,这误导了我排除问题的思考方向!直到我搞懂了写入命令的实际工作原理!!
真正写入image1 备用分区的命令是:
sf erase 800000 800000
sf write 80800000 800000 800000
实在是耽误事,这也是逼着我搞懂上边写的那些知识点的根本原因,也是促使我写了这个学习笔记(教程)的罪魁祸首,其实也是因祸得福,毕竟学到了更多知识。
我这个人搞什么就学什么,不搞了,放下时间一长就忘了,所以要给自己写这么一个备忘用的笔记教程,好方便下次用的时候能快速捡起来。
接下来是一些与之相关的扩展知识:
存储空间与地址范围之间的换算:
0x是表示十六进制数的前缀, 0x0和0x00和0x0000都代表0,区别在于在存储空间上,0x0占的是4位,0x00占的是8位,0x0000占的是16位。(扩展:十六进制还会用H表示,0H,00H,000H)
地址范围0x40000 = 262144byte = 256kb
地址范围0x80000 = 524288byte = 512kb
地址范围0x400000 = 4194304byte = 4096kb = 4mb
地址范围0x740000 = 7602176byte= 7424kb = 7.25mb
地址范围0x800000 = 8388608byte = 8192kb = 8mb
地址范围0x8000000 = 10485760byte = 10240kb = 10mb
U-Boot是什么:
U-Boot属于bootloader的一种,是用来引导启动内核的,它的最终目的就是,从flash中读出内核,放到内存中,启动内核。它刚开始被放到flash上,然后上电以后先执行它,它会完成硬件初始化,设置处理器模式,关闭看门狗,屏蔽中断,初始化sdram,设置栈,设置时钟,从flash引导内核到内存,就好像我们PC上的BIOS一样(这段抄的网上的介绍)。
U-Boot有自己的Shell(与Windows/Dos下的批处理相似),可以通过命令脚本做许多事,TTL刷机用的就是U-Boot的命令,有兴趣更进一步可以去学习这些命令,除了刷机命令外,下面也会讲解一些用得到的其他命令。
U-Boot部分常用Shell命令:
printenv # 显示环境变量的值
setenv # 改变或增加环境变量
saveenv # 设置过变量后需要通过该命令保存
设置环境变量的例子
printenv bootdelay # 查看启动延迟当前设置的值
setenv bootdelay 5 # 设置启动延迟5秒,方便输入Crtl+C中断启动
saveenv # 保存启动延迟设定
“setenv” 也可以用于新建变量,用法和修改变量一样,如果环境变量里没有bootdelay,输入setenv bootdelay 5便可添加该变量,如果输入不带参数的setenv bootdelay便可删除。
[英文教程参考]https://forum.openwrt.org/t/support-ma5671a-sfp-gpon/48042/29
The module should have two images on the flash: active(0) at 0xC0000 and standby(1) at 0x800000
模块的flash闪存中有2个images分区:主要固件分区active(image0) 在 0xC0000; 备用固件分区standby(image1) 在 0x800000
If standby is also present, image1_is_valid=1
如果想让备用分区也有效,需要设置环境变量image1_is_valid=1
printenv image1_is_valid # 查看备用分区设置状态
setenv image1_is_valid 1 # 将备用分区设置为有效
saveenv
Make sure the active one is 0
确保活动分区为image0
printenv committed_image # 查看活动分区设置状态(默认启动哪个分区)
setenv committed_image 0 # 设置活动分区为image0(mtd2)分区
saveenv
如果想默认启动备用分区则设置为:
setenv committed_image 1 # 用于默认启动image1(mtd5)分区
saveenv
reset # 重启猫棒
更详细的U-Boot命令,感兴趣的可以去网上查。
刷机后分区工作方式分析(这部分很重要,建议详细阅读)
从主要固件分区(环境变量committed_image 0)启动后的分区结构:
SSH下使用cat /proc/mtd命令获取
mtd0: 00040000 00010000 "uboot"
mtd1: 00080000 00010000 "uboot_env"
mtd2: 00740000 00010000 "linux"
mtd3: 006191d8 00010000 "rootfs"
mtd4: 00400000 00010000 "rootfs_data"
mtd5: 00800000 00010000 "image1"
TTL下启动时跑码获取
[ 0.288000] 0x000000000000-0x000000040000 : "uboot"
[ 0.292000] 0x000000040000-0x0000000c0000 : "uboot_env"
[ 0.300000] 0x0000000c0000-0x000000800000 : "linux"
[ 0.304000] 0x0000001e7f89-0x000000800000 : "rootfs"
[ 0.336000] 0x0000004b0000-0x000000800000 : "rootfs_data"
[ 0.344000] 0x000000800000-0x000001000000 : "image1"
从备用分区(环境变量committed_image 1)启动后的分区结构:
SSH下使用cat /proc/mtd命令获取
mtd0: 00040000 00010000 "uboot"
mtd1: 00080000 00010000 "uboot_env"
mtd2: 00740000 00010000 "image0"
mtd3: 00800000 00010000 "linux"
mtd4: 006d8077 00010000 "rootfs"
mtd5: 00410000 00010000 "rootfs_data"
TTL下启动时跑码获取
[ 0.288000] 0x000000000000-0x000000040000 : "uboot"
[ 0.292000] 0x000000040000-0x0000000c0000 : "uboot_env"
[ 0.300000] 0x0000000c0000-0x000000800000 : "image0"
[ 0.304000] 0x000000800000-0x000001000000 : "linux"
[ 0.312000] 0x000000927f89-0x000001000000 : "rootfs"
[ 0.340000] 0x000000bf0000-0x000001000000 : "rootfs_data"
通过分析上面的分区结构我们可以看出,使用不同分区启动,分区名称和对应的mtd号会有所改变,但是主分区的偏移地址和大小不变,因此TTL刷机不受影响。但是在SSH下刷机,要看好mtd号和分区名称,避免刷错分区!
总结一下猫棒的分区结构和工作模式,我们可以分析得出猫棒完整的分区结构是:
主分区1:0x000000000000-0x000000040000 : "uboot"
主分区2:0x000000040000-0x0000000c0000 : "uboot_env"
主分区3:0x0000000c0000-0x000000800000 : "image0"
┗子分区:0x0000001e7f89-0x000000800000 : "rootfs"
┗子分区:0x000000??????-0x000000?????? : "rootfs_rom"(隐藏只读分区)
┗子分区:0x0000004b0000-0x000000800000 : "rootfs_data"
主分区4:0x000000800000-0x000001000000 : "image1"
┗子分区:0x000000927f89-0x000001000000 : "rootfs"
┗子分区:0x000000??????-0x000000?????? : "rootfs_rom"(隐藏只读分区)
┗子分区:0x000000bf0000-0x000001000000 : "rootfs_data"
如果将启动参数设置为committed_image 0,则主分区3由image0更名为linux,并在启动时加载及初始化子分区rootfs、rootfs_rom、rootfs_data,主分区4下不加载子分区。
如果将启动参数设置为committed_image 1,则主分区4由image1更名为linux,并在启动时加载及初始化子分区rootfs、rootfs_rom、rootfs_data,主分区3下不加载子分区。
换而言之image0、image1都是存放固件的分区,一个主要、一个备用,而rootfs是固件分区里的文件系统子集,rootfs_data是固件分区里的文件系统子集下的可写分区子集,rootfs包含在固件中,随固件一同刷入,rootfs分区包含只读(rootfs_rom)和可写(rootfs_data),rootfs_data分区就是rootfs中可写部分的位置,其中存储了你对猫棒做出的所有设置和修改的文件、安装的插件,恢复出厂设置也是清除此分区内的数据。
比如说你删除或替换了一个文件,rootfs_data就会记录你的操作,而你删掉或替换前的文件在rootfs_rom中依然保留有原始文件;你修改了一个设置,rootfs_data同样会记录你的操作,而出厂设置依然原封不动的保存在rootfs_rom中。
当需要读取文件和设置时,系统会先读取rootfs_data,再读取rootfs_rom。如果rootfs_data中有记录修改,则返回这个结果,如果rootfs_data中没有记录修改,则去读取rootfs_rom,返回rootfs_rom中的结果。
这样做的好处就是只要删除掉rootfs_data里的数据,就能达到复原的效果(恢复出厂设置),坏处是所有修改的文件,都会从rootfs_rom复制到rootfs_data里,所占用的空间会倍增(flash的空间足够大的话,这个坏处个人感觉可以忽略不记)。
另外,rootfs_data中的数据是以JFFS2文件系统格式化的,如果刷机后无法保存配置,是因为JFFS2分区也就是rootfs_data分区异常导致,一定要确保刷机时使用sf erase擦除了整个分区(如果使用SSH刷机要确保包含“-e”参数)。
刷完固件首次启动,建议等待1分钟左右,待系统重建完JFFS2分区后,再开始配置参数,如果连接着TTL,等全部跑码结束后再开始配置参数。
如果无法保存配置,还可以在Web管理页面里的“备份/升级”中恢复一下出厂,此操作只针对提供Web刷机功能的固件。
还有就是,由于嵌入式的flash容量很小,没有调整的必要,所以分区都是固定好的,也因此不需要"分区表"这种在计算机上有的东西。换句话说在猫棒的flash中,分区的位置都是固化好的。
固件备份及导出:
mtd0、mtd1分区很重要,勿刷了就会变砖,那我们要如何备份这些分区呢?
首先是mtd0分区,这个分区储存着uboot,这个分区要是刷坏了,TTL、SSH所有线刷都没救,只能用编程器,但前提也得是有备份。如果没有编程器及芯片焊接的本事,不要动!不要动!不要动!
再就是mtd1分区,这个分区上边提到了,存储着SN序列号、MAC地址、光学校准配置等,如果刷坏,猫棒无法工作。有备份的话,可以用TTL、SSH刷机方式恢复。
然后是image0、image1分区,这两个分区存放的都是固件,如果你买的是商家刷好的猫棒,建议先备份一下这里面的固件,商家固件跟网上免费下到的固件还是有一些区别的。
SSH下相对好备份一些,但不是所有固件都提供SSH。
TTL备份需要用到Tera Term的宏命令,以及PowerShell脚本。
以备份mtd1(uboot_env)分区为例,打开记事本将以下代码拷入:
; 启用日志自动关闭并获取当前工作目录。
logautoclosemode 1
getdir dir
; 查询gSerial以获取日志文件名。
sendln 'env print gSerial'
recvln
recvln
strsplit inputstr '=' 2
gSerial = groupmatchstr2
; 转存全部环境变量。
dumpName = 'env'
call setlog
wait 'FALCON => '
sendln 'env print'
wait 'FALCON => '
logclose
; 转存mtd1(uboot_env)
dumpName = 'mtd1'
mdAddress = 'B0040000'
mdSize = '20000'
call memdump
closett
messagebox '转存已完成' gSerial
end
:setlog
sprintf2 filename '%s\%s_%s.log' dir gSerial dumpName
logopen filename 0 0 1
return
:memdump
call setlog
sprintf2 mdCmd 'md.l %s %s' mdAddress mdSize
sendln mdcmd
wait 'FALCON => '
logclose
return
拷入上边这些代码后,将文件保存为backup_mtd1.ttl(保存时注意扩展名)
再打开记事本,将如下代码拷入:
$dumpFiles = Get-ChildItem -Filter "*_*.log"
foreach ($file in $dumpFiles)
{
$serial = $file.Name.Split('_')[0]
mkdir $serial -Force
mkdir "$serial\Log" -Force
mkdir "$serial\Bin" -Force
$noExtName = [IO.Path]::GetFileNameWithoutExtension($file.FullName)
$content = [IO.File]::ReadAllLines($file.FullName)
$cmd = $content[0].Substring(0,2)
$content = ($content | select -Skip 1 | select -SkipLast 1)
if ($cmd -eq 'md')
{
$byteArray = [byte[]]::new($content.Length * 16)
$arrayIndex = 0
foreach ($line in $content)
{
$lineData = ($line.split(' ') | select -Skip 1 -First 4)
foreach ($4bytes in $lineData)
{
foreach ($byteIndex in (6,4,2,0))
{
$byteArray[$arrayIndex] = [convert]::ToByte($4bytes.Substring($byteIndex, 2), 16)
$arrayIndex++
}
}
}
Set-Content "$($serial)\Bin\$($noExtName).bin" -Value $byteArray -Encoding Byte
} else {
Set-Content "$($serial)\Bin\$($noExtName).txt" -Value $content
}
mv $file.FullName "$($serial)\Log\"
}
拷入上边这些代码后,将文件保存为bin_convert.ps1(保存时注意扩展名)
新建文件夹,将backup_mtd1.ttl和bin_convert.ps1拷入,至于文件夹的名字看个人喜好。
接下来我们打开Tera Term 工具,连接好你的串口,设置好频率;
按住Ctrl+C,然后插入猫棒或者接通电源,等屏幕回显FALCON => 以后;
点击菜单里的控制-宏,选择backup_mtd1.ttl打开;
这时脚本将开始读取猫棒中的所有环境变量以及mtd1(uboot_env)分区,并在你刚刚新建的用于存放backup_mtd1.ttl的目录中转存两个以你猫棒设备名称为开头的log日志文件,分别是XXXXX_env.log和XXXXX_mtd1.log,转存过程很长(备份mtd2基本用时在50分钟),会有跑码,转存完成后会有提示窗口。
然后我们右键bin_convert.ps1文件,选择使用PowerShell运行,运行过程中会有命令行窗口,运行结束后文件夹里会多出一个以你猫棒设备名命名的文件夹,转换好的XXXXX_mtd1.bin文件就在bin文件夹下。
同时bin文件夹下还会有一个叫做XXXXX_env.txt的文件,这个文件里保存的是猫棒里的所有环境变量。
如果想备份mtd0(uboot)分区,则需要将backup_mtd1.ttl文件中的
; 转存mtd1(uboot_env)
dumpName = 'mtd1'
mdAddress = 'B0040000'
mdSize = '20000'
call memdump
这一段内容替换为
; 转存mtd0(uboot)
dumpName = 'mtd0'
mdAddress = 'B0000000'
mdSize = '10000'
call memdump
如果想备份image0分区,则替换为
; 转存mtd2(image0)
dumpName = 'mtd2'
mdAddress = 'B00C0000'
mdSize = '1D0000'
call memdump
如果想备份image1分区,则替换为
; 转存mtd5(image1)
dumpName = 'mtd2'
mdAddress = 'B0800000'
mdSize = '200000'
call memdump
常用的分区如何备份这里就说完了,下面我们说说mdSize的值和存储空间的对应关系:
从这个表里mdSize的对应关系和换算方法一目了然。
TTL备份固件的方法到这里就讲完了,建议将备份好的bin文件改一下名,添加上uboot_env、image0、image1这些标注,毕竟如果你的猫棒默认启动分区设置的是image1的话,image1分区所对应的是mtd3,而不是mtd5。加上标注可以避免刷机过程中因为文件名混淆导致的错误。
串口、COM口、TTL:
串口就是COM口,全称是cluster communication port ,串行通讯端口。是指计算机或一些电子设备上的D-SUB外形(一种9针连接器结构)的物理串行通信接口。
而TTL指的是电平标准(电信号),TTL信号标准是低电平为0,高电平为1(+5V电平)。除了TTL以外还有RS-232、RS-485电平标准。电脑上的D-SUB外形的串口只有RS-232和RS-485这两种协议)。
从某种意义上,可以说线路上存在的仅仅是电流,而这些“电平标准”规定了电流在什么样的线路上流动和流动的样式;通过串口收发的逻辑电路UART,通用异步收发器(Universal Asynchronous Receiver/Transmitter),电流才被解释和组装成数据,并变成CPU可直接读写的形式。
FT232RL、CH341、CH340、PL2303、CP2102这些芯片都是USB转TTL串口的芯片,使用这些芯片制作的USB转TTL串口模块,可以使用USB来为电脑扩展串口(TTL电平)。
接设备的时候,一般只接GND RX TX。不会接Vcc或者+3.3v的电源线,避免与目标设备上的供电冲突。
其他事项:
固件跟跟固件不同,尝试TTL刷新固件时,最好只刷主要固件分区(image0),确定固件没问题后再刷image1备用分区,有些固件不支持切换分区,或者直接在环境变量中image1_is_valid 0禁止了image1备用分区。
.bin固件、.image固件有何区别?没区别!!
发现一个奇怪的问题,
基于新版固件修改版_2022.08.25
huawei-ma5671a_new_busybox-squashfs.image
通过TTL刷机后,在爱快下与博通BCM57810网卡无法握手,
而使用SSH再刷一遍便可解决!!!?
又或许要先刷入
HUAWEI_MA5671A基于牛奶_修改版_2022.04.13
huawei_ma5671a_optic_1224-squashfs.image
再一点一点升上来!?
其他事项:
setenv bootdelay 5
setenv asc 0
setenv asc0 0
setenv preboot "gpio input 105;gpio input 106;gpio input 107;gpio input 108;gpio set 3;gpio set 109;gpio set 110;gpio clear 423;gpio clear 422;gpio clear 325;gpio clear 402;gpio clear 424"
printenv bootdelay
setenv bootdelay 5
printenv asc
printenv asc0
printenv committed_image
setenv committed_image 0
setenv committed_image 1
saveenv
reset
SSH刷机(MA5671A):
TTL刷机中,我们已经讲了关于猫棒的相关基础知识,这些都明白以后SSH刷机就简单了,首先不是所有固件都支持SSH,所以SSH刷机通用性不高,但有些操作相对TTL要简单省时,毕竟SSH是通过网线,速率要比TTL快的多。
SSH刷机我们用到的工具主要是MobaXterm,一定要使用正式版,怎么注册自己想办法,否则功能限制太多,根本没法用,我用的是MobaXterm 22.1版。
首先,U-Boot不支持SSH,只有Openwrt固件支持,也就是固件系统启动完毕以后才能进行SSH刷机,至于能不能刷要看猫棒里的固件,目前网上可以下到的大多都支持SSH。
具体能不能支持登录一下Web后台查看一下“系统”菜单下的“管理权”就知道了,有的固件连“管理权”都没有提供,支持不支持SSH就更不好说了。另外毕竟有商家在做猫棒的生意,不开放SSH也在情理之中。
TTL刷机主要讲的是从主分区启动(committed_image 0)以后的操作,SSH刷机我们就以从备用分区启动(committed_image 1)为例。
首先我们用网线将光纤收发器和电脑网卡连接,SSH刷机也要用到光纤收发器,即便不刷机,想要用猫棒,光纤收发器是不可能不买的,除非你有带SFP口的交换机或网卡,如果没有,光纤收发器是最廉价的使用猫棒的方法,所以TTL刷机一开始就推荐购买带TTL接口的收发器。
将电脑网卡的ip地址设置成跟猫棒一个网段,比如192.168.1.2,子网掩码255.255.255.0,网关可以设也可以不设192.168.1.1,如果你的电脑还有其他网卡,检查你电脑的其他网卡所联入的网络是不是同样是此网段,如果是建议禁用掉网卡或拔掉网线,如果是无线网卡,断开连接,避免发生不必要的冲突。
将猫棒插入收发器,接通电源,等待猫棒启动完成后,使用MobaXterm软件,通过SSH登录猫棒系统。具体操作是点击右上角会话图标会弹出如下界面,远程主机填入192.168.1.10,指定用户名root(不同固件不同)。
点击确认按钮(ok),会关闭此窗口返回主界面,我刷的固件没有设置密码,这里就直接登录了,通过下图可以看到,左侧窗口显示出了猫棒的文件列表,右侧是命令行窗口。
这个就是SSH刷机的优势,所有文件可以直接在列表里操作,无需复杂的命令。
我们输入cat /proc/mtd命令,如果返回下列结构就说明猫棒是用备用分区启动的。
从备用分区committed_image 1启动后的分区结构:
root@HUAWEI:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00010000 "uboot"
mtd1: 00080000 00010000 "uboot_env"
mtd2: 00740000 00010000 "image0"
mtd3: 00800000 00010000 "linux"
mtd4: 006d8077 00010000 "rootfs"
mtd5: 00410000 00010000 "rootfs_data"
root@HUAWEI:~#
SSH备份固件:
刷机前,我们先备份一下固件,以备不时之需。
逐一输入下列命令:
cat /dev/mtd0 > /tmp/mtd0.bin
cat /dev/mtd1 > /tmp/mtd1.bin
cat /dev/mtd2 > /tmp/mtd2.bin
cat /dev/mtd3 > /tmp/mtd3.bin
cat /dev/mtd4 > /tmp/mtd4.bin
cat /dev/mtd5 > /tmp/mtd5.bin
然后从设备的/tmp目录,将5个文件备份到本地电脑(建议一个文件一个文件的备份,备份到电脑以后,删除掉猫棒/tmp目录下生成的.bin文件后再备份下一个,因为猫棒空间有限,同时放不下这5个文件)。
在左侧窗口中找到tmp目录下生成的.bin文件,然后右键下载(也可以点击窗口上方蓝色向下箭头横线的图标)。
选择要保存的位置,确定。
等待文件下载到电脑就完成了备份(备份完成后别忘了右键删除tmp目录下的.bin文件)。
另外如果你使用的MobaXterm是免费版,下载文件会卡住不动,无法下载。
除了使用MobaXterm软件备份,也可以使用MobaXterm备份,具体操作是:
新建TCP/IP连接,主机输入192.168.1.10,点击确认在弹出的SSH认证窗口中输入用户名和密码点击确定(我的固件用户名是root,没有密码)。
然后,没有问题的话就连上了,接下来的操作跟在MobaXterm软件中是一样的,查看一下分区结构,输入命令在tmp目录下生成.bin备份文件。
接下来我们将导出的.bin文件备份到本地电脑,具体操作是点击菜单中的文件 - SSH SCP,在弹出窗口的虚线下部,from: "/tmp/你要备份的.bin",to: "浏览一个文件夹",点击Receive按钮。
这时便开始从tmp目录中下载固件到本地计算机。
进度条走完以后固件就备份到了本地,不得不说还是SSH快。
备份完记得删除tmp目录下生成的.bin文件。
rm /tmp/mtd1.bin
SSH恢复(刷入)固件:
使用MobaXterm软件,通过SSH登录猫棒系统。
在左侧文件列表中选择tmp目录双击进入。点击上方绿色横杠向上箭头图标,然后在打开的窗口里选择想要输入的固件文件。
等进度条走完以后固件就上传到了tmp目录中。
除了使用MobaXterm软件上传,也可以使用Tera Term上传,具体操作是击菜单中的文件 - SSH SCP,在弹出窗口的虚线上部,from: "浏览想要上传的固件",to: "/tmp/固件名.bin",点击Receive按钮。
等进度条走完以后固件就上传到了tmp目录中。
传输完毕后输入刷机命令:
cat /tmp/mtd1.bin > /dev/mtd1 && reboot
刷完之后猫棒会自动重启(reboot的作用)。
刷机过程中的回显信息:
root@HUAWEI:~# mtd write -r /tmp/mtd1.bin /dev/mtd1
Unlocking /dev/mtd1 ...
Writing from /tmp/mtd1.bin to /dev/mtd1 ...
Rebooting ...
SSH刷机教学完毕!!!
接下来是一些与之相关的扩展知识:
多种备份和刷机命令:
备份时还可以用如下命令,.bin也可以用分区名命名(看个人喜好):
dd if=/dev/mtd0 of=/tmp/uboot.bin
dd if=/dev/mtd1 of=/tmp/uboot_env.bin
dd if=/dev/mtd2 of=/tmp/image0.bin
dd if=/dev/mtd3 of=/tmp/linux.bin
刷机时还可以用如下命令:
dd if=/tmp/mtd3.bin of=/dev/mtd3&& reboot
或者
mtd -r write /tmp/mtd3.bin /dev/mtd3
mtd -r write /tmp/mtd3.bin linux
不过更推荐使用
mtd -e linux write /tmp/mtd3.bin linux
# -e擦除linux分区内全部数据、将tmp目录下的mtd3.bin写入linux分区
之所以推荐,是因为擦除一遍分区内的全部数据,可以有效的避免JFFS2分区也就是rootfs_data分区异常,导致的无法保存配置问题。
至于为什么备份和写入有这么多命令可用,是因为cat是操作文件,因为Linux系统一切皆文件,所以cat才可以,dd是操作磁盘,mtd是专门操作flash,命令不同,但是能产生相同效果。
我个人习惯用
dd if=/dev/mtd3 of=/tmp/image1.bin #备份
mtd -e linux write /tmp/image1.bin linux #刷机
其他常用SSH命令:
设置uboot的env (在SSH下设置uboot的env)
fw_setenv bootdelay 5 #启动延迟5秒
fw_setenv asc 0
fw_setenv preboot
fw_setenv committed_image 0 #从主要固件分区启动
fw_setenv committed_image 1 #从备用固件分区启动
fw_printenv #查看uboot环境变量
fw_printenv bootdelay
fw_printenv asc
fw_printenv preboot
fw_printenv committed_image
reboot #重启猫棒
mtd命令参数:
root@HUAWEI:~# mtd ?
用法: mtd [<选项> ...] <命令> [<参数> ...] <设备>[:<设备>...]
设备的格式为mtdX(例如:mtd4)或其标签
mtd可用以下命令:
unlock 解锁设备
refresh 刷新mtd分区
erase 清除设备上的所有数据
verify <镜像文件>|- 校验<镜像文件> (use - for stdin) 到设备
write <镜像文件>|- 写入<镜像文件> (use - for stdin) 到设备
jffs2write <文件> 将 <文件> 追加到设备上的 jffs2 分区
以下选项可用:
-q 安静模式(一次:写入时无[w],两次:无状态消息)
-n 在不先擦除块的情况下写入
-r 命令成功后重新启动
-f 强制写入而不进行trx检查
-e <设备> 执行命令前擦除<设备>
-d jffs2write的目录,默认为“tmp”
-j 写入镜像时将<文件>集成到 jffs2 数据中
-s 将数据追加到jffs2分区时跳过前n个字节,默认为“0”
-p 从分区偏移开始写入
例子:将linux.trx写入到标签为linux的mtd4分区,然后重启
mtd -r write linux.trx linux
SSH常用命令汇总:
cat /proc/mtd
fw_printenv
fw_printenv bootdelay
fw_setenv bootdelay 5
fw_setenv asc 0
fw_setenv preboot
fw_printenv committed_image
fw_setenv committed_image 0
fw_setenv committed_image 1
dd if=/dev/mtd3 of=/tmp/image1.bin #备份
mtd -e linux write /tmp/mtd3.bin linux #刷机
mtd -r -e linux write /tmp/mtd3.bin linux #刷机后重启
mtd -r -e image0 write /tmp/mtd3.bin image0
Reboot
其他相关知识:
接收光功率:
-10到-18 很好
运营商标准-20
-20 到-24 一般正常
-25勉强能用
-26快断网了
-27 基本快断网了
测试原版固件:
ssh root@192.168.1.10 admin123
华为的Shell,不完整,除了版本号什么都干不了,可用命令:
display_version
dmesg
mtd
root@SFP:~# display_version
OMCI daemon v7.5.1(Compiled on May 15 2018 15:09:43)
software_Version=V8R017C00S207, internal_version =V800R017C00SPH207B001, 1620-00801-00-00-0011-01
root@SFP:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00010000 "uboot"
mtd1: 00080000 00010000 "uboot_env"
mtd2: 00740000 00010000 "linux"
mtd3: 006191d8 00010000 "rootfs"
mtd4: 00400000 00010000 "rootfs_data"
mtd5: 00800000 00010000 "image1"
mtd2=image0 mtd5=image1
原创:该教程由宅人改造家研究整理,转载时请注明出处!