AI的出现加上工作繁忙,博客从月更变成年更了,新年第一个需要记录的事是给车库的Aqara M1S 2022网关刷上自定义固件。前因是车库的外网用的是一个4G上网卡,关上车库门后,外网丢包率很高,但是Aqara这个网关有个逆天的逻辑,这种情况下一段时间后会断开外网链接,不再尝试连接米家,临时的解决方法是装了一个智能插座,每天重启2次网关,要彻底解决这个问题需要刷上自定义固件从局域网连接(经由外网隧道,虽然丢包率高,但是网确实还是通的)。
前置准备
前置知识
M2网关和M2 2022网关用的是两个芯片,后者根S1E用的是同一个SOC,二进制程序需要选择正确
所需工具
一个U型2.0mm螺丝刀,用于网关拆机
USB转串口模块
测试夹或焊接工具,推荐前者吧,我手残焊了1一小时
良好的网络环境,需要把梯子做在路由器上,因为需要联网下载固件,当然你可以自己改脚本从本地下载
前置工作
切换到Aqara模式
连接UART口至电脑,引脚可参考下图,从按钮开始数依次为,GND(存疑),TX,RX
串口工具打开,波特率115200
连接电源地板并上电,终端有看到数据后进入下一步
刷机
不停按回车,并重新上电
观察uboot是否已经中断
查看当前bootargs,把init=/linuxrc改为init=/bin/sh
1 2 3
printenv bootargs ubi.mtd=UBI,2048 root=/dev/mtdblock6 rootfstype=squashfs ro init=/linuxrc LX_MEM=0x3FE0000 mma_heap=mma_heap_name0,miu=0,sz=0x200000 cma=2M mmap_reserved=fb,miu=0,max_start_off=0x3300000,max_end_off=0x3600000 mtdparts=nand0:1536k@1280k(BOOT0),1536k(BOOT1),384k(ENV),128k(KEY_CUST),5m(KERNEL),5m(KERNEL_BAK),16m(rootfs),16m(rootfs_bak),1m(factory),-(UBI)
设置bootargs并启动
1 2
setenv bootargs ubi.mtd=UBI,2048 root=/dev/mtdblock6 rootfstype=squashfs ro init=/bin/sh LX_MEM=0x3FE0000 mma_heap=mma_heap_name0,miu=0,sz=0x200000 cma=2M mmap_reserved=fb,miu=0,max_start_off=0x3300000,max_end_off=0x3600000 mtdparts=nand0:1536k@1280k(BOOT0),1536k(BOOT1),384k(ENV),128k(KEY_CUST),5m(KERNEL),5m(KERNEL_BAK),16m(rootfs),16m(rootfs_bak),1m(factory),-(UBI) run bootcmd
挂载基础分区,这些命令执行后,不会执行fw_manager.sh,后者会把UART输出给干掉,获得一个临时的shell
1 2 3 4
mount -t ramfs ramfs /var; mkdir /var/tmp cp /etc/init.d/rcS /var/tmp/rcS sed -i 's/fw_manager.sh -r/echo skip/g' /var/tmp/rcS /var/tmp/rcS
联网,现在是没有网络的,找了很多办法,wifi_start.sh始终没有办法连上Wi-Fi,这里想了一个曲线救国的办法,把fw_manager.sh中屏蔽UART输出的逻辑给屏蔽掉,阅读启动脚本/linuxrc会调用/etc/init.d/rcS也就是上面改的脚本,fw_manager.sh中依次调用main()->runner()->run_prepare(),这里只需要设置两个prop就可以bypass掉屏蔽UART掉相关逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
run_prepare() { local check_mdnsd=`pstree | grep mdnsd` local check_mosqu=`pstree | grep mosquitto` local entry_facmd=`agetprop persist.sys.factory_result` local uart_enable=`agetprop persist.app.tty_enable` local debug_flag=`agetprop persist.app.debug_log` if [ "$check_mdnsd" = "" ]; then mdnsd ;fi if [ "$check_mosqu" = "" ]; then mosquitto -d ;fi wait_property_svr_ok check_zigbee_ota if [ ! "$entry_facmd" = "true" ]; then /usr/factory_test/bin/start_fac.sh exit 0 fi # Disable Uart. if [ "$uart_enable" != "true" -a "$debug_flag" != "true" ] ;then echo "enable tty" fi }
1 2
asetprop persist.app.tty_enable true asetprop persist.app.persist.app.debug_log true
重启网关,应该能正常执行完初始化,并连接上Wi-Fi,同时串口也得到了保留
下载curl,这里需要用S1E的二进制程序
1
cd /tmp && wget -O /tmp/curl "http://master.dl.sourceforge.net/project/aqarahub/binutils/curl?viasf=1" && chmod a+x /tmp/curl
刷自定义固件,我这里中间内核报错了,看着像OOM了,没管,最后刷机成功了
1 2
/tmp/curl -s -k -L -o /tmp/m1s22_update.sh https://raw.githubusercontent.com/niceboygithub/AqaraCameraHubfw/main/modified/M1S22/m1s22_update.sh chmod a+x /tmp/m1s22_update.sh && /tmp/m1s22_update.sh
重启后telnet应该自动打开,可以去Home Assistant的Aqara Gateway集成上添加网关了
参考文献