上一篇写这台小米 BE3600 的固件漏洞时,我从头到尾没拧一颗螺丝。主控是什么、内存多大、闪存多少,全是从 /proc 和 /sys 里读出来的,那篇里也交代过一句:这些数字只能说明系统自己怎么说,证明不了板子上到底焊了什么。想看板上焊的是什么,只能把机器拆开。

这篇就是拆的过程。顺序是:先把丝印认一遍,确定了七颗主芯片的型号,再掉过头去固件里一条一条对账——对得上就写进来,对不上的单独列一节。认芯片这件事,只看别人的拆机图会认错,自己拍的照片不放大也会认错,所以下面每一颗型号都是从板上丝印读出来的,并且都配了放大后的实物图。

先把结论摆出来,免得看一半不知道拆出了什么:

角色板上丝印说明
主控 SoCQualcomm IPQ5312四核 ARMv7,1.1GHz,内置 2.4G 射频
内存Rayson RS128M16V8DB-107AT128M×16 = 256MB DDR3
闪存GigaDevice GD5F1GM7REYIG1Gbit = 128MB SPI NAND
千兆交换MOTORCOMM YT9215S5+2 口千兆交换控制器
2.5G PHYQualcomm QCA8081单口四速,最高 2500BASE-T
5G 射频Qualcomm QCN6402只做 5G 频段,2×2
2.4G 功放HT2533丝印三行读全后的型号位;公开渠道无规格

先把话说到前头。这台机器是我自己买的、自己拆的,拆之前已经过了保修期。拆解会破坏外观、可能弄丢卡扣,也可能因为静电把板子打坏——要不要拆、拆坏了算谁的,你自己掂量。另外这篇里所有判断都只对我手上这一台成立,同型号不同批次的物料是可能被替换的,后面第三节会用实例说明为什么这事很容易踩坑。

拆之前,先把这台机器的接口和型号记清楚

小米 BE3600 2.5G(RD15)机身正面,四根固定式天线与单颗状态指示灯
机身正面。四根天线是固定死的,不能转向;正面只有一颗状态指示灯,没有多余的按键。
小米 BE3600 背部接口,四个 RJ45 网口标注 1、2、3 与 4(2.5G),另有 RESET 小孔和 MESH 键
背部的接口全貌: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:

小米 BE3600 主板 PCB 上的 xiaomi 与 MD15 丝印特写
板上印的是 MD15,不是 RD15。这台机器的型号在三个地方写法都不一样:卖的时候叫 RD15,PCB 上是 MD15,天线料号里又夹着 -RD-。

再往细看,PCB 上还有一行 M015.R0110 和日期 20250207——板子是 2025 年 2 月 7 日打样的。固件那边 /proc/version 里写的构建时间是 Thu Mar 20 02:49:04 2025,中间隔了六周。物料、打板、出固件,这条时间线是能够互相咬上的,这类交叉验证在拆解文里比单看一张图有意思得多。

小米 BE3600 底部只有一颗固定螺丝,拆下后即可分离外壳
底面总共只有一颗螺丝,其余全靠卡扣。拧下它,剩下的就是耐心和塑料撬片的事了。

要拆的话,从底面这一颗螺丝开始。

拆开之后:一块窄板,四片屏蔽罩

小米 BE3600 拆开后的外壳与四根天线组件,天线为白色塑料壳内嵌黑色 PCB 振子
拆开后的全貌。四根天线其实都是白色塑料壳里嵌一片黑色 PCB 振子,靠一条馈线连到主板——不是那种绕线圈的金属天线。

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

小米 BE3600 主板正面全貌,取下屏蔽罩后可见主控与内存布局,PCB 丝印为 MD15
主板这一面。板子左上角有 xiaomi 和 MD15 丝印,右下的四根网口在另一面。所有大芯片都躲在屏蔽罩里,这也是为什么只看外观根本认不出用料。
小米 BE3600 主板背面,可见四个 RJ45 网口、网络隔离变压器与 DC 电源座
翻过来这一面就是网口、变压器和电源座。四个 RJ45 挤在一排,右边那颗 PPT PS M-2443 是网口的隔离变压器。

主板是窄长条。你注意一下这个布局:四颗大芯片全部集中在板子的一侧,网口和电源全在另一侧。这不太常见——一般路由器会把网口和交换芯片放在一起,这颗却把交换芯片留在了芯片那一面,只用走线把信号引到背面的 RJ45 上。

散热结构也在这一面:主板上盖了一块均热铝板,铝板下面是四片屏蔽罩,每片罩子里对应一块导热垫。

小米 BE3600 主板带屏蔽罩状态,可见覆盖主控与射频区域的金属屏蔽框
带屏蔽罩的时候是这样。散热和屏蔽是同一套金属框,芯片的背面还贴着一块均热铝板。
小米 BE3600 的均热铝板与屏蔽框,框上留有导热硅脂垫与蓝色导热垫
取下来的均热铝板与屏蔽框。框上有几处导热垫印子,能反推出下面压着哪几颗芯片、各自多大。

取下来的铝板上留着几块导热垫的印子,形状和位置刚好能反推出下面压着哪几颗芯片、各自占多大——这算是拆机时一个免费的好处:不用悬空猜芯片位置。顺便说,这种「芯片背面贴铝板、正面透到外壳散热」的做法,效率上不如让芯片正面直接压散热片,但在这个功耗档位够用;我在其他机器上见过类似设计(联通 HG6371F 从猫那篇里主板就是这样)。

一颗一颗认:板上这七颗主芯片

下面每一颗都是把丝印放大到能看清字才写的。手机拍的原图直接看是读不准的,尤其是批次码和最后几位,字又小又有反光。

主控:Qualcomm IPQ5312

小米 BE3600 主控芯片特写,丝印为 Qualcomm IPQ5312 003
主控:Qualcomm IPQ5312 003,最后一行 FE547HLS 是批次码。固件里 /sys/devices/soc0/machine 读出来也是 IPQ5312——这一条软硬件对得上。

这颗在上一篇里已经出现过——当时是从 /sys/devices/soc0/machine 读出来的字符串。现在有了实物对照,两边是同一个型号,这一条可以确定。

内存:Rayson 256MB DDR3

小米 BE3600 内存颗粒特写,丝印为 Rayson RS128M16V8DB-107AT,128M×16 即 256MB DDR3
内存颗粒:RS128M16V8DB-107AT。128M×16 就是 2Gbit,也就是 256MB;-107 是速度等级,换算下来是 DDR3-1866,跟工具从系统里读到的 1866MHz 对得上。

这一颗是这篇文章里最能体现「认丝印」价值的地方,原因见下一节。

闪存:GigaDevice 128MB SPI NAND

小米 BE3600 闪存芯片特写,丝印为 GigaDevice 5F1GM7REYIG,1Gbit SPI NAND 即 128MB
闪存:GigaDevice(兆易创新)的 SPI NAND,完整的料号是 GD5F1GM7REYIG——板上左边缘那颗被屏蔽框压住了一半,所以只看得到 5F1GM7REYIG。查料号表,1G 这一段是容量位,1Gbit = 128MB。

把料号拆开看:GD 是厂商,5F 表示 SPI NAND,1G 是容量位,R 表示 1.8V 供电,Y 是 WSON8(8×6mm)封装,I 是工业温度范围。这颗只有 128MB,不是 256MB——这一点后面跟固件的分区表对上了,是全文最关键的一处交叉印证。

另外,闪存焊在板子最边缘,一部分被屏蔽框压住,所以丝印开头两个字母被挡掉了。只看照片很容易把它当成一颗来路不明的芯片。

小米 BE3600 主控与内存颗粒共处同一屏蔽框内,右侧为 256MB DDR3 内存
屏蔽框里的两颗:左边 IPQ5312,右边 256MB DRAM。主控和内存贴得这么近,是为了把 DDR 的走线做到最短。

千兆交换:MOTORCOMM YT9215S

小米 BE3600 千兆交换芯片特写,丝印为 MOTORCOMM YT9215S,旁边是 25MHz 晶振
千兆交换: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

小米 BE3600 的 2.5G 网口 PHY 芯片特写,丝印为 Qualcomm QCA8081 002
2.5G 网口那颗 PHY: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

小米 BE3600 的 5G 射频芯片特写,丝印为 Qualcomm QCN6402 001,旁边是 48MHz 晶振
5G 射频: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 这一侧,还有颗功放

小米 BE3600 的 2.4G 射频区,屏蔽框内可见 2.4G 功放芯片,丝印以 8245 开头
2.4G 这边是主控内置射频加外置功放。屏蔽框里那颗小功放芯片的丝印有三行:8245SD、971446、HT2533。左边橙色丝印的 2G_0/2G_1 是两路天线口。

主控内置射频的发射功率通常不够,所以要外挂功放(FEM)。2.4G 这一侧屏蔽框里那颗小功放芯片,丝印一共有三行:

8245SD
971446
HT2533

公开那篇同型号拆解只读了第一行 8245SD,据此认成 KCT8245SD。把三行读全,最下面那行 HT2533 才更像型号位——第一行往往是批次或序列号,不是型号。这颗芯片的丝印排布本身就在诱导你认错。

但 HT2533 这个型号,我在公开渠道没查到规格书。所以这一颗我只给丝印原文,不给结论。三行字都在上面的图里,谁认得这颗,欢迎告诉我。

那为什么软件侧查不到它?这个问题的答案涉及功放这类芯片的本质,我在后面「拆完再回固件里对账」那一节专门写了一段——因为证据也在那边。

四根天线,两根 2.4G 两根 5G

小米 BE3600 的四根天线并排展示,每根天线内部都是一片黑色 PCB 振子并标注了料号
四根天线摆一排。每片黑色 PCB 振子上都有自己的料号,格式统一是 MD15-<频段>-<序号>-RD-V0.x-<批次>——MD15 对应 PCB,RD 对应产品平台,两个编号混在同一串料号里。
小米 BE3600 的 5G 天线 PCB 特写,料号丝印为 MD15-5G-1-RD-V0.3-2542
5G 那两片的料号是 MD15-5G-1-RD-V0.3-2542。同一台机器上四根天线并不都是同一个版本,2.4G 那两片就写到了 V0.5。
小米 BE3600 的 2.4G 天线 PCB 特写,料号丝印为 MD15-2.4G-2-RD-V0.5-2534
2.4G 那两片的料号是 MD15-2.4G-2-RD-V0.5-2534。把两份料号并排看,能确认这四根天线确实是两根 2.4G、两根 5G,而不是四根通用天线。

把天线拿下来单独看,两片的振子形状差别很大:

小米 BE3600 的 5G 天线 PCB 振子走线特写,馈电结构较为简单
把 5G 天线的 PCB 单独拿出来看:走线比较舒展,馈电点就在左边那个小孔。
小米 BE3600 的 2.4G 天线 PCB 振子走线特写,可见折叠的曲折线结构
2.4G 这片就明显不一样了:中间多出一段折叠的曲折线。2.4G 波长比 5G 长,要在同样长度的 PCB 上做出合适的电长度,就得把振子折起来。

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_switch450560裕太微 YT9215S 交换芯片的驱动
qca_ssdk901120高通交换 SDK
qca_nss_ppe409600NSS/PPE 硬件转发引擎
qca_nss_sfe237568快速转发卸载(Shortcut FE)
ipq_cnss2339968IPQ 的 NSS 核心驱动
ecm741376高通连接管理器,把转发卸载上去
umac / qca_ol / wifi_3_03522560 / 1507328 / 991232无线驱动栈(2.4G 与 5G 共用)
emesh_sp65536Mesh 组网
dm_req_crypt12288配置分区的加密卷
pwm_rgb / leds_gpio / button_hotplug12288 / 12288 / 12288指示灯、按键

前面认的那颗交换芯片,在这里被实锤了。板上丝印是 MOTORCOMM YT9215S,内核里挂着一个叫 yt_switch 的模块——名字里的 yt 就是裕太微。这条链路是「板上丝印 → 料号 → 内核模块名」三级对上的,比任何一张拆机图都硬。

顺带说,模块表里还有几个厂商私有的东西,一眼能看出是小米自己加的:local_gw_security、wan_check、ip_account、wandt_filter,以及一串 miwifi_xt 开头的统计模块。这些不是高通给的,是厂商在开源基础上补的业务逻辑,想看一台机器的固件「改了多少」,数这一类模块最直观。

小米 BE3600 上 cat /proc/modules 的原始输出截图,列出已加载的内核模块、内存占用与依赖计数
/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,不用去翻参数表。

小米 BE3600 上 cat /proc/net/dev 的原始输出截图,列出 eth0、eth1、wl0 等网络接口的收发字节与包数
/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,也就是这台机器有一个活的串口。板子边缘那几个圆形焊盘位置看着像它的引出点(这个我只对了位置,没实测),哪天真刷成砖了,那大概是最后的救砖通道。

小米 BE3600 上 cat /proc/interrupts 的原始输出截图,含 pci1_wlan_ce、q6v5_wcss 与 rxdma2host 等中断行
/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 设备建在哪个分区擦除块数算出来里面的卷
ubi0mtd19 rootfs336336 × 128 KiB = 42 MiBkernel(静态,10 MiB,实际数据 3.0 MiB)、ubi_rootfs(动态,23.3 MiB)
ubi1mtd23 overlay214214 × 128 KiB = 26.75 MiBcfg(动态,23.0 MiB)

两个数字都不差分毫:ubi0 的 336 个物理擦除块乘 128 KiB,正好是 rootfs 分区的 42 MiB;ubi1 的 214 个乘出来,正好是 overlay 分区的 26.75 MiB。所以前面那三条「逻辑卷」的身份也就定死了:

  • mtd24 kernel(3.0 MiB)= ubi0 的 0 号卷,静态卷,实际数据 3172002 字节——和 ubinfo 报的 Data bytes: 3172002 一模一样。
  • mtd25 ubi_rootfs(23.4 MiB)= ubi0 的 1 号卷,也就是当前的根文件系统。
  • mtd26 cfg(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

免责声明

这台机器是我自己买的、已经过保,所有芯片型号都是从这台机器的实物丝印上读出来的,固件数据都来自这台机器本身。拆解有损坏设备的风险,请自行评估;文中提到的命令也请只在自己的设备上执行。

文中凡是引用外部资料的地方都给了链接,凡是只有单一证据、我没法坐实的地方,都单独注明了「这是解释,不是结论」。

欢迎来到XiaoZou123,这里是一个电脑极客、数码爱好者网站。我平时喜欢关注数码新闻,研究计算机技术。如果你看我头像觉得我是二次元,那我其实还算不上!
最后更新于 2026-10-06