某些技术 2008-04-09 21:54:20 阅读4659 评论26 字号:大中小 订阅
尽管在国外有一些闲置的服务器, 但是却不敢拿来建网站。网站这种应用出境率太高, 即使像 fr_eebsd.org 这种良民, 被 GF\/\/ 也是很容易的事情。到时候不仅 $ 打水漂, 可恨连 VPN 都用不了, 上网只能戴套, 实在是划不来。
于是乎我决定利用 ADSL/HTTB 带宽建站。至于服务器, 实在不想和豆瓣的阿北一样用笔记本来做, 一方面耗电, 另一方面笔记本常有爆炸事件, 不敢在无人职守的情况下超长待机。故决定使用 NAS (网络存储服务器, 网盘) 来做。
这里性价比最高的是 Buffalo 的 Linkstation 网盘, 首选的是 LinkStation HD-H120LAN120G 这个型号, 居然拥有高达 400M 的 MIPS CPU 以及 64M 的巨量内存 (耗电 20W 左右)。当然非常不幸的是, LS 120G 全上海断货, 而且奸商奇货可居哄抬物价, 这令 Cr@cker 非常不爽。
最终这直接导致了我选用路由器这种 "难民级" 设备来建站, 鸟枪变炮。于是就有了这篇文章。
当然也会有少数人不理解, 路由器怎么可以拿来做网站呢? 是啊, 你一两百块钱买过来的这个小盒子尽管便宜, 却也是一台完整的高性能计算机了, 除了没有显示器和鼠标键盘。当然啦, 只要你愿意, 加个诸如摄像头或者声卡什么的外设还是可以的。
大部分的路由器的固件都是可以重新刷过的, 诸如 LinkSys、D-Link、Buffalo、Netgear、ASUS 这些品牌的路由器都在著名固件 "OpenWrt" 支持之列。这里有一份详细的 支持列表, 请先查阅。
经过研究, 我觉得 ASUS 系列的路由器较为实惠。首选 ASUS WL-HDD 这款 "网络硬盘盒", 他的特点是比起一般的路由器多一个 2.5 IDE 硬盘接口以及一个 USB 1.0 接口, 可以加装一块硬盘和 USB 盘用于存放网站数据。
其次是 ASUS WL-500b (可以升级到 WL-500g) 和 ASUS WL-500g 路由器, 他们使用和 WL-HDD 一样的硬件, 也带有一个 USB 1.0 接口。使之同样成为建站和网络打印服务器的首选。
WL-HDD/500b/500g 售价都在一两百元上下, WL-HDD 稍贵, 我在上海以 248¥ 拿到的货。他们的硬件配置都是 MIPS BCM4702 125MHz CPU、16MB SDR 32bit 内存和 4M 闪存 (耗电 10W)。
另一个版本 WL-500gP 稍贵, 拥有 200MHz CPU, 著名改*机网站 "数&位天堂" 就是构建于 ASUS-WL-500gP 之上。网站上有 WL 全系列硬件配置表, 若要选购以作改机之用, 可以参考。
下面专为 ASUS 的 OLEG 固件开辟一节, 未在其他硬件上测试过, 其他路由器用户可快速掠过, 去到 OpenWrt 固件部分。
固件 (Firmware, 韌體) 被保存在路由器闪存中, 通常是一个完整的 Linux 操作系统。将路由器原固件改成自定义固件, 可以实现在原有路由器功能上增删定制任意自己想要的功能, 就像是操作一台完整的电脑一样。
刷新固件, 常用于使路由器自动下载 BT、绕过 ISP (诸如网xx通、电yy信) 的多a用b户c共d享e限f制, 绕过 ISP 的 DNS 域a名b劫c持d等流_氓行为。这里就不详加讨论了, 请诸位自己找资料。
OLEG 是 "数位天*堂" 选用的固件, 是通过 ASUS 官方固件修改而来。门槛较低, 兼容性高, 这里推荐初级 ASUS 用户使用。下面是刷机步骤。
1. 造访 http://oleg.wl500g.info/ , 下载最新的固件 (WL-HDD 用户请下载 1.9.2.7-9 及以前的版本, 其后版本不支持 WL-HDD)。
2. 解压缩 WLxxx-1.9.2.x-x.zip 得到 trx 文件。
3. 访问自己的路由器地址 http://192.168.1.1 (WL-HDD 是 http://192.168.1.220, 推荐使用直接的网线连接而不是无线方式), 登录后找到 "System Setup" 的 "Firmware Upgrade" 项, 上传 trx 文件。
4. 稍候片刻, 等待机器自动重启。
重启后会再次进入管理界面, 设置用户名。这样你就可以通过 telnet 来登入路由器了 (密码: admin)。哇噻, 我的到了一个 Linux Shell!
接下来接入 USB 盘或者插上 IDE 盘, 如果不喜欢命令行的 fdisk 工具, 可以先使用其他工具分区格式化再接入 ASUS WL 设备。然后执行 "fdisk -l", 下面是在我机器 (WL-HDD) 上的显示。
Disk /dev/ide/host0/bus0/target0/lun0/disc: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/ide/host0/bus0/target0/lun0/part1 1 14395 115627806 83 Linux
/dev/ide/host0/bus0/target0/lun0/part2 14396 14461 530145 82 Linux swap
/dev/ide/host0/bus0/target0/lun0/part3 14462 14527 530145 82 Linux swap
/dev/ide/host0/bus0/target0/lun0/part4 14528 14593 530145 82 Linux swap
接下来就是挂接硬盘 (当然, 如果对原装的 4M flash 有信心, 也可以不加硬盘撒):
# mount /dev/ide/host0/bus0/target0/lun0/part1 /opt
# swapon /dev/ide/host0/bus0/target0/lun0/part2
# swapon /dev/ide/host0/bus0/target0/lun0/part3
# swapon /dev/ide/host0/bus0/target0/lun0/part4
安装 ipkg (硬盘/U 盘已经加载置 /opt 目录):
# mkdir /opt/tmp
# mkdir /opt/tmp/ipkg
# wget http://ipkg.nslu2-linux.org/feeds/optware/oleg/cross/stable/ipkg-opt_0.99.163-9_mipsel.ipk
ipkg.sh install ipkg-opt_0.99.163-9_mipsel.ipk
# wget http://ipkg.nslu2-linux.org/feeds/optware/oleg/cross/stable/uclibc-opt_0.9.28-13_mipsel.ipk
# ipkg.sh install uclibc-opt_0.9.28-13_mipsel.ipk
# ipkg update
这样我们就可以像使用 debian apt-get 一样直接通过 "ipkg install xxx" 来安装已经编译好的二进制程序了。
在 http://ipkg.nslu2-linux.org/feeds/optware/oleg/cross/stable/ 位置拥有大量的 ipk 文件, 这些都是 ipkg 包, 实际上, 我们大可不必使用 ipkg 程序来安装这些软件。
ipk 文件实际上是 tgz 格式的, 解包后会得到 data.tar.gz 和 control.tar.gz 两个 tgz 文件 (tgz 套着 tgz? 貌似很奇怪的样子), 而 data.tar.gz 就是二进制程序结构。使用解包的 data.tar.gz 文件, 可以提供一种更为灵活的系统维护形式 (初级用户不推荐)。
好了, 简单的配置就这样了, 请玩家继续深入阅读 OLEG 的相关参考资料。
数.位天堂::ASUS 500 改机讨论区 WL-500g::系列改機基本步驟
Sprayfly::WL-HDD/500 Setup Guide
OpenWrt 固件通常是骇_机族的首选, 基本上你可以自由定制包括 Kernel 在内的所有东西, 这往往给人一种很爽的幻觉。除此之外, OpenWrt 还有一个叫做 DD-WRT 的表兄 (访问其主站需_破.墙_) 以及 DebianWRT 的堂兄, 也可以在 OpenWrt 上跑 Gentoo。
其中 DD-WRT 在管理上相当便捷, 玩家也是颇多的, 这里也推荐大家不妨尝试一下。而在路由器上跑 Debian, 就比较诡异了, 而跑 Gentoo 就更是说不出的诡异了。这里我的首选还是 OpenWrt, 因为我需要一个足够小, 占用资源足够少的固件, OpenWrt 定制起来非常方便, 自己编译吧。
当然 OpenWrt 已经有编译版了, 只是想用 OpenWrt 而对定制没有要求的同学可以偷懒了。
这里做得比较漂亮的是 Hive 版, 安装配置相当方便, 可以通过其站点 获取 资料。而 OpenWrt 官方也提供编译版 下载。
下面, 就让我们来建立一个 OpenWrt 固件。首先, 显然你已经有一台运行 Linux 的计算机 (什么, 你是 Windows 用户? 那你来看我的博客做什么?), 然后上到 OpenWrt 官网, 下载 源码 (当然也可以使用 SVN)。
OpenWrt 有两个分支, 较新的是 "Kamikaze(神风? 晕)" 版, 另一个是 "whiterussian(白俄罗斯)" 版 下载。这里选用较为稳定的 whiterussian RC6 版本。下面我们开始配置编译。
下面以我的 ASUS WL-HDD 设备为例, 来讲解 OpenWrt 的编译和配置。
$ wget http://downloads.OpenWrt.org/whiterussian/rc6/whiterussian_rc6.tar.bz2
$ tar -xjf whiterussian_rc6.tar.bz2
$ cd whiterussian_rc6.tar.bz2
$ make menuconfig
接下来会出现配置选单, 大部分的选项使用默认即可。可以酌情修改配置, 一般来说只要不是改得太过分, 生成的固件都是可用的。因为我是 ASUS WL-HDD 的盒子, 所以我主要是在系统中取消了 httpd 服务 (后面会提到我将使用 Eurasia3 应用服务器提供 web 服务), 并且将 IDE 硬盘的支持设置为 "内建 ([*] builtin)" 模式。
1. OpenWrt Package Selection --->
Busybox Configuration --->
Networking Utilities --->
[ ] httpd
2. Kernel Configuration / Device Support --->
[*] IDE Support, EXT3 filesystem support
USB 支持可以在系统安装好后使用模块加载 资料。
3. Target Root Filesystem --->
[*] jffs2
这里决定了生成映像文件使用的文件格式, 其中 squashfs 是只读的, jffs2 是可写的, 我们通常选择 jffs2 格式, 以后可以直接读取编辑路由器的 flash 存储器。
配置完成后执行编译。
$ make V=99
当编译完成后, 你可以在 whiterussian_rc6/bin 目录下找到生成的 trx 映像。
比如 OpenWrt-brcm-2.4-jffs2-4M.trx 这个映像, "brcm" 是通用的路由器硬件, jffs2 是文件系统, 4M 是指适用 flash 存储器大小, ASUS WL-HDD/500 的 flash 都是 4M, 适用于这个映像。
Kamikaze 和 Whiterussian 不同, 它生成诸如这样的映像 OpenWrt-brcm47xx-2.6-squashfs-64K.trx, 在硬件型号上可以自由配置。特别诡异的是在 Kamikaze 下 64K 指 4M flash, 而 128K 是指 8M flash 以此类推。
终于, 我们拿到了 trx 映像文件。其中只有 menuconfig 这一步有点工作量。貌似把系统日志部分 (syslogd) 砍掉, 可能会导致路由器重启失败, 需要保留, 其他服务应该都是可以取消的。
至于程序库, 可以等以后手工编译添加进系统。诸如 libpthread、libreadline 这些库是以后运行 Stackless Python 需要的, 对于非常常用的可以编译到镜像里去。
至于OpenWrt SDK 和 Image Builder, 我们在下面的开发中其实并不会用到, 不必选择编译。
在编译过程中, 会去网上拿许多依赖的 package 源码文件。比起 Kamikaze 来, Whiterussian 要下载海量的资源, 如果你网速不够快, 那么可以直接去 OpenWrt 官网上拿 (不推荐, 除非网速真的很慢)。你需要修改 whiterussian_rc6/scripts/download.pl 这个脚本, 清空 "foreach my $mirror (@ARGV) { ... }" 代码块即可。
编译完成以后, 请保留 whiterussian_rc6 目录, 这是我们接下来做交叉编译 (Cross Compiling) 的平台。
将 OpenWrt trx 映像写入路由器, 你需要 whiterussian_rc6/scripts/flash.sh 这个工具。你也可以从 这里下载这个脚本。
现在将路由器调至回复模式, 计算机和路由器直接使用网线连接, 确信能够 ping 到。作好准备工作。
以我的 ASUS WL-HDD 为例, 连好网线以后, 按住 reset 按钮, 同时插上电源, 黄灯开始规律闪烁即进入 flash 回复模式。接下来确认 WL-HDD 在 192.168.1.1 这个位置 (当然如果你已经设置过 nvram, ip 以 nvram 为准), 如果 ip 不是 192.168.1.1, 你需要先修改 flash.sh 文件中关于 ip 的设定。
$ apt-get install tftp
$ chmod +x flash.sh
$ ./flash.sh OpenWrt-brcm-2.4-jffs2-4M.trx asus
完成 Firmware 上传之后, 程序会回到 shell 下, 等待黄灯熄灭 (即开始更新 Firmware), 再等到 WLAN 绿灯亮起, 此时 Firmware 已经写入机器, 并且机器已经完成重启。恭喜恭喜!
解下来我们可以使用 telnet 192.168.1.1 登录进路由器。进入 Linux Shell 以后, 你可以使用 nvram show/set 命令来显示和设置 nvram, 修改机器 IP 等数据, 重启机器使修改生效。例如:
nvram set lan_ipaddr=192.168.0.2
nvram commit
Whiterussian 启动时加载 IDE 硬盘存在 BUG, 你需要修改 /etc/modules.d/20-ide 文件, 调整内核模块的加载顺序如下:
ide-core
pdc202xx_old
ide-detect
ide-disk
重启以后, ide 硬盘就可以被识别出来了。如果编译进了 fdisk, 那么可以用 fdisk -l 来查看硬盘。
和 OLEG 不同, OpenWrt 不用经过配置就可以使用 /etc/init.d 初始化脚本目录, 在里面添加启动脚本挂载硬盘, 并删掉不喜欢的服务。
#!/bin/sh
# chmod +x /etc/init.d/S90Example
mount /dev/ide/host0/bus0/target0/lun0/part1 /mnt
swapon /dev/ide/host0/bus0/target0/lun0/part2
swapon /dev/ide/host0/bus0/target0/lun0/part3
swapon /dev/ide/host0/bus0/target0/lun0/part4
killall logger
killall syslogd
killall crond
killall klogd
下面使用 free 命令, 看看剩下多少内存留给我们接下来的应用 (果然是寸土寸金啊)。
total used free shared buffers
Mem: 14296 7580 6716 0 56
Swap: 1572828 0 1572828
Total: 1587124 7580 1579544
这样, 这个 Linux 系统已经可用了。
在 OpenWrt 下也可以进行本地编译, 你可以 下载 root_fs_mipsel.ext2.bz2 , 并查阅 相关资料。
这里你不必真的在路由器上挂接 root_fs_mipsel.ext2 到文件系统上, 你可以在本地计算机上挂接并拷贝到路由器的 U 盘或者硬盘上。
$ mkdir ~/tmp
$ mkdir ~/tmp/root
$ mount -o loop root_fs_mipsel.ext2 ~/tmp/root
$ cd ~/tmp
$ tar -cjf root_fs_mipsel.tar.bz2 root
然后把 root_fs_mipsel.tar.bz2 拷贝到路由器硬盘上解压缩。
# cd /mnt
# wget http://192.168.x.x/root_fs_mipsel.tar.bz2 # 如果本机有 HTTP 服务, 那么可以通过 wget 从本机上取得文件
# tar -xjf root_fs_mipsel.tar.bz2
这样我们就得到了 /mnt/root 目录, 里面包含了完整的编译环境和需要的库文件。接下来以 /mnt/root 为根 ('/') 目录, 即可使用本地编译环境。
# chroot /mnt/root/ /bin/ash -
# gcc -v
# exit
不过你应该永远避免在路由器上进行本地编译, 首先是速度极慢, 然后诸多依赖也不能满足 (比如 Include 等), 但是这里架设的编译环境也并不是没有用处, 因为在 root_fs_mipsel 的 lib 目录下有许多我们需要的重要的库文件可以直接拿来使用, 省去许多费事的编译。
很显然, Eurasia3 才是王道。不过这个 Web 应用服务器依赖于 Stackless Python。找了半天, 也只有 Python 的 ipk 包。好吧, 自己编译吧。
除了高度定制, 自己编译 OpenWrt 映像的另一个好处就是交叉编译环境已经准备好了。现在让我们回到 whiterussian_rc6 目录, 来设定交叉编译环境, 很简单, 你只要在你的 PC 中输入下面几条命令。
$ export PATH=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/usr/bin:/PATH/TO/whiterussian_rc6/staging_dir_mipsel/mipsel-linux-uclibc:/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin:$PATH
$ export AR=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin/mipsel-linux-uclibc-ar
$ export AS=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin/mipsel-linux-uclibc-as
$ export LD=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin/mipsel-linux-uclibc-ld
$ export NM=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin/mipsel-linux-uclibc-nm
$ export CC=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin/mipsel-linux-uclibc-gcc
$ export CPP=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin/mipsel-linux-uclibc-cpp
$ export GCC=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin/mipsel-linux-uclibc-gcc
$ export CXX=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin/mipsel-linux-uclibc-g++
$ export RANLIB=/PATH/TO/whiterussian_rc6/staging_dir_mipsel/bin/mipsel-linux-uclibc-ranlib
$ export ac_cv_linux_vers=2.4.30
$ export CFLAGS="-Os -s"
现在你的编译环境已经是面向 OpenWrt MIPS 系统的了, 与本地编译唯一的不同, 就是你需要对源代码包的 configure 脚本增加 --host=mipsel-linux 参数。
$ ./configure --host=mipsel-linux
$ make
$ make install
大部分 x86 体系的软件包都可以在交叉编译平台上通过编译。不过 Stackless Python 貌似并不支持 MIPS 体系的计算机, 为此我编写了一个补丁, 你可以访问 这个地址, 将邮件中 "# stackless-2.52.mips.xcompile.patch" 以下部分复制出来保存为 stackless-2.52.mips.xcompile.patch 文件。下面我们就可以编译 Stackless Python 了。
$ wget http://www.stackless.com/binaries/stackless-252-export.tar.bz2
$ tar -xjf stackless-252-export.tar.bz2
$ cat stackless-2.52.mips.xcompile.patch | patch -p0
$ cd python-2.52
$ export CROSS_COMPILE=yes
$ ./configure --prefix=/opt/Stackless-2.5.2 --host=mipsel-linux
$ make
$ make install
现在我们在本机的 /opt 下得到了 Stackless-2.5.2 目录, 打包放到路由器的 /opt 目录下, 我们就可以正常使用 Stackless Python 了。
关于在其他版本的 Stackless Python 里如何 H@ck 代码以支持 MIPS 架构, 请仔细阅读 patch 文件。据 Richard Tew 说他对在 Stackless 中加入 MIPS 支持颇感兴趣, 除非他能跑得过 Python 的开发速度 (这好像有点冷~~`)。很显然 Guido 把 Stackless 拒之门外是一个严重错误, 喂喂, 别再鼓捣 Python 3000 什么拉!
现在登入 WL-HDD, 下载 Eurasia3, 编写一个 Eurasia3 (这里使用 svn 版, 我正准备发布的 alpha4 的原型, alpha2 可以在这里下载) 的测试程序:
# !/opt/Stackless-2.5.2/bin/python2.5
from Eurasia.web import config, mainloop
def controller(client):
client.write(
'HTTP/1.0 200 OK\r\n'
'Content-Type: text\r\n'
'\r\n'
'hello world!' )
config(controller=controller,
port=80)
mainloop()
做了一下小测试, hello world 每秒可以达到 40 个以上的请求数, 尽管比起一台普通的 PC 同样的 Eurasia3 程序慢了几百倍, 但是对于一台嵌入式设备而言, 已是颇令人满意了。
PS:据阿北说他的笔记本是做开发用途, 而不是做了网站, 这里勘下误。
或是邮件反馈可也:
askdama[AT]googlegroups.com
订阅 substack 体验古早写作:
关注公众号, 持续获得相关各种嗯哼:
评论
“这里性价比最高的是 Buffalo 的 Linkstation 网盘, 首选的是 LinkStation HD-H120LAN120G 这个型号, 居然拥有高达 400G 的 MIPS CPU 以及 64M 的巨量内存 (耗电 20W 左右)。”
这个盒子的 MIPS CPU 是 400G ?
你好~
你說的Python 可以在編譯目錄下找到
接下來 make 會使用這個已經編譯好的 Python 來執行 setup.py 編譯编译 sharedmods
指的是說在MIPS的機器上嗎? 還是在x86 Linux?
指令要如何下?
我使用Ubuntu 7.10 ,Python 是2.5的沒錯
您說的 bin 是 /bin 嗎?
Ubuntu 上找到python 在 /usr/bin 這個資料夾下
如果您說的是 /bin ,要如何裝到 /bin 下呢?
把patch過的檔和原擋比較後,發現檔案內容沒有不一樣的地方
可能stackless python 是較新的版本
patch 無法應用在上面
如果是這樣要如何修改?
你好~
今天照著你的步驟,
用RC6的版本,
目錄也改成stackless-2.52 ,
也應用了 patch ,
還是出現這樣的訊息就停了
checking for %zd printf() format support... configure: error: cannot run test program while cross compiling
See `config.log' for more details.
另外看了你在 Blog 上的描述, 發現你 Stackless Python 的目錄是 "stackless-2.5.2-r63812", 而我制作 patch 的目錄是面向 "stackless-2.52" 目錄的 (貌似官方的 tar.bz2 包有改動?), 你可以先嘗試將目錄改成 "stackless-2.52" , 再應用 patch 重新編譯。
你好,想請請教一下
使用WhiterussianRC6 編譯的Stackless Python 可以在kamikaze7.09 ,kernel 2.6 下正常運作嗎?
用户名留空:admin
admin:密码留空
admin:admin
root:密码留空
root:admin
root:root
密码留空:root
初始密码无外乎这几种可能。
在此非常感謝沈兄提供諸多寶貴的意見,謝謝。
1. OpenWrt 有 Whiterussian 和 Kamikaze 兩個分支。其中 Kamikaze 分支較新, 而 Whiterussian 據說要更穩定。
據我所知 Whiterussian 和 Kamikaze 的配置方式尤其在網絡配置 (和內核配置) 上有較大的不同。
理論上, 這兩個版本 ASUS WL-HDD 都能刷, 而且貌似 OpenWrt 對 WL-HDD 的支援度是相當之高。
因為定制的需要, 我使用的是自己編譯的韌體。我編譯了 Kamikaze, 或由于配置上的失當, 這份韌體無法正確啟動, 因為調試手段所限故沒有深入追究。而 OpenWrt 官方提供的 Kamikaze 韌體是可用的。
相較, 自編譯的 Whiterussian 則要穩定得多, 一般都能啟動起來。故, 對有定制和開發 (包括交叉編譯) 需要的, 我認為 Whiterussian 是更好的選擇。
2. 據我觀察, 按住 reset 再接上電源 (但需注意, 接上電源後仍需按住 reset 數秒直到黃燈開始閃爍), 并不是每次都會進入黃燈閃爍的回復模式。
多試幾次應該可以進到回復模式。然後使用 OpenWrt scripts 目錄下的 flash.sh 腳本向 WL-HDD 寫入 (./flash xxx.trx asus)。
我遇到過某些類型的韌體 (比如 DD-WRT) 可能會影響機器的開機和重置行為, 但是 OLEG 韌體不會對開機有影響, 可以順利進入回復模式改機到 OpenWrt。
希望這些能對您有所幫助。并祝數位天堂越辦越好 :)
1.您提的openwrt有兩個分支,這兩個分支有何差異?這兩個版本WL-HDD都能刷嗎?
2.我手上的WL-HDD似乎是不能以您提的方式刷韌體,就是您所說的連好網線按住 Reset 按鈕再插入電源,同樣的步驟只見WL-HDD像正常開機一樣並不會進入所謂的黃燈規律閃爍的 flash 回復模式,不知是哪個流程出錯了。