技术分析文章,剖析 CVE-2024-20154——MediaTek MT6769 NB-IoT 基带固件中的栈缓冲区溢出漏洞,涵盖逆向工程与利用链。
分类: CWE-121 — 基于栈的缓冲区溢出
严重性: 严重(MediaTek 公告)· 8.8 高危,攻击向量:相邻(CISA-ADP)
类型: 远程代码执行 — 无需用户交互,无需事先关联
披露: MediaTek 安全公告,2025 年 1 月 6 日 https://corp.mediatek.com/product-security-bulletin/January-2025
分析目标: Samsung Galaxy A14 SM-A145R — MT6769 系列(Helio G80),属于 MediaTek 受影响芯片组列表 - 固件在安全条件下进行了仿真。
状态: 已修补。
这是我首次发表的基带研究。我的背景与电信基础设施、合法拦截中介层、stingray 和 IMSI-catcher 分析以及嵌入式设备安全相去甚远——我之前从未对蜂窝调制解调器进行过深入的固件逆向工程。我想向自己证明,结构化的分析方法论能够适应不同的目标,而对特定平台的熟悉程度可以被严谨的链路追踪所替代。NB-IoT 之所以引人注目,是因为它处于一个真正危险的交叉点:该协议专为资源受限的 IoT 设备设计,攻击面是预关联的,而且无论手机用户在做什么,调制解调器协议栈都会处理它。
当对已修补的固件进行分析并确认漏洞模式不存在时,用于在针对特定函数之前对固件进行大规模分析的 AI 系统
独立地将重建的漏洞类别、条件和受影响的固件系列与 CVE-2024-20154 的描述相匹配。
技术结论是分析师本人的。
你口袋里的手机至少包含两台独立的计算机。你与之交互的那台运行 Android。另一台——基带——完全独立运行,处理所有无线电通信,并且对上层操作系统几乎完全不可见。Android 可能已完全修补。浏览器可能已被沙箱化。用户可能从未点击过恶意链接。如果漏洞代码位于调制解调器固件中,在应用处理器介入之前就处理无线电信号,那么这一切都无关紧要。
CVE-2024-20154 正是这类漏洞。
一个畸形的 NB-IoT 系统信息广播导致 MediaTek 调制解调器固件接受攻击者控制的调度计数,将该计数通过 RRC 到 L1 的配置路径传递而从不进行钳制,最终将其用作 NB-IoT 广播信道处理程序内部栈写入循环的循环边界。当计数超过目标数组的容量时,循环会越过它们写入,触及栈上保存的寄存器,并覆盖保存的返回地址。然后该函数将损坏的值恢复到返回地址寄存器中并跳转到它。
使其严重性如此之高的原因:
该漏洞在 MediaTek 2025 年 1 月 6 日的安全公告中发布,严重性评级为严重,影响包括 LR12A 调制解调器系列在内的多个系列。Samsung 将该修复纳入其 2025 年 2 月安全维护版本。
本文不发布武器化漏洞利用,且无法根据此处发布的内容复现。 目标是展示链路在哪里断裂、为什么每一层都未能阻止它,以及当你无法将调试器附加到实时调制解调器时,负责任地验证基带漏洞需要什么。
主要目标:Samsung Galaxy A14(SM-A145R)。无线电子系统由 MT6769 芯片组系列(Helio G80)中的 MediaTek 基带处理器驱动。MT6769 系列明确列在 MediaTek 针对 CVE-2024-20154 的受影响芯片组列表中。``` AP/CP firmware: A145RXXU1AWD1 Modem software: MOLY LR12A.R3.TC10.6M.A14.PR.SP.V1.P5 Build date: 2023-04-18
基带固件不是 Android 代码。它是 SoC 无线电子系统上的一个独立嵌入式系统,拥有自己的 CPU、自己的 RTOS 和自己的内存空间,位于 Android 进程沙箱之外。
### 2.2 调制解调器架构
对提取出的二进制文件的分析表明,调制解调器处理器运行 MIPS32,采用小端模式下的 MIPS16e2 压缩指令。MIPS16e2 是一种用于嵌入式代码体积缩减的 16 位编码扩展——这与联发科针对 Helio 代基带的方法一致,并得到了针对该 SoC 系列的独立公开基带研究的证实。
操作系统是 Nucleus RTOS,提供任务调度、IPC 消息队列和基于池的内存分配器。没有内核/用户特权分离,任务之间没有内存保护单元强制隔离,也没有硬件栈保护机制。
本文中的所有地址均为虚拟地址,在 Ghidra 中以基址 `0x90000000` 加载。
### 2.3 缓解措施(在分析的构建版本中观察到)
| 缓解措施 | 状态 | 效果 |
|---|---|---|
| ASLR | 缺失 | 固件地址是静态的,可从镜像中预测 |
| 栈金丝雀 | 缺失 | `SAVE`/`RESTORE` 存储被调用者保存寄存器时没有保护值 |
| NX / W^X | 缺失 | 栈内存可执行 |
| CFI | 缺失 | 返回地址未根据任何策略进行验证 |
### 2.4 分析方法
三条并行路径:
**静态分析。** 三星固件包 → CP 分区提取 → `md1img.img` → Ghidra(MIPS LE 32 位,基址 `0x90000000`),并使用 NCC Group 的 `mtk_bp` 工具集从固件调试段中恢复联发科工程符号。
**动态验证。** 使用 Unicorn Engine(MIPS32 仿真)分两个阶段隔离执行特定的固件例程。阶段 1 试图通过原生指令对证明 `si_count` 未经限制地复制到通道上下文中。阶段 2 在真实固件字节上执行了存在漏洞的循环,并确认固件自身的指令破坏了保存的返回地址。在阶段 1 无法完全原生运行的情况下——因为 CPHY 分发路径所需的 RTOS 服务对象环境未被重建——副作用被直接建模,并在所有输出中如此标注。
**无线电侧验证。** 使用带 ZMQ 回环的 srsRAN 4G——纯软件,无射频发射——确认测试载荷能够在 NB-IoT PHY 编码和传输块传递后存活。
---
## 3. 攻击面:NB-IoT 与 SIB1-NB
### 3.1 关联前攻击面
NB-IoT(窄带物联网)是 3GPP Release 13,旨在利用现有授权 LTE 频谱连接资源受限的 IoT 设备。它被实现在包括消费级智能手机在内的多种现代蜂窝 SoC 中。
在 RRC_IDLE 状态下,在任何 RRC 连接建立之前,搜索服务的设备将:
1. 与小区的时间信号同步(NPSS/NSSS)
2. 通过 NPBCH 解码主信息块(640 ms 传输窗口)
3. 从 NPDSCH 解码 SIB1-NB(2560 ms 调度)
4. 使用 SIB1-NB 中的调度信息定位其他系统信息块
在第 3 步,调制解调器在任何连接或用户交互之前,处理来自一个它尚未认证的实体的消息。满足正常小区选择条件的恶意发射机将被处理。```
+------------------+ +---------------------+
| Rogue Base Stn | | Target UE (Modem) |
+--------+---------+ +----------+----------+
| |
| NPSS/NSSS sync |
|--------------------------------------->|
| MIB-NB (640 ms cycle) |
|--------------------------------------->|
| SIB1-NB (malformed, si_count > 8) |
|--------------------------------------->| ← vulnerability triggered
| [no RRC connection established] |
SIB1-NB 定义于 3GPP TS 36.331。其 schedulingInfoList 字段携带小区广播的系统信息消息数量,规范将其限制为最多 8 个条目(1..maxSI-Message-NB-r13 = 8)。这是协议层约束。内存安全约束——即列表长度不得超过目标数组的容量——必须由固件单独强制执行。
但事实并非如此。
固件从三星 CP 包中获取,并使用 NCC Group 的 mtk_bp 工具集进行提取:```
md1img.img → md1_extract.py → 000_md1rom (17.8 MB code image)
→ 017_md1_dbginfo (XZ-compressed CATI debug symbols)
CATI 调试段通过 `mtk_dbg_extract.py symbols` 解压并解析,随后通过 `ImportSymbolsScript.py` 导入 Ghidra。结果是在整个调制解调器栈中获得了完整的内部函数名——ERRC 层、L1 信道管理、IPC 子系统以及 NB-IoT BCCH 处理链——从而支持语义引导的链重建。
本文中所有函数名均来自从固件镜像中提取的 MediaTek 自身嵌入的调试符号。
---
## 5. 漏洞
### 5.1 存在漏洞的循环
`el1_ch_nbcch_resume_req`(`0x90213940`)处理 NB-IoT 广播信道恢复事件。其 MIPS16e2 函数序言:```asm
90213940: save 0xE8, ra, s0-s1
SAVE 指令将 sp 递减 0xE8,并向下存储被调用者保存的寄存器:```
old_sp (= new_sp + 0xE8)
new_sp + 0xE4 saved ra ← overflow target
new_sp + 0xE0 saved s1
new_sp + 0xDC saved s0
new_sp + 0x98 si_sched_arr [34 halfwords = 68 bytes]
new_sp + 0x78 si_type_arr [32 bytes]
new_sp + 0x00 ← stack pointer after SAVE
从实际固件二进制文件的 Ghidra 反编译结果来看:```c
for (uVar6 = 0; uVar6 < (byte)param_2[0x40a]; uVar6 = uVar6 + 1) {
si_type_arr[uVar6] = /* SI type byte */; // 1 byte/iter, base new_sp+0x78
si_sched_arr[uVar6] = /* SI schedule halfword */; // 2 bytes/iter, base new_sp+0x98
}
param_2[0x40a] 是 ch_ctx[+0x40A] —— 通道上下文 BSS 结构体中的一个持久字节。
循环边界被直接使用,没有事先与数组容量进行比较。
流 A(半字 sh 写入)从 new_sp+0x98 开始,每次迭代前进 2 字节。
它在第 38 次迭代时到达位于 new_sp+0xE4 的保存 RA:```
new_sp + 0x98 + i×2 = new_sp + 0xE4
i = (0xE4 - 0x98) / 2 = 0x4C / 2 = 38
流 B(字节 `sb` 写入)从 `new_sp+0x78` 开始,需要迭代 108 次才能到达 RA 槽位:```
new_sp + 0x78 + i = new_sp + 0xE4
i = 0xE4 - 0x78 = 108
当 si_count = 40(演示值,选择该值是为了超过 38 的溢出阈值)时,
循环运行 40 次迭代。Stream B 永远不会到达 RA 槽位。RA 损坏完全
来自 Stream A。
经过 40 次迭代后,MIPS16e2 RESTORE 指令从栈中重新加载被损坏的值
到 $ra,然后 jrc ra 转移控制权。
ch_ctx[+0x40A] 由 el1_ch_nbcch_start 在 0x90213444 处写入。两条连续的 MIPS
指令,它们之间没有任何内容:```asm
; el1_ch_nbcch_start @ 0x90213444
lbu v0, 0x99(s0) ; read IPC_msg[+0x99] = si_count from CPHY_CFG_REQ
sb v0, 0x40A(s1) ; write to ch_ctx[+0x40A] — no clamp, no mask, no compare
### 5.4 ERRC 构建器 — 层 A
CPHY_CFG_REQ 缓冲区在 ERRC 层中由解码后的 SIB1-NB 构建。函数
`errc_chm_l1_set_bcch_si_reception` 写入 `IPC_msg[+0x99]`:```c
// errc_chm_l1_set_bcch_si_reception — Layer A
// Loop bound: decoded schedulingInfoList entry count from SIB1-NB
while (bVar3 < *(byte *)(param_3 + 0x44) && (param_2 != 0)) {
bVar3++;
if (uVar2 != param_2) {
*param_5 = *param_5 + 1; // CPHY_CFG_REQ[+0x99]++ — no upper bound check
}
}
循环边界是来自 SIB1-NB 的解码条目数。计数器每解码一个条目递增一次,递增次数等于已解码的条目数,没有最大限制保护。
一旦 CPHY_CFG_REQ 缓冲区被填充,ERRC 会将其分发给 L1,并使用 sap_id = 0x501F 作为路由键:```
el1_ch_rcv_ilm (sap 0x501F)
→ el1_chmgm_errc_cfg_req_in_idle ← stores CPHY_CFG_REQ @ L1_ctx[+0x323C]
→ el1_chmgm_nbcch_handler
→ el1_ch_nbcch_main
→ el1_ch_nbcch_cphy_cfg_req_process ← validates cell identity, no si_count check
→ el1_ch_nbcch_start @ 0x90213444 ← Layer B: lbu + sb, no clamp
### 5.6 三层缺失的钳位
| 层级 | 函数 | 地址 | 是否存在钳位? |
|---|---|---|---|
| A — ERRC 构建器 | `errc_chm_l1_set_bcch_si_reception` | ERRC 范围 | **无** |
| B — L1 拷贝 | `el1_ch_nbcch_start` | `0x90213444` | **无** |
| C — L1 循环 | `el1_ch_nbcch_resume_req` | `0x90213940` | **无** |
任何一层中的任何单一检查都会打破这条链。
### 5.7 根本原因
一个被违反的不变量:
> SI 调度条目的数量绝不能超过目标数组的容量。
3GPP 提供了预期的协议边界(8 个条目)。固件需要在每一层强制实施内存安全边界,即计数变为索引或循环限制的地方。在易受攻击的构建中,计数从 SIB1-NB 广播字段出发,经过 ERRC 解码器,进入 CPHY_CFG_REQ 消息,跨越 IPC 边界进入 L1 任务,进入通道上下文 BSS,并进入一个栈写入循环——没有任何一层对其进行钳位。
---
## 6. 调用链——如何被发现
### 6.1 两条路径的混淆
两条结构相似但不同的路径可以将一个 0x760 字节的配置缓冲区传递给 `el1_ch_nbcch_main`:
| 路径 | 来源 | `[+0x99]` 值 | 相关性 |
|---|---|---|---|
| 路径 A(ERRC → L1 IPC) | ERRC 从解码的 SIB1-NB 构建 CPHY_CFG_REQ | 来自 OTA 的 `schedulingInfoList.count` | **易受攻击的路径** |
| 路径 B(L1 内部) | `el1_ch_scs_ind_send` 构建内部 IPC 主体 | 硬编码 `1` | 不易受攻击 |
路径 B 确认了消息格式——字节 `+0x99` 是 `el1_ch_nbcch_start` 所消费的 SI 计数。由于其计数始终硬编码为 1,因此不会溢出。受外部影响的路径是路径 A。
### 6.2 写入者搜索
在固件中模式搜索任何写入偏移 `+0x99` 的指令产生了噪声:T1(直接 `sb`,约 100 次命中),T2(拆分基址,5 次命中),T3(计算偏移,0 次),T4(重叠的 `sh`/`sw`,约 465 次)。ERRC 通道管理函数在 `msg_send6` 交叉引用列表中缺失,因为 ERRC 使用 `errc_com_send_msg`。一次仿真探测确认写入发生在 ERRC 侧:从 L1 调度器运行 Unicorn 测试框架并监视对缓冲区 `+0x99` 偏移的写入,从 L1 侧没有捕获到任何内容。```
[RUN] dispatcher=0x90214418 watching IPC_msg+0x99
NO writes to IPC_msg+0x99 caught from dispatcher.
Write happened before el1_ch_nbcch_main — confirmed ERRC-side.
在 errc_com_send_msg 中跟踪 sap_id = 0x501F 确定了到
el1_chmgm_errc_cfg_req_in_idle 的路由,该函数将 CPHY_CFG_REQ 指针存储在
L1_ctx[+0x323C] 处,并开始下游分发。
SIB1-NB schedulingInfoList.count (demonstrator: 40) │ ▼ [ERRC task] errc_chm_ch_ctrl_req_hdlr → errc_chm_call_ctrl → errc_chm_l1_main → errc_chm_l1_call_ctrl → errc_chm_l1_snd_cphy_cfg_req ← allocates 0x760-byte CPHY_CFG_REQ → errc_chm_l1_set_cphy_req_nbcch_cfg → errc_chm_l1_set_bcch_inf → errc_chm_l1_set_bcch_si_reception ← Layer A: CPHY_CFG_REQ[+0x99] = 40 → errc_com_send_msg(sap=0x501F) ← IPC to L1 │ ▼ [L1 task] el1_ch_rcv_ilm (sap 0x501F) → el1_chmgm_errc_cfg_req_in_idle ← stores CPHY_CFG_REQ @ L1_ctx[+0x323C] → el1_chmgm_nbcch_handler → el1_ch_nbcch_main → el1_ch_nbcch_cphy_cfg_req_process ← no si_count validation → el1_ch_nbcch_start @ 0x90213444 ← Layer B: lbu + sb, no clamp │ ▼ ch_ctx[0x40A] = 40 (persists in BSS) │ ▼ [state machine advances to 0x0B, event 0x2C] el1_ch_nbcch_resume_req @ 0x90213940 ← Layer C: loop bound from ch_ctx[0x40A] │ ▼ stack overflow → jrc ra → PC = attacker-controlled
---
## 7. 验证
这个特定的 SM-A145R 型号在正常的 ship-build 操作中似乎不会触发存在漏洞的 NB-IoT 代码路径,这就是为什么使用了混合仿真和静态分析,而不是直接进行硬件复现。
**静态验证。** 固件二进制文件中包含存在漏洞的指令对。调用链是根据符号、交叉引用和反编译的函数体重建的。
**在仿真中本机执行。** `el1_ch_nbcch_resume_req` 内部的循环在 Unicorn Engine(MIPS32)中基于真实的 MediaTek 固件字节运行。固件自身的 `sh` 指令在 `0x90213B02` 处写入了保存的返回地址槽。`RESTORE` 指令将损坏的值加载到 `$ra` 中,`jrc ra` 转移了控制流。
**显式建模。** `el1_ch_nbcch_start` 中的 `lbu`/`sb` 复制无法完全本机运行,因为 `el1_ch_nbcch_cphy_cfg_req_process` 内部的 RTOS 回调表分发路径需要活跃的 Nucleus 堆对象,而扁平仿真器无法提供这些对象。第二阶段中的恢复处理程序(`el1_ch_nbcch_resume_req`)仅从驻留在 BSS 中的通道上下文读取,不会命中相同的分发路径,这就是为什么第二阶段无需相同的脚手架即可本机运行。第一阶段的副作用——从 `IPC_msg[+0x99]` 写入 `ch_ctx[+0x40A]` 的一个字节——被直接建模并标记为 `[PHASE1-MODEL]`。
**未声称。** 完整的端到端空中硬件复现。
### 7.1 防篡改
测试框架强制执行了一条规则:不允许任何钩子将证明标记写入保存的返回地址槽。每一次非固件内存写入都被跟踪。```
[PROOF-W] saved_RA write: pc=0x90213b02 addr=new_sp+0xE4 value=0xbeef
[PROOF-W] saved_RA write: pc=0x90213b02 addr=new_sp+0xE6 value=0xdead
[ANTI-TAMPER] no hook wrote RA=0xDEADBEEF — firmware only
anti_tamper_fail = False
0x90213B02 是循环体内部的 sh 指令。固件将这些字节放置在
预测的栈偏移处。在小端序存储中,位于 new_sp+0xE4 和 new_sp+0xE6 的半字
0xBEEF 和 0xDEAD 组合为 [ef be ad de] = 0xDEADBEEF。
[REGS] RA = 0xdeadbeef ← firmware wrote this; decisive proof PC = 0x00000000 ← Unicorn unmapped-fetch artifact, not a hardware exception vector
[STACK] new_sp+0xE4: [ef be ad de] ← little-endian 0xDEADBEEF
[PC-EXPLAIN] PC=0 is an unmapped-fetch artifact; decisive proof is RA=0xDEADBEEF + stack bytes [ef be ad de] + [PROOF-JRC] CONFIRMED: saved RA = 0xDEADBEEF
### 7.3 ZMQ 传递
为确认测试载荷在 NB-IoT PHY 编码和传输块传递后仍能保持完整,使用了带 ZMQ 回环(无射频发射)的 srsRAN 4G。载荷是一个刻意构造的非合规向量——`schedulingInfoList` 上的 ASN.1 SIZE 约束被放宽以允许 40 个条目,并通过 pycrate 往返解码确认了第 14 字节处的计数字段。```
SIB1 received
SIB2 activated
exit 0
这证实了传输层投递。固件侧的 ASN.1 行为由 Layer A 静态分析确立。
el1_ch 任务只有一个栈。阶段 1 和阶段 2 是两个独立的 IPC 事件,由同一任务顺序处理,两者之间栈完全展开。计数持久保存在通道上下文 BSS 中,而非栈上:```
EVENT: CPHY_CFG_REQ (Phase 1)
el1_ch_nbcch_start
lbu v0, 0x99(s0)
sb v0, 0x40A(s1) ← ch_ctx[0x40A] = attacker value, written to BSS
returns — stack fully unwound
EVENT: resume (state 0x0B, msg 0x2C) (Phase 2) el1_ch_nbcch_resume_req ← frame 0xE8, reads ch_ctx[0x40A] as loop bound loop × 40 → saved RA corrupted jrc ra → attacker-controlled PC
`ch_ctx[0x40A]` 位于 BSS 中,并保留攻击者的值,直到调制解调器重置或后续通道配置将其覆盖。
### 8.2 栈帧```
old_sp (= new_sp + 0xE8)
new_sp + 0xE4 saved ra
new_sp + 0xE0 saved s1
new_sp + 0xDC saved s0
new_sp + 0x98 si_sched_arr [34 halfwords = 68 bytes]
new_sp + 0x78 si_type_arr [32 bytes]
仿真测量确认了帧大小。仿真结果确认了数组位置——RA 在迭代 38 处写入,与 si_sched_arr 从 new_sp+0x98 开始一致。
| 构建 | 调制解调器固件 | 构建日期 |
|---|---|---|
| 易受攻击 | A145RXXU1AWD1,MOLY LR12A...V1.P5 | 2023-04-18 |
| 已修补 | A145RXXUDDZC2,MOLY LR12A...V3.P8 | 2025-04-23 |
构建日期通过从两个镜像中提取 md1_dbginfo 元数据确认。补丁 ID:
MOLY00720348 · 问题 ID:MSV-2392。
el1_ch_nbcch_start(易受攻击二进制中的 0x90213444): lbu/sb 指令
对已不存在。将 IPC_msg[+0x99] 直接复制到 ch_ctx[+0x40A] 的操作已消失。
el1_ch_nbcch_resume_req(易受攻击二进制中的 0x90213940): 对
ch_ctx[0x40A] 进行栈写入的循环已不存在。不受信任的字节成为固定大小栈数组
循环边界的架构已不复存在。函数体被替换为不同的分发结构。
errc_chm_l1_set_bcch_si_reception: 无界计数器循环被替换为
面向验证的辅助函数调用。
已修补二进制中存在两个函数,而易受攻击二进制中不存在:``` el1_ch_nbcch_param_check el1_ch_scell_param_check
单行边界检查会表现为在相同地址的现有函数内部添加的几条指令。而修补后的二进制文件所展示的是一次架构层面的修订:NBCCH 调度路径被重新设计,使得 `si_count` 作为循环边界的模式在该路径中不再存在。
### 10.4 CVE 归属
此处描述的漏洞与 MediaTek 于 2025 年 1 月 6 日发布的 CVE-2024-20154 相符。确认依据:
- 受影响的固件系列(LR12A)与 MediaTek 的公告相符。
- 漏洞类别——栈溢出、缺少边界检查、来自恶意基站的 RCE、无需用户交互——与 CVE 描述及 NVD 记录相符。
- 修补后的固件恰好移除了被识别为存在漏洞的代码结构。
- 补丁 ID MOLY00720348 已从 MediaTek 的公告和 Android 安全公告(A-376809176)中确认。
- AI 辅助分析在人工确认之前,独立地将重建的模式匹配到了 CVE-2024-20154。
---
## 11. 伦理与负责任披露
### 11.1 本文不包含的内容
没有武器化的漏洞利用。没有固件二进制内容。没有畸形的载荷字节。没有针对真实设备触发该漏洞的分步操作流程。复现一个可工作的攻击所需的信息——针对特定调制解调器解码器的完整载荷构造、用于完整 Phase 1 仿真的 RTOS 堆对象脚手架、空口无线电配置——均被有意省略。
### 11.2 为什么 ZMQ 回环与仿真是合乎伦理的方法
ZMQ 回环意味着从未通过空口发送任何信号。没有针对任何真实设备。没有涉及运营商网络。该验证完全在分析师自有硬件上的受控软件环境中运行。这是验证预关联无线电漏洞的正确方法——发送畸形广播会影响范围内的任何设备。
Unicorn 仿真证明,该易受攻击的行为存在于固件二进制文件本身之中,可复现,且独立于任何特定设备状态或无线电环境。这比单次硬件崩溃在技术上更具说服力,并且避免了通过空口部署任何内容。
### 11.3 MediaTek 知识产权
所有分析均基于从消费级设备合法获取的固件以及三星公开发布的固件包进行。未使用任何专有文档。MediaTek 内部结构体定义和 IPC 消息格式仅在解释内存安全故障所必需的范围内进行描述。它们并未作为规范发布。
---
| 迭代 | sh 写入到 | 效果 |
|---|
| 0–33 | si_sched_arr[0..33] | 在边界内 |
| 34–35 | new_sp+0xDC — 保存的 s0 | s0 被损坏 |
| 36–37 | new_sp+0xE0 — 保存的 s1 | s1 被损坏 |
| 38 | new_sp+0xE4 — 保存的 ra [15:0] | RA 低半字 |
| 39 | new_sp+0xE6 — 保存的 ra [31:16] | RA 高半字 |
| 门控 | 条件 | 检查位置 |
|---|
| NB-IoT 活动路径 | cfg_type == 1 | el1_ch_nbcch_cphy_cfg_req_process |
| 信道未完成 | done_flag == 0 | ch_ctx[0x438] |
状态机 0x0B | NBCCH 处于恢复状态 | el1_ch_nbcch_main 分发 |
| si_count 非零 | ch_ctx[0x40A] > 0 | 循环条件 |
| 频段类别 ≤ 2 | 有效 NB-IoT 模式 | el1_ch_nbcch_resume_req 入口 |
el1_chmgm_cell_info_get 非零 | 小区在服务表中 | 在 el1_ch_nbcch_start 中调用 |
| 函数 | 地址 | 作用 | 是否钳制? |
|---|
errc_chm_l1_set_bcch_si_reception | ERRC 范围 | 写入 CPHY_CFG_REQ[+0x99] | 无 |
el1_ch_nbcch_cphy_cfg_req_process | 0x90213F80 | 将 CPHY 配置路由到 L1 | 不适用——不读取 si_count |
el1_chmgm_cell_info_get | 0x9020E0D0 | 验证 EARFCN/PCI | 不适用 |
el1_ch_nbcch_start | 0x90213444 | 将计数复制到 BSS | 无 |
el1_ch_nbcch_resume_req | 0x90213940 | 将计数用作循环边界 | 无 |