如何恢复 ART 分区
备份 ART 数据! 备份 ART 数据! 备份 ART 数据!
ART数据不通用,不要在别的路由器上使用
当前大多数路由器的 ART 数据都是针对该设备“量身定制”的,其中包含射频校准信息。
即使你的路由器看起来能正常工作,实际上很可能性能不佳,甚至超出无线规范允许的范围。
这种“超规格”运行不仅可能违法,还可能干扰你自己或邻居的其他无线设备。
另外请注意:文中提到的工具不适用于基于 NAND 闪存的路由器,若强行使用,可能会造成更严重的损坏。
已在 Netgear WNDAP360 和 BUFFALO WZR-HP-AG300H 上测试通过
请务必确认你的设备 ART 分区偏移地址是否相同!(可通过核对 MAC 地址验证)
我在折腾自己的路由器时,不小心弄坏了 ART 分区。
如果 ART 分区被擦除或损坏,ath 无线模块将无法启动。
ART 分区中存储的是射频校准数据。如果你之前没有备份自己的 ART 数据,恢复后无线性能可能不如从前(不过我觉得,比完全不能用强 )。
前提条件
最理想的情况是你已经备份过自己的 ART 分区。这在 OpenWrt 系统或某些基于 Linux 的原厂固件中很容易做到(前提是你可以通过命令行访问设备)。 在设备上查找 ART 分区:
cat /proc/mtd
找到 art 或 ART (例如我的是 mtd5) 然后执行以下命令备份:
dd if=/dev/mtd5 of=/tmp/art.backup
通过 SSH 或其他方式将这个备份文件复制到你的电脑上。
如果你已有自己的备份,请直接跳到 将 ART 分区刷回设备 部分;如果没有……那你可能需要一点运气,还得多花些功夫。
修改 ART 分区中的 MAC 地址
如果你没有自己的 ART 备份,就需要找一个和你设备型号完全相同的用户提供的 ART 文件(我没试过用不同型号的 ART 文件,不建议这么做)。由于 MAC 地址就保存在这个分区里,你需要修改它。
注意: ART 分区中某些区域有校验和(checksum),根据 ath9k 驱动的要求,这些校验和必须为 0xffff。如果校验错误,无线模块将无法启动。
在电脑上用你喜欢的十六进制编辑器(我用的是 ghex)打开 ART 备份文件(比如叫 art.backup)。
我的设备有两个无线模块,所以有两个 MAC 地址和两个校验和。修改方法如下:
2.4GHz 无线(radio0):跳转到偏移地址 0x120c,将 MAC 地址改成你自己的(注意:只改这 6 个字节,别多动!)。
5GHz 无线(radio1):跳转到偏移地址 0x520c,同样改成你自己的 MAC(我通常在 2.4GHz 的 MAC 基础上加 1)(同样,只改这 6 个字节!)。
现在,你需要擦除原有的校验和,跳到 0x1202(radio0),将这两个字节改为 FF FF;跳到 0x5202(radio1),同样改为 FF FF。
保存文件,然后刷入你的 ART 分区(具体方法见下一部分)。
重启路由器后,WiFi 接口不会正常启动,因为校验和错误。你会在控制台或日志(dmesg / logread)中看到类似这样的提示:'Bad EEPROM checksum: 0xad22'
记下两个无线模块各自的校验和值(比如 0xad22)。
回到十六进制编辑器:在 0x1202 处填入 radio0 的校验和(比如 AD 22);在 0x5202 处填入 radio1 对应的校验和。
保存文件,重新刷入路由器,现在你的 WiFi 就能正常工作,并且使用正确的 MAC 地址了!
将 ART 分区刷回设备
如果 ART 分区不是只读的,可以直接从操作系统层面刷写。
如果分区是只读的,你可以选择以下方法之一:
- 安装或编译内核模块 kmod-mtd-rw 然后运行命令临时启用写入权限:“insmod mtd-rw.ko i_want_a_brick=1”
- 或者修改 OpenWrt 源码中的分区定义,重新编译内核。
- 或者通过 U-Boot 刷写(见下文)。
通过 OpenWrt 刷写
操作很简单:把你的 ART 备份文件放到路由器的 /tmp 目录下,然后执行:
mtd -r write /tmp/art.backup art
该命令会在刷写完成后自动重启设备,这是必需的。
如果你的 ART 分区是只读的,又没有串口控制台,那就需要修改 OpenWrt 源码中 images/Makefile 里的分区定义,重新编译固件并刷入。 也可以使用 kmod-mtd-rw 内核模块,无需重新编译即可写入 ART。 强烈建议:修复 ART 分区后,立即刷回一个正常的、将 ART 设为只读的固件,以避免后续误操作。
通过 U-Boot 刷写
重要警告 此处操作失误可能导致设备永久变砖!!
如果你有可用的串口控制台,且 ART 分区为只读(大多数情况都是),可以考虑通过 U-Boot 操作。具体步骤因路由器型号略有不同,但总体流程如下:
准备工作: 先确认 ART 分区在闪存中的起始地址。查看 dmesg 或 logread,你会看到类似这样的分区信息:
0x000000000000-0x000000040000 : "u-boot" 0x000000040000-0x000000050000 : "u-boot-env" 0x000000050000-0x000000200000 : "kernel" 0x000000200000-0x0000007f0000 : "rootfs" 0x0000003f0000-0x0000007f0000 : "rootfs_data" 0x0000007f0000-0x000000800000 : "art" 0x000000050000-0x0000007f0000 : "firmware"
在我的设备(Atheros AR7161)上,ART 起始于: 0x0000007f0000 。在 U-Boot 中,这个地址通常要加上平台基址:
0xbf7f0000
你需要一个配置好的 TFTP 服务器,IP 地址需与 U-Boot 中的 serverip 一致(可在 U-Boot 中用 printenv 查看)
查看内存起始地址:
bdinfo
假设结果是:
0x80000000
现在,从 TFTP 下载 ART 文件到内存:
ar7100> tftpboot 0x80000000 art.backup Trying eth0 Using eth0 device TFTP from server 192.168.1.1; our IP address is 192.168.1.2 Filename 'art.backup'. Load address: 0x8000000 Loading: ################################################################# done Bytes transferred = 65536 (10000 hex)
注意最后显示的文件大小:10000 hex
接下来,擦除 ART 分区中原有内容(使用前面查到的起始地址和文件大小-前加 +0x):
erase 0xbf7f0000 +0x10000
最后,将内存中的数据写入闪存(基础用法:cp.b <内存中的起始位置> <闪存中的目标位置> <数据长度 - 使用与上述相同的大小但不带+号):
cp.b 0x8000000 0xbf7f0000 0x10000
完成!