上一篇写这台小米 BE3600 的固件漏洞时,我从头到尾没拧一颗螺丝。主控是什么、内存多大、闪存多少,全是从 /proc 和 /sys 里读出来的,那篇里也交代过一句:这些数字只能说明系统自己怎么说,证明不了板子上到底焊了什么。想看板上焊的是什么,只能把机器拆开。
这篇就是拆的过程。顺序是:先把丝印认一遍,确定了七颗主芯片的型号,再掉过头去固件里一条一条对账——对得上就写进来,对不上的单独列一节。认芯片这件事,只看别人的拆机图会认错,自己拍的照片不放大也会认错,所以下面每一颗型号都是从板上丝印读出来的,并且都配了放大后的实物图。
先把结论摆出来,免得看一半不知道拆出了什么:
| 角色 | 板上丝印 | 说明 |
|---|---|---|
| 主控 SoC | Qualcomm IPQ5312 | 四核 ARMv7,1.1GHz,内置 2.4G 射频 |
| 内存 | Rayson RS128M16V8DB-107AT | 128M×16 = 256MB DDR3 |
| 闪存 | GigaDevice GD5F1GM7REYIG | 1Gbit = 128MB SPI NAND |
| 千兆交换 | MOTORCOMM YT9215S | 5+2 口千兆交换控制器 |
| 2.5G PHY | Qualcomm QCA8081 | 单口四速,最高 2500BASE-T |
| 5G 射频 | Qualcomm QCN6402 | 只做 5G 频段,2×2 |
| 2.4G 功放 | HT2533 | 丝印三行读全后的型号位;公开渠道无规格 |
先把话说到前头。这台机器是我自己买的、自己拆的,拆之前已经过了保修期。拆解会破坏外观、可能弄丢卡扣,也可能因为静电把板子打坏——要不要拆、拆坏了算谁的,你自己掂量。另外这篇里所有判断都只对我手上这一台成立,同型号不同批次的物料是可能被替换的,后面第三节会用实例说明为什么这事很容易踩坑。
拆之前,先把这台机器的接口和型号记清楚


WAN/LAN 一组四个 RJ45,底下依次标着 1、2、3、4(2.5G)——也就是三个千兆口加一个 2.5G 口,四个口都能盲插当 WAN。左边是 RESET 小孔,右边是 MESH 键。四个网口全部挂在 WAN/LAN 一个标签底下,意味着都能当 WAN 用,也支持双 WAN 和链路聚合。规格上写得清楚:三个千兆口加一个 2.5G 口。后面拆开你会看到,这三个千兆口和那一个 2.5G 口,在板上是两条完全不同的链路——一颗交换芯片管前者,一颗独立 PHY 管后者。
型号这件事值得单独说一句。机身底部标签写的是 RD15,但把主板翻过来看 PCB 丝印,印的是 MD15:

MD15,不是 RD15。这台机器的型号在三个地方写法都不一样:卖的时候叫 RD15,PCB 上是 MD15,天线料号里又夹着 -RD-。再往细看,PCB 上还有一行 M015.R0110 和日期 20250207——板子是 2025 年 2 月 7 日打样的。固件那边 /proc/version 里写的构建时间是 Thu Mar 20 02:49:04 2025,中间隔了六周。物料、打板、出固件,这条时间线是能够互相咬上的,这类交叉验证在拆解文里比单看一张图有意思得多。

要拆的话,从底面这一颗螺丝开始。
拆开之后:一块窄板,四片屏蔽罩

外壳打开之后,结构比想象中简单:一个上下壳、四根天线、一块主板,没有多余的排线和转接板。天线是固定在壳体上的,所以拆的时候要先把馈线从主板上拔下来。

xiaomi 和 MD15 丝印,右下的四根网口在另一面。所有大芯片都躲在屏蔽罩里,这也是为什么只看外观根本认不出用料。
PPT PS M-2443 是网口的隔离变压器。主板是窄长条。你注意一下这个布局:四颗大芯片全部集中在板子的一侧,网口和电源全在另一侧。这不太常见——一般路由器会把网口和交换芯片放在一起,这颗却把交换芯片留在了芯片那一面,只用走线把信号引到背面的 RJ45 上。
散热结构也在这一面:主板上盖了一块均热铝板,铝板下面是四片屏蔽罩,每片罩子里对应一块导热垫。


取下来的铝板上留着几块导热垫的印子,形状和位置刚好能反推出下面压着哪几颗芯片、各自占多大——这算是拆机时一个免费的好处:不用悬空猜芯片位置。顺便说,这种「芯片背面贴铝板、正面透到外壳散热」的做法,效率上不如让芯片正面直接压散热片,但在这个功耗档位够用;我在其他机器上见过类似设计(联通 HG6371F 从猫那篇里主板就是这样)。
一颗一颗认:板上这七颗主芯片
下面每一颗都是把丝印放大到能看清字才写的。手机拍的原图直接看是读不准的,尤其是批次码和最后几位,字又小又有反光。
主控:Qualcomm IPQ5312

Qualcomm IPQ5312 003,最后一行 FE547HLS 是批次码。固件里 /sys/devices/soc0/machine 读出来也是 IPQ5312——这一条软硬件对得上。这颗在上一篇里已经出现过——当时是从 /sys/devices/soc0/machine 读出来的字符串。现在有了实物对照,两边是同一个型号,这一条可以确定。
内存:Rayson 256MB DDR3

RS128M16V8DB-107AT。128M×16 就是 2Gbit,也就是 256MB;-107 是速度等级,换算下来是 DDR3-1866,跟工具从系统里读到的 1866MHz 对得上。这一颗是这篇文章里最能体现「认丝印」价值的地方,原因见下一节。
闪存:GigaDevice 128MB SPI NAND

GigaDevice(兆易创新)的 SPI NAND,完整的料号是 GD5F1GM7REYIG——板上左边缘那颗被屏蔽框压住了一半,所以只看得到 5F1GM7REYIG。查料号表,1G 这一段是容量位,1Gbit = 128MB。把料号拆开看:GD 是厂商,5F 表示 SPI NAND,1G 是容量位,R 表示 1.8V 供电,Y 是 WSON8(8×6mm)封装,I 是工业温度范围。这颗只有 128MB,不是 256MB——这一点后面跟固件的分区表对上了,是全文最关键的一处交叉印证。
另外,闪存焊在板子最边缘,一部分被屏蔽框压住,所以丝印开头两个字母被挡掉了。只看照片很容易把它当成一颗来路不明的芯片。

千兆交换:MOTORCOMM YT9215S

MOTORCOMM(裕太微)YT9215S。这颗是 5+2 口千兆交换控制器,LQFP-128 封装,只要一颗 25MHz 晶振就能跑——右边那颗方方正正写着 25.0 的就是它。这颗是国产的裕太微 YT9215S。查它的公开规格,是 5+2 口的二层管理型千兆交换控制器,LQFP-128 封装,5 个口内置千兆 PHY,另外留了两路上行接口(一路 RGMII/MII,一路 SGMII/HSGMII)给主控或外部 PHY 用。
这颗芯片有个细节挺方便核对:它自带 5 个千兆 PHY,所以只要一颗 25MHz 晶振就能工作,不需要给每个网口各配一颗。图上右边那颗方方正正的晶振,丝印就是 25.0。板上能同时看到「交换芯片」和「25MHz」,基本就能确认这颗在干交换的活。
2.5G 网口的 PHY:Qualcomm QCA8081

Qualcomm QCA8081。它是一颗单口四速以太网 PHY,支持 10M/100M/1G/2.5G,对外走 SGMII+ 接主控。按高通官网的产品页,QCA8081 是一颗单口四速 PHY,支持 10M/100M/1G/2.5G,对外走 2500BASE-T;连主控那侧可以配成 1.25G SGMII 或者 3.125G SGMII+。这颗和上面那颗交换芯片是两条独立的链路,正好解释了为什么四个网口里只有一个能跑 2.5G。
顺着这条线还能挖到一个有意思的细节:这颗 PHY 在 Linux 主线上是有驱动的,编号 0x004dd101,2021 年合进 at803x 这个 PHY 驱动里(LKML 上的补丁)。也就是说,理论上你不装任何厂商插件,内核自己就能认出它。
5G 射频:Qualcomm QCN6402

Qualcomm QCN6402。这颗只负责 5G 频段,2.4G 是主控里内置的——板上丝印 5G_0/5G_1 那两路走线就是从这个片区出去的。右上角那颗 48.000 是射频用的 48MHz 晶振。这台机器的无线是「主控内置 2.4G + 外挂一颗 5G 射频」的组合。所以 2.4G 那一路在板上找不到独立芯片,是正常的——很多拆解文在这里会写成「2.4G 射频芯片缺失」或者干脆编一个型号出来。
晶振这边也能佐证:这块板上同时有 25.0(交换芯片用)和 48.000(射频用)两种,晶振频率不同,说明它们服务的是两类完全不同的电路。这种「靠一颗晶振反推芯片用途」的办法,在看不清主芯片丝印的时候特别管用。
2.4G 这一侧,还有颗功放

8245SD、971446、HT2533。左边橙色丝印的 2G_0/2G_1 是两路天线口。主控内置射频的发射功率通常不够,所以要外挂功放(FEM)。2.4G 这一侧屏蔽框里那颗小功放芯片,丝印一共有三行:
8245SD
971446
HT2533
公开那篇同型号拆解只读了第一行 8245SD,据此认成 KCT8245SD。把三行读全,最下面那行 HT2533 才更像型号位——第一行往往是批次或序列号,不是型号。这颗芯片的丝印排布本身就在诱导你认错。
但 HT2533 这个型号,我在公开渠道没查到规格书。所以这一颗我只给丝印原文,不给结论。三行字都在上面的图里,谁认得这颗,欢迎告诉我。
那为什么软件侧查不到它?这个问题的答案涉及功放这类芯片的本质,我在后面「拆完再回固件里对账」那一节专门写了一段——因为证据也在那边。
四根天线,两根 2.4G 两根 5G

MD15-<频段>-<序号>-RD-V0.x-<批次>——MD15 对应 PCB,RD 对应产品平台,两个编号混在同一串料号里。
MD15-5G-1-RD-V0.3-2542。同一台机器上四根天线并不都是同一个版本,2.4G 那两片就写到了 V0.5。
MD15-2.4G-2-RD-V0.5-2534。把两份料号并排看,能确认这四根天线确实是两根 2.4G、两根 5G,而不是四根通用天线。把天线拿下来单独看,两片的振子形状差别很大:


2.4G 和 5G 都在同一块塑料壳里,为什么振子要做得不一样?因为天线电长度是按波长算的。5G 频率高、波长短,一片窄板上就能放下接近半个波长的振子;2.4G 波长差不多是 5G 的两倍多,同样长的板子上放不下,就只能把振子折起来。折线不是为了「看起来高级」,是被尺寸逼出来的。这一条光看参数表永远看不出来,只有把天线拆下来对着看才明白。
拆完再回固件里对账
到这儿硬件侧的事说完了。下面这一节是这篇跟大多数拆解文不一样的地方:把板上认到的东西,回过头去跟固件里读出来的数据一条条对。对得上的当证据,对不上的单独拎出来。
固件里那串 128MB,正好把闪存铺满
把 /proc/mtd 打印出来,一共 27 条:
mtd0: 00100000 00020000 "0:SBL1" mtd14: 00100000 00020000 "0:APPSBL"
mtd1: 00100000 00020000 "0:SBL1_1" mtd15: 00100000 00020000 "0:APPSBL_1"
mtd2: 00100000 00020000 "0:MIBIB" mtd16: 00080000 00020000 "0:TRAINING"
mtd3: 00080000 00020000 "0:BOOTCONFIG" mtd17: 00200000 00020000 "0:ART"
mtd4: 00080000 00020000 "0:BOOTCONFIG1" mtd18: 00040000 00020000 "0:LICENSE"
mtd5: 00200000 00020000 "0:QSEE" mtd19: 02a00000 00020000 "rootfs"
mtd6: 00200000 00020000 "0:QSEE_1" mtd20: 02a00000 00020000 "rootfs_1"
mtd7: 00080000 00020000 "0:DEVCFG" mtd21: 00080000 00020000 "bdata"
mtd8: 00080000 00020000 "0:DEVCFG_1" mtd22: 00080000 00020000 "crash"
mtd9: 00080000 00020000 "0:TME" mtd23: 01ac0000 00020000 "overlay"
mtd10: 00080000 00020000 "0:TME_1" mtd24: 003066a2 0001f000 "kernel"
mtd11: 00080000 00020000 "0:CDT" mtd25: 0175f000 0001f000 "ubi_rootfs"
mtd12: 00080000 00020000 "0:CDT_1" mtd26: 01702000 0001f000 "cfg"
mtd13: 00080000 00020000 "0:APPSBLENV"
把 mtd0 到 mtd23 这 24 条的容量加起来,结果是一个很干净的整数:134217728 字节,也就是正好 128 MiB。而这颗闪存芯片的标称容量,正是 128MB。
换句话说,原始分区不多不少、刚好铺满整颗闪存,没有留下任何空档。这个数字不是「差不多」——它是逐字节对上的。反过来说,如果有人告诉你这台机器是 256MB 闪存,你拿这条一算就知道不对。
但这里还有个更细的地方,一般拆解文不会提:最后三条 mtd24/mtd25/mtd26 的擦除块大小是 0001f000,也就是 124 KiB,而上面 24 条全是 00020000,128 KiB。
同一个闪存设备上,擦除块大小不可能是两种。124 KiB 这个数字其实是 UBI 的算术结果:物理擦除块 128 KiB 要减去两个页头(每页 2 KiB),剩下的 128 − 2×2 = 124 KiB 就是 UBI 逻辑卷的擦除单位。所以这三条不是原始分区,而是建在 UBI 之上的逻辑卷,只是内核对用户空间把它们也伪装成了 mtd 设备。命名上也对得上——kernel、ubi_rootfs、cfg,都是典型的 UBI 卷名。
这一条推论的价值在于:光看「27 个分区」这个数字,你会把闪存容量算错一倍。真正的原始分区只有 24 条,加起来 128 MiB;后面三条是从里面「长」出来的逻辑卷。
哪颗芯片挂哪条驱动,模块表里写得明明白白
要看「这台机器用了什么驱动」,最直接的入口是 /proc/modules——它列出所有动态加载的内核模块。这颗设备上装了二百多个,其中和硬件直接相关的是这些:
| 模块 | 大小 | 对应板上的哪颗芯片 / 干什么的 |
|---|---|---|
yt_switch | 450560 | 裕太微 YT9215S 交换芯片的驱动 |
qca_ssdk | 901120 | 高通交换 SDK |
qca_nss_ppe | 409600 | NSS/PPE 硬件转发引擎 |
qca_nss_sfe | 237568 | 快速转发卸载(Shortcut FE) |
ipq_cnss2 | 339968 | IPQ 的 NSS 核心驱动 |
ecm | 741376 | 高通连接管理器,把转发卸载上去 |
umac / qca_ol / wifi_3_0 | 3522560 / 1507328 / 991232 | 无线驱动栈(2.4G 与 5G 共用) |
emesh_sp | 65536 | Mesh 组网 |
dm_req_crypt | 12288 | 配置分区的加密卷 |
pwm_rgb / leds_gpio / button_hotplug | 12288 / 12288 / 12288 | 指示灯、按键 |
前面认的那颗交换芯片,在这里被实锤了。板上丝印是 MOTORCOMM YT9215S,内核里挂着一个叫 yt_switch 的模块——名字里的 yt 就是裕太微。这条链路是「板上丝印 → 料号 → 内核模块名」三级对上的,比任何一张拆机图都硬。
顺带说,模块表里还有几个厂商私有的东西,一眼能看出是小米自己加的:local_gw_security、wan_check、ip_account、wandt_filter,以及一串 miwifi_xt 开头的统计模块。这些不是高通给的,是厂商在开源基础上补的业务逻辑,想看一台机器的固件「改了多少」,数这一类模块最直观。

/proc/modules 的原样输出(只截了一屏)。前面那张模块对照表里的对应关系,就是从这一大堆里一条条挑出来的。模块目录里还躺着一颗没被加载的 PHY 驱动
/proc/modules 只列已经加载的模块。更有意思的是把驱动目录整个列出来,看这台机器准备了什么:
yt_switch.ko yt_phy_module.ko <-- 注意这两个
qca-ssdk.ko qca-nss-ppe.ko qca-nss-dp.ko
qca_ol.ko umac.ko qdf.ko wifi_3_0.ko
ecm.ko ecm-wifi-plugin.ko ecm_sfe_l2.ko ecm_ae_select.ko
diagchar.ko passthrough.ko enid.ko qca-mcs.ko
mtd_nandecctest.ko mtd_oobtest.ko mtd_pagetest.ko mtd_readtest.ko
mtd_speedtest.ko mtd_stresstest.ko mtd_subpagetest.ko mtd_torturetest.ko
yt_switch.ko 已经加载,对应板上那颗裕太微交换芯片——这条前面说过。但紧挨着它还有一个 yt_phy_module.ko:裕太微的 PHY 驱动,而这颗模块在这台机器上根本没有被加载。
为什么没加载?因为这台机器的 2.5G PHY 是 Qualcomm 的 QCA8081,不是裕太微的。反过来说——固件里带着另一颗 PHY 的驱动,意味着这个型号在硬件设计上本来就准备了两套 2.5G 方案。前面说「同型号不同批次会换料」,这里正好给出了另一半证据:换料这件事,厂商是提前把驱动都塞进固件里的。
另外,驱动目录里还有一整套 NAND 自检工具:mtd_nandecctest、mtd_oobtest、mtd_pagetest、mtd_readtest、mtd_speedtest、mtd_stresstest、mtd_subpagetest、mtd_torturetest。八个 MTD 测试模块一个不少,说明这版固件保留了产线和返修用的闪存自检能力。它们平时不加载,但真怀疑闪存坏了的时候,insmod 一下就能用——这算是折腾之前值得知道的一张底牌。
为什么功放这个型号,软件侧根本查不到
看到这里可能会冒出一个疑问:前面那些芯片都能从固件里对出来,凭什么叫功放就只能看丝印?
答案有点反直觉——因为这类芯片压根不需要驱动,内核里也就不会留下它的任何记录。
功放(FEM)通常是「功率放大器 + 低噪声放大器 + 收发切换开关」三合一。它干活只需要几个信号:什么时候放大发射、什么时候放大接收、什么时候把天线让给哪一路。这些信号就是几根 GPIO 的高低电平,由无线驱动按收发时序去拉动——不是寄存器读写,也没有设备地址。
没有寄存器接口,就意味着没有地方存放「我是谁」:没有 ID 寄存器、没有枚举过程、没有驱动 probe 日志。所以翻遍 /proc、/sys、/lib/modules 都找不到它——不是没找对地方,是它本来就不参与软件世界。
这一条在固件侧其实有旁证。把 /lib/modules/$(uname -r)/ 里那两百多个模块挨个看过去,没有任何一个是功放驱动:网口有 yt_switch.ko、PHY 有 yt_phy_module.ko、闪存有一整套 mtd_*,唯独功放一个字都没有。这本身就是「它不需要驱动」的直接证据。
软件侧能看到的只是它的影子:无线驱动会占住几根 GPIO 做收发控制,而它真实的增益特性是被写进板级校准文件(BDF)里的——校准文件记的是「这条射频链目标多少功率」,不是「这颗芯片叫什么名字」。也就是说,系统里能看到「这里有一颗独立功放、占了哪几根控制线」,但看不到它是哪一颗。
所以结论很干脆:认功放只能靠眼睛看丝印。这也是这一节里那颗芯片我只给丝印原文、不下结论的原因。
接口名里藏着两条链路
前面认芯片时提过一句:三个千兆口和那个 2.5G 口在板上是两条独立的链路。这一条在固件侧也有影子——把 /proc/net/dev 打出来,一台只有四个网口的路由器,内核里居然挂了二十多个网络接口:
eth0 eth0.1 eth0.2 eth0.3 eth1
br-lan br-miot lo
wl0 wl1 wl4 wl5 wl13 wifi0 wifi1 mld-wifi0 hostap_mld0 bhap_mld0 bhsta_mld0
soc0 soc1 gre0 gretap0 erspan0 bond0 ip6tnl0
重点看前两行。eth0 底下挂着 eth0.1、eth0.2、eth0.3 三个 VLAN 子接口——这是「一个物理口接交换芯片,再用 VLAN 把 WAN 和 LAN 切开」的标准写法。而 eth1 干干净净,一个子接口都没有。两个 MAC,一个带 VLAN 一个不带,跟板上那两条 HSGMII 的形状是对得上的:一条去 YT9215S 带三个千兆口,一条去 QCA8081 带 2.5G 口。
无线这边的命名同样能读。wl0/wl1 是两个频段对应的接口,wifi0/wifi1 是它们底下的物理设备,soc0/soc1 是 SoC 内部的数据通路;br-lan 是有线加无线的那个大网桥,br-miot 是给米家设备单独分出去的。
还有一串 mld- 前缀的:mld-wifi0、hostap_mld0、bhap_mld0、bhsta_mld0。mld 是 Multi-Link Device,Wi-Fi 7 多链路聚合才有的东西——光看接口名就能确认这台机器支持 MLO,不用去翻参数表。

/proc/net/dev 的原样输出。左边是接口名,右边几列是收发计数——上面那份接口清单就是从这儿抄的,可以看出 wl0 和 wifi1 其实是同一条链路的两面。中断表还顺带交代了 5G 射频挂在哪条总线上
/proc/interrupts 看着像排障用的东西,其实把总线拓扑也写出来了。跟无线有关的中断是这么几组:
pci1_wlan_ce_0 .. ce_5 pMSI 1..6
pci1_wlan_grp_dp_0 .. grp_dp_11 pMSI 7..17
q6v5_wcss_userpd1_* / userpd2_* smp2p
rxdma2host-monitor-destination-mac1..3 GIC-0 516/520
wbm2host-tx-completions-ring1 .. ring4 GIC-0 479..482
pci1_wlan_ce_* 这一组,前缀里的 pci1 说得明明白白:它走的是 PCIe,不是挂在 SoC 内部总线上的。两块射频里,2.4G 是主控内置的,那这颗外挂的 QCN6402 自然就是走 PCIe 的那一颗。这一条我在板上看不出来(PCB 上的走线肉眼分不出总线和地址线),但内核自己说了。
另外两组也能对上:q6v5_wcss_userpd1 和 userpd2 是两颗无线子系统的固件进程(WCSS),1 和 2 对应两个频段;rxdma2host-monitor-destination-mac1/2/3 里的 mac1/2/3 是三组无线 MAC 的转发环。一块 2×2 加 2×2 的机器,在内核里是能数出 MAC 数量的。
还有一条不起眼但实用的:中断表里有 msm_serial0,也就是这台机器有一个活的串口。板子边缘那几个圆形焊盘位置看着像它的引出点(这个我只对了位置,没实测),哪天真刷成砖了,那大概是最后的救砖通道。

/proc/interrupts 的原样输出(节选)。pci1_wlan_ce_*、q6v5_wcss_userpd1/2、…-mac1/2/3 这几组名字,就是上面那几段判断的全部依据。板载 256MB,为什么系统只认 180MB
内存颗粒是 256MB,但 /proc/meminfo 里的 MemTotal 只有 180428 kB。这两个数字不矛盾,差额去向也是可查的:SoC 的保留区、GPU、无线固件、以及各种 DMA 缓冲都要从物理内存里先划走,内核最后能管到的只剩这些。所以「板载 256MB」和「可用 180MB」是两回事,不能拿其中一个去否定另一个。
还有一处更要紧:SwapTotal 是 0。这台机器没有 swap,内存吃满的时候没有退路。同一份 meminfo 里还有一行 SUnreclaim: 53448 kB——180MB 里有 53MB 是被内核模块占住的、不可回收的 slab。装了二百多个模块的代价,在这里是能看到的。
配置到底藏在哪儿
/proc/mounts 里有一处很值得看:/etc 本身挂的是 ramfs(重启即丢),但 /etc/config、/etc/crontabs、/etc/smartvpn 这十个目录,全部挂在同一个设备 /dev/mapper/sec_cfg 上,而那是一个加密卷。上一篇里从文件读取通道翻出来的现象——官方导出的配置备份 .des 是明文、.mbu 是密文——到这里就对上了:配置本来就住在加密卷里。
这十条挂载点的清单是:「/etc/config、/etc/crontabs、/etc/smartvpn、/etc/ppp、/etc/mipctl、/etc/parentalctl、/etc/smartcontroller、/etc/datacenterconfig、/data/etc、/tmp/sec_cfg/etc」。想动这台机器的任何配置,都绕不开这个卷,这也是为什么上一篇里改 crontab 那么绕。
这一条推论还能再钉一遍。/proc/cmdline 里写着内核启动时用的根文件系统参数:
ubi.mtd=rootfs root=mtd:ubi_rootfs rootfstype=squashfs rootwait clk_ignore_unused vmalloc=1G
ubi.mtd=rootfs 说的是「UBI 设备建在名叫 rootfs 的那个 mtd 分区上」,root=mtd:ubi_rootfs 说的是「根文件系统用 UBI 里的 ubi_rootfs 卷」。这就把刚才那条推论接上了:mtd19 才是原始分区,mtd25 是从它里面长出来的逻辑卷。
再把 ubinfo -a 跑出来,整套布局就彻底闭合了。这台机器上建了两个 UBI 设备:
| UBI 设备 | 建在哪个分区 | 擦除块数 | 算出来 | 里面的卷 |
|---|---|---|---|---|
ubi0 | mtd19 rootfs | 336 | 336 × 128 KiB = 42 MiB | kernel(静态,10 MiB,实际数据 3.0 MiB)、ubi_rootfs(动态,23.3 MiB) |
ubi1 | mtd23 overlay | 214 | 214 × 128 KiB = 26.75 MiB | cfg(动态,23.0 MiB) |
两个数字都不差分毫:ubi0 的 336 个物理擦除块乘 128 KiB,正好是 rootfs 分区的 42 MiB;ubi1 的 214 个乘出来,正好是 overlay 分区的 26.75 MiB。所以前面那三条「逻辑卷」的身份也就定死了:
mtd24kernel(3.0 MiB)=ubi0的 0 号卷,静态卷,实际数据 3172002 字节——和 ubinfo 报的Data bytes: 3172002一模一样。mtd25ubi_rootfs(23.4 MiB)=ubi0的 1 号卷,也就是当前的根文件系统。mtd26cfg(23.0 MiB)=ubi1的 1 号卷,挂载表里/data、/userdisk挂的正是它。
顺带纠正一个差点被我写错的地方:那条名字叫 overlay 的分区,里面装的不是 overlayfs,而是一个只放了 cfg 一个卷的 UBI 设备。也就是说它实际是「配置卷的容器」,不是「可写的根覆盖层」。我第一遍看到 overlay 这个名字时,就直接把它写成了「26.8MB 的可写层」——分区名会骗人,卷的信息才是真的。
三条跟网上资料对不上的地方
认完芯片我去查了公开资料,其中能查到的同型号拆解挺详细(比如 这一篇)。把两边并排一比,有四处不一样,而且都不是我读错丝印那种不一样。这一节单独写,因为它是这篇最想说的东西。
第一处:内存颗粒换了品牌
公开那篇拆解里,内存是兆易创新的 GDP1BFLM-CB,DDR3L-1866、256MB。而我这台上是 Rayson RS128M16V8DB-107AT——换了一家供应商。容量和速度等级是同一档,所以整机表现上不会有区别。
这类替换在电子产品里叫「二供」,属于常规操作,不是偷工减料。但它意味着:如果你照着别人的拆解文去给这台机器配散热片、或者指定内存型号,很可能会对不上。认自己的板子,永远比认别人的文章可靠。
第二处:2.5G 那颗 PHY 换了厂商
这一处更明显:公开那篇写的是裕太微 YT8821C,而我这台上是 Qualcomm QCA8081——不只是型号不同,连厂商都不是同一家。这两颗都是 2.5G PHY,功能上属于同类,但它说明了一件更要紧的事:
同一型号的路由器,隔几个批次就可能换掉一颗主要芯片,而外观、型号、包装完全不变。所以你在网上看到的任何一份拆解清单,都只能当作「这个型号曾经用过什么」,不能当作「我买的这台一定是什么」。想确认手上这台,唯一可靠的办法就是拆开看丝印,或者从固件侧把 PHY 认出来——下一节说怎么做。
第三处:2.4G 功放,公开拆解认错了型号
这一处的性质跟前两处不同——不是换料,是认错。公开那篇拆解写「2.4G 外置了两颗 FEM 芯片,上面丝印着『8245SD』,型号是 KCT8245SD」,然后给出了 KCT8245SD 的完整参数表。
但我把丝印读全之后发现,那颗芯片有三行字:8245SD、971446、HT2533。按常规排布,最下面那行才是型号位,8245SD 更像批次或序列号。而 HT2533 这个型号我在公开渠道没查到规格书。
我没办法断定公开那篇一定是错的(我也没有那颗芯片的 datasheet),但它给出的那套 KCT8245SD 参数表,我建议你别直接拿去引用:型号这一层没坐实,参数就都是悬空的。我自己也只写到这里为止。
这件事反过来印证了这篇文章的方法:认丝印最大的风险不是「看不清」,而是「看得清一半就以为全看清了」。第一行印得最清楚,偏偏第一行常常不是型号。
第四处:CPU 到底是不是 A53,我给不出确定答案
这一条我得把话说满。IPQ5312 在公开资料里,几乎清一色写成「四核 Cortex-A53」——包括官方渠道和各家评测。但把固件里的 /proc/cpuinfo 拉出来,这台机器自己报的不是这么回事:
model name : ARMv7 Processor rev 4 (v7l)
CPU implementer : 0x51
CPU architecture: 7
CPU variant : 0xa
CPU part : 0x801
CPU revision : 4
三个关键字段:implementer 0x51 是高通,architecture 7 意味着这版内核把它当 32 位 ARMv7 在跑,part 0x801 是核的编号。而按 ARM 的编号规则,Cortex-A53 报的是 architecture 8 加 part 0xd03——对不上。
那 0x801 是什么?在社区维护的高通核编号表里,0x801 对应的是 Kryo 2xx Silver。而 Kryo 260 那颗 Silver 核,本身又是从 Cortex-A53 派生的设计。
所以最可能的解释是:核用的是 A53 一路派生下来的设计,但在这台机器的固件里跑在 32 位模式下,于是 cpuinfo 把 architecture 报成了 7。这样一来,「A53」和「v7」两种说法可能并不矛盾,只是各自在说不同的层面——一个是核的设计来源,一个是它实际运行的模式。
但我必须承认,这只是解释,不是结论。我手上能拿到的只有 cpuinfo 这一个证据,它证明不了高通的内部设计。所以我把它摆在这里:如果你手上有 IPQ5312 的官方 datasheet 或者权威的核编号表,欢迎告诉我,我把这一节改掉。
不拆机也能拿到这些信息
上面拆解得到的结论,有一部分其实不拆机也能拿——只要你能在固件侧执行命令。上一篇里写过,这台机器上有一条命令执行通道,我把它封成了工具,里面有个「执行并取回输出」的功能,能直接把命令结果拿回来。
要认芯片,下面这几条最有用。而且这一轮我全都跑通了,把实际结果一并贴出来,你可以照着在别的机器上试:
cat /sys/devices/soc0/machine—— 主控型号。这台读出IPQ5312,跟板上丝印完全一致。cat /sys/class/mdio_bus/*/*/phy_id—— PHY 的 ID。这台读出0x004dd101,正是 QCA8081 的 PHY ID。不用拧一颗螺丝,就能认出 2.5G 口是谁带的——这一条是整篇文章里性价比最高的。cat /proc/mtd—— 全部分区与容量,能反推闪存大小和 A/B 布局。ubinfo -a—— UBI 设备的数量、每个卷的大小与类型。这台读出 2 个 UBI 设备、3 个卷,就是前面那张表。ls /lib/modules/$(uname -r)/—— 驱动目录,能看出固件「预置了哪些硬件支持」。本次挖出的那颗没被加载的yt_phy_module.ko就是这么翻到的。cat /proc/modules—— 已加载的内核模块,带厂商前缀的(yt_、qca_、miwifi_)都能对上板上或固件里的一块。cat /proc/interrupts—— 中断名能反推总线和外设,本次靠它认出 5G 射频走 PCIe。cat /proc/net/dev—— 接口命名能反推链路是怎么分的。cat /proc/cpuinfo—— 核数、架构、指令集扩展。cat /proc/mounts—— 谁挂在哪、哪个卷是加密的。
也有两条我跑了却没拿到有用输出,一并记下来,省得别人再踩:
dmesg | grep -iE "nand|ubi|phy|switch"—— 这条我原本很期待,结果只匹配到一堆无线日志。原因是phy这个关键词撞上了日志里的phymode,真正的闪存识别、PHY 注册信息一条都没打出来。想在开机日志里找硬件信息,关键字得再收窄一点(比如dmesg | grep -i nand),或者干脆直接dmesg | head -200从头看。cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies—— 这条我还没跑。它能确认这颗 CPU 到底有没有多档频率,是「CPU 到底什么来路」那一节剩下的最后一个问号。
我一直觉得,「读固件」比「抄参数表」有意思的地方就在这儿:参数表是厂商写的宣传材料,而固件是这台机器自己在说的话。两边的口径对上了,你才知道参数是真的;对不上,你才知道该怀疑谁。
这台机器还能再挖的东西
拆完这一轮,我给自己留了几条没解的问题,一并写出来:
- CPU 那一条还差最后一环:核编号的权威对照我手上没有,得看
scaling_available_frequencies有没有多档,或者直接问高通。文章里我把那段标成了「这是解释,不是结论」,等更硬的资料来推翻或者确认。 HT2533这颗功放的规格书:丝印三行我读全了,但公开渠道查不到 datasheet。谁手上有,欢迎补一份。- 闪存的实际可写寿命:128MB SLC 的标称擦写次数不低,但真正能随便写的地方只有
cfg那个 23MB 的卷,长期写日志的机器值得盯一下。
这台机器的固件侧我还写过一篇(就是开头提到的那篇),讲怎么在不拧螺丝的情况下拿到 shell、以及顺手挖到的两个漏洞。硬件和软件一起看,这台机器才算是被看完整了:小米 BE3600 固件漏洞挖掘:命令注入、任意文件读取与利用工具。同一系列的还有几台设备,硬件路线不同,方法是一样的:中兴 BE7200Pro+ 的固件预览、联通 HG3142F 光猫拆解。
工具下载
固件侧那些命令,是用这个工具跑的。文件名:MiWiFi-RD15-Toolkit-v1.2.exe
分享链接:https://ug.link/xiaozou/filemgr/share-download/?id=df8d8a98a4e344c8bceb862ca554f6c9
访问密码:tpqa
顺便把小米 BE3600 的硬件详情也公开了:
分享链接:https://ug.link/xiaozou/filemgr/share-download/?id=9dee538b86ff49bd9df7e77baed80d4a
访问密码:dsjQ
免责声明
这台机器是我自己买的、已经过保,所有芯片型号都是从这台机器的实物丝印上读出来的,固件数据都来自这台机器本身。拆解有损坏设备的风险,请自行评估;文中提到的命令也请只在自己的设备上执行。
文中凡是引用外部资料的地方都给了链接,凡是只有单一证据、我没法坐实的地方,都单独注明了「这是解释,不是结论」。

Comments NOTHING