☰
Modem搜网注册全链路:SIM初始化、PLMN选择与小区搜索
2026/11/3 6:46:44 网站建设 项目流程

简介:《高通平台modem搜网注册流程》PPT面向5G通信协议开发、Modem测试与场测分析人员,聚焦终端开机后从初始化到成功驻网的核心链路。内容按初始化、PLMN与RAT选择、扫频与小区搜索、小区选择、随机接入、RRC连接建立及注册等阶段展开,并结合协议、代码和实际日志,说明SIM卡读取、MBN加载、policyman策略执行、SD选制式等关键行为,对分析掉网、无服务等问题有直接参考价值。压缩包仅含1个pptx文件,约1.59MB,篇幅集中、目录按流程组织,便于对照检索。已有5132人学习,适合Modem开发、协议栈测试及网络优化人员用于梳理搜网注册流程和排查思路。

1. 搜网注册:那两三秒里 modem 到底做了什么

手机重启,状态栏的信号图标两三秒就亮起来了。对做 modem 侧搜网注册的人来说,这两三秒里跑完的是一条从 SIM 卡文件系统一路走到核心网附着的完整链路:初始化、PLMN 与 RAT 选择、扫频与小区搜索、随机接入与 RRC 注册。每一环都有明确的入口和出口,也都能在 log 里找到对应的行。链路任何一处断掉,用户看到的现象都完全一样——无服务、仅限紧急呼叫、信号格闪一下就没了。这就是搜网类问题难查的根源:现象被抹平了,只剩下一堆模块和时间戳。5G NR 阶段这条链的骨架并没有变,只是 RAT 列表里多了一项,扫频和小区搜索换成了 SSB 那一套同步信号。下面按这条链本身的顺序,一段一段拆开看它是怎么被设计和实现的。

2. 初始化:SIM、EFS/NV、MBN 与 policyman 如何决定系统的先验

开机上电之后,modem 并不是"先扫频再说"。它要先建立一整套先验:这张卡是谁的、属于哪个运营商、这台终端在这个运营商下允许用哪些频段和制式、双卡时哪张卡优先。这些先验决定了后面扫频的范围、RAT 的尝试顺序,甚至决定了某些频点根本不会被扫。初始化阶段做错或做慢,后面所有阶段都会被拖累,而 log 里表现出的却只是"驻留慢"。

2.1 卡状态机:CARD_INSERTED 与 SUBSCRIPTION_READY 之间隔了什么

先看两行几乎每个搜网 log 都会出现的记录:

02:42:32.119 [ mmocmmgsdi.c 2072] =MMOC= CARD_INSERTED: Set sim_available_status on sub 0 02:42:34.929 [ mmgsdi.c 7938] MMGSDI_SUBSCRIPTION_READY_EVT, app: 0x3, slot: 0x1

第一条是物理检测:卡座电平变化,卡"在位"。第二条是逻辑就绪:卡内的应用(USIM/CSIM)已经激活,文件系统可读,后续才能去读 IMSI、EF_LOCI、EF_PLMNwAcT 这些搜网必需的文件。两行之间差了 2.8 秒,这 2.8 秒里做的是上电复位、协商传输参数、选应用、校验 PIN、建立文件系统通道——任何一步超时,后面就等不到 SUBSCRIPTION_READY。

这中间的旁证是电话本模块读紧急号码:

02:42:32.128 [ qmi_pbm.c 5580] Card ecc for session type 6: 110,120,119,999,911,122,118,08,000,112 02:42:32.128 [ qmi_pbm.c 5663] Hardcoded ECC : #911,*911,112,911

能读出卡内 ECC 表,说明卡的文件系统已经可访问。所以排查"开机很慢"时,第一刀切在这里:如果 CARD_INSERTED 有了但 SUBSCRIPTION_READY 迟迟不来,问题在卡侧或 UIM 驱动,跟射频、跟扫频一点关系都没有,别再去翻 RRC 的 log。

2.2 MBN 与 policyman:同一台终端换张卡行为就不一样

卡就绪的第一件事是把 IMSI 解析出来,取前几位得到 IMSI PLMN:

02:42:34.936 [ policyman_uim.c 1045] IMSI PLMN: (MCC 460, MNC 1, pcs_incl 0) 02:42:34.939 [ policyman_policy.c 209] subs 0: Started executing policy version 1101.2.7 (17720529) 02:42:34.939 [ policyman_policy.c 224] subs 0: Finished executing policy 1101.2.7 (8 ticks)

MCC 460 / MNC 01 就是这张卡的归属网络标识,它是后面选 MBN 的键值。紧接着 MCFG 模块按这个键去挑配置:

02:42:34.935 [ mcfg_uim.c 2379] Selecting config using IMSI MCC=460 MNC=1 02:42:34.949 [ mcfg_utils.c 913] Config: C3I_CN-LA-7+7_mode-SDM43902 02:42:34.949 [ mcfg_utils.c 913] Config: VoLTE-CU

MBN 是"运营商 + 地区 + 双卡形态"打包出来的配置集合,里面装着频段裁剪、测量门限、发射功率上限、VoLTE 开关这类参数。同一个硬件平台,插 A 运营商的卡和 B 运营商的卡,加载的 MBN 不同,支持频段列表和测量策略就不同——这是"同一台手机换卡后某些频点搜不到"最常见的解释,而不是硬件坏了一半。policyman 那一行的 8 ticks 是策略树的求值耗时,策略版本号变了意味着整棵树的决策结果都可能变,做对比测试时版本号必须对齐,否则两次 log 没有可比性。

2.3 SD 模块的 rat_acq_order:能力、卡、NV 三者求交

policyman 算完策略,把结果交给 SD(System Determination)去定"优先在哪个系统上取服务":

02:42:35.037 [ sdss.c 55272] =SD= PM -> SD: rat_acq_order for asubs_id 0, num_rat 3 02:42:35.037 [ sdss.c 55288] =SD= rat_acq_order[0]: 9 [1]: 5 [2]: 3 [3]: 0 [4]: 0 [5]: 0 02:42:35.037 [ sdss.c 55167] =SD= adding rat 2 to rat_acq_order index 3 02:42:35.037 [ sdss.c 55167] =SD= adding rat 4 to rat_acq_order index 4 02:42:35.037 [ sdss.c 55167] =SD= adding rat 11 to rat_acq_order index 5

policyman 只给了 3 个(num_rat 3),后面三个是 SD 自己补进来的旧制式兜底,0 是空位填充。这段顺序就是后续尝试的优先级:先 9,再 5,再 3。列表里的数值是 RAT 枚举,从后面日志能对上:9 对应 LTE,2 对应 CDMA,4 对应 HDR。补完之后还要按协议栈能力裁剪:

02:42:35.311 [ sdcmd.c 27555] =SD= Mode 4 not supported on any stack 02:42:35.311 [ sdcmd.c 27555] =SD= Mode 2 not supported on any stack

这一步是"能力求交":卡和 NV 说要支持,但当前软件没有对应的协议栈,那就只能从列表里划掉。所以看到 rat_acq_order 里有一项,不代表它会被真的尝试;反之,如果日志里某个制式从头到尾没出现 ACQ 请求,先看这几行裁剪记录,再去怀疑射频。

2.4 用 log 切片验证初始化是否走完

初始化阶段的 log 是散落的,人工翻容易漏。我一般写个小脚本按时间戳把四个关键事件切出来,缺哪个一眼就能看到:

import re # 四个锚点:卡在位、卡就绪、策略执行完成、SD 给出 rat 顺序 ANCHORS = [ ("CARD_INSERTED", "物理卡检测"), ("SUBSCRIPTION_READY", "卡应用就绪"), ("Finished executing policy", "策略求值完成"), ("rat_acq_order", "RAT 尝试顺序确定"), ] def slice_init(path): hits = [] with open(path, errors="ignore") as f: for line in f: for key, name in ANCHORS: if key in line: # 只保留时间戳与命中的锚点,避免输出过长 ts = re.search(r"\d{2}:\d{2}:\d{2}\.\d{3}", line) hits.append((ts.group(0) if ts else "?", name)) break return hits for ts, name in slice_init("modem.log"): print(f"{ts} {name}")

脚本只做一件事:按出现顺序列出锚点。如果 SUBSCRIPTION_READY 缺失,后面三项基本也都会缺,因为搜网请求根本没被发起;如果前两项齐了而 rat_acq_order 缺失,问题就在 policyman 或 MCFG,常见原因是 MBN 没加载成功或者卡里的 IMSI 读出来是空的。把四个锚点作为硬性检查项,比直接扎进 RRC 层翻日志省时间得多。

3. PLMN 与 RAT 选择:优先级顺序为什么能收敛

初始化的输出是一组先验:哪些 RAT 可用、优先顺序如何。接下来要回答的是"去哪张网上找"。这一步在 23.122 协议里定义得非常明确,而它的设计动机其实很朴素——用先验换时间:能不扫全频段就不扫,能直连上次成功的网络就不重新找。

3.1 自动模式的五级顺序:每一级都在省一次全扫

自动模式下 PLMN 的选择顺序是 RPLMN → HPLMN → UPLMN → OPLMN → other PLMN。这个顺序不是随便排的,每一级对应一种先验强度:

RPLMN 是上次注册成功的 PLMN,存在卡里(EF_LOCI),它是唯一一个"这台终端刚刚在这个网络上成功过"的证据,所以排第一,开机直接按它去搜,通常几秒内就能驻留。HPLMN 来自 IMSI 的 MCC/MNC,是归属网络,卡一插就知道,不需要任何搜索成本。UPLMN 和 OPLMN 是用户和运营商写在卡里的优先列表(EF_PLMNwAcT 与 EF_OPLMNwAcT),用于漫游场景下指定偏好。最后一级 other PLMN 才是兜底,意味着要做全频段扫描,耗时最长。

顺序的意义在于:越靠前的项越可能"一次命中",越靠后的项越依赖完整扫频。所以现场遇到"开机很久才驻留",先确认是不是掉到了 other PLMN 那一级——那说明前面四级全失败了,本身就是一个强信号。

3.2 REG 模块怎么分派:一个入口函数对应一种选择模式

REG 模块的 main 循环收到的请求类型不同,走的分支也不同。开机或无服务后 CM 发过来的是 service request,统一进reg_state_process_cm_service_req,在里面按手动/自动再分流。按日志和函数名还原出来的骨架大致是这样:

/* 按日志与函数名还原的分派骨架,非原样代码 */ void reg_state_process_cm_service_req(cm_service_req_type *req) { if (req->mode == REG_MODE_MANUAL) { if (req->plmn_valid) { /* 用户明确指定了 PLMN,只尝试这一个 */ start_manual_plmn_selection(req); } else if (reg_is_power_up_manual()) { /* 手动模式但没指定,退回归属网络 */ start_automatic_plmn_selection(req); } else { /* 其它情况只争取受限服务,不阻塞后续流程 */ reg_mode_start_limited_service(req); } return; } /* 自动模式:按 RPLMN -> HPLMN -> 高优先级 -> other 依次降级 */ if (reg_has_rplmn()) { start_plmn_selection(req); /* RPLMN */ } else if (reg_has_hplmn()) { start_automatic_plmn_selection(req); /* HPLMN */ } else { start_higher_priority_plmn_selection(req); /* UPLMN/OPLMN */ } }

这段骨架值得注意的地方是"降级"的写法:它是串行的,前一级失败才进下一级,而不是并行把所有 PLMN 都试一遍。串行省电、省射频资源,代价是失败路径的时延会累加。另一个细节是手动模式的三条分支——用户指定了 PLMN 就只试那一个,试不到也不偷偷回自动;没指定且是开机手动模式时退回归属网络;其余情况直接给受限服务。这解释了为什么手动搜网选了一个不存在的网络后,终端会停在"仅限紧急呼叫",而不是自己悄悄回到自动模式。

各级对应的实现文件也很好记:

选择场景实现文件入口函数
自动 RPLMNReg_mode_plmn_selection.cstart_plmn_selection
自动 HPLMNReg_mode_automatic_plmn_selection.cstart_automatic_plmn_selection
自动高优先级Reg_mode_higher_priority_plmn_selection.cstart_higher_priority_plmn_selection
手动指定Reg_mode_manual_plmn_selection.cstart_manual_plmn_selection
受限服务reg_mode_limited_service 相关reg_mode_start_limited_service

3.3 RAT 顺序的两层来源:AP 给的列表 + 卡/NV 的先验

PLMN 定下来之后选 RAT。这里容易误解的一点是:RAT 列表不是 REG 自己拍的,它是由 AP 侧设置的 NV10 和 EFS 文件共同决定的 rat list,通过 service request 一并送进 REG。自动模式下 REG 拿到这个列表后,还会参考卡或 NV 里记录的 RPLMN RAT、HPLMN RAT 再调一次顺序,然后从第一个开始试,失败换第二个,直到这个 PLMN 下所有 RAT 都试完。

这个"嵌套"结构是理解搜网 log 的关键:PLMN 循环在外层,RAT 循环在内层。所以你会看到同一个 PLMN 下出现多次注册请求,每次都换了 initial_rat;只有内层全部失败,才会降级到下一个 PLMN。看到连续多次注册失败就断言"网络拒绝",是把两层循环看反了——先确认这几次请求的 PLMN 是否相同,再看 RAT 是否在递增。

一段海外网络的测试 log 可以印证这个顺序:随 service request 传到 REG 的 rat list 是 LTE/CDMA/HDR,对应数值 9/2/4。REG 先选 RPLMN 及其 RAT,选好之后并不自己去做接入,而是调用reg_send_mmr_reg_req把请求发给 MM 模块,由 MM 去驱动协议栈激活。REG 只做选择,不做接入——职责边界划得很清楚,这也是为什么查"选网选错了"要盯 REG,查"接入失败了"要往下看 MM 和 RRC。

4. 扫频、小区搜索与小区选择:从一个频点到 suitable cell

PLMN 和 RAT 定完,MM 收到注册请求,按 initial_rat 发 rrc_service_req 去激活对应协议栈。以 LTE 为例,RRC 收到请求后先激活 PDCP/RLC/MAC/CPHY,拿到当前支持的特性(频段、载波聚合等),然后才挑一个频点开扫。问题在于一个频段的带宽很大、频点很多,怎么快速找到信号好的频点,是这一阶段的设计核心。

4.1 LTE 的两种扫频:system scan 与 band scan

LTE 扫频分 system scan(频点扫频)和 band scan(频段扫频)。每次注册或手动搜网成功找到合适小区后,终端会把该频点的信息(PLMN、频点号)写进 EFS 里的 acq_db。下次开机优先用 acq_db 里的频点去搜,这就是 system scan 的先验来源。扫频范围由 scan_scope 决定:

/* 扫频范围枚举,SYS_SCAN_SCOPE_ACQ_DB 表示优先用历史频点库 */ typedef enum { SYS_SCAN_SCOPE_NONE = -1, /* 仅内部使用 */ SYS_SCAN_SCOPE_FULL_BAND, /* 全频段扫描,耗时最长 */ SYS_SCAN_SCOPE_ACQ_DB, /* 只用 acq_db 里的历史频点 */ SYS_SCAN_SCOPE_MAX /* 仅内部使用 */ } sys_scan_scope_e_type;

MM 发给 RRC 的请求里就带着这个 scope:

02:41:36.455 [ emm_rrc_if.c 552] DS: SUB 1 EMM: Sent LTE_RRC_SERVICE_REQ scan_scope 1

scope 为 1 对应 FULL_BAND,意味着这次没有可用的历史频点,只能全扫。这就把"开机驻留慢"分成两类:scope 为 ACQ_DB 但历史频点已经失效(换城市、换卡),会白扫一轮再降级;scope 直接是 FULL_BAND,那慢是必然的。前者是 acq_db 陈旧问题,后者是正常代价,两者的处理方式完全不同。

扫到之后的日志链条很清晰:

20:10:27.679 [ lte_rrc_csp.c 6509] CSP: Acq requested on earfcn 41292 20:10:27.720 LTE LL1 SSS Results EARFCN = 41292 | 0| 6153| 422| Normal| Pre| 826| 243984| 0| | 1| 1842| 418| Normal| Mid| 2137| 244000| 0| 20:10:27.720 [ lte_ml1_sm_acq.c 3640] Acq search results for bin 0: 6 cells found 20:10:27.753 [ lte_rrc_csp.c 27463] CSP: Acq succeeded on physical cell ID 422 on earfcn 41292 20:10:27.766 [ lte_rrc_csp.c 29513] CSP: Adding cell to Acq DB 20:10:27.766 [ lte_rrc_csp.c 12025] CSP: Acq list count = 10

一个频点上一次搜出 6 个小区,RRC 从里面挑一个可用的(PCI 422),然后把频点写回 acq_db,acq_db 里已有 10 条记录。所以 acq_db 是一个上限受控的列表,不是无限增长——现场如果怀疑 acq_db 被老数据占满,可以看 Acq list count 和写入记录的时间。

4.2 PSS/SSS:5ms 定时和帧边界是怎么定出来的

"从频点找到 PCI"这一步靠的是两级同步。以 FDD 为例,一个无线帧 10ms,含 10 个子帧,每个子帧 2 个时隙,每个时隙 7 个符号。PSS 在子帧 0 和子帧 5 的第一个时隙的最后一个符号上发送,内容完全相同。终端拿本地 PSS 序列做相关,一旦捕获,只能确定出 5ms 的定时——因为两个 PSS 长得一样,不知道抓的是哪一个。

于是需要 SSS。SSS 在 PSS 前一个符号上,子帧 0 和子帧 5 的 SSS 内容不同。终端在 PSS 定时基础上盲检 SSS,解出来之后不但拿到了组号,还顺便确定了自己抓的到底是子帧 0 还是子帧 5,帧边界就此确定。

物理层标识的组成方式要分清:PSS 携带组内标识(0-2,共 3 个),SSS 携带组号(0-167,共 168 组),最终 PCI = 3 × 组号 + 组内标识,取值范围 0-503。所以只看 PSS 只能区分三个候选,必须两个都解出来才有完整的 PCI。日志里 "Acq succeeded on physical cell ID 422" 说明这两步都已经成功,422 分解开就是组号 140、组内标识 2。

4.3 WCDMA 的三级同步:从时隙边界到主扰码

WCDMA 的扫频思路和 LTE 不完全一样。它先分 acq_db 和频段扫描,频段扫描里又分 raw scan 和 fine scan:raw scan 以固定步长把频段粗扫一遍,按信号强度排序,再以最好的频点为中心做小范围 fine scan,两次排序后从最强频点开始小区搜索。已经扫过的频点会被跳过一段范围,避免重复劳动。

08:32:05.273 [ rrccspdb.c 2169] Acq DB Freq 10750 NOT scanned. Scan 08:32:05.326 [ srchacq.c 3684] ACQ REQ:Rx AGC -99 Chan 10750 band 1024 08:32:05.357 [ srchacq.c 3303] ACQ_CNF: Failure on freq=10750 fail type 0 rxagc = -1060 08:32:07.327 [ srchfs.c 1471] SRCH type 0 the raw and fine scan thresholds are -103 and -48 08:32:07.526 [ srchacqproc.c 866] ACQ SUCCESS! FREQ:10700 PSC:100 STTD:0 PROC:0 08:32:07.820 [ rrccspdb.c 1641] Updated: PLMN 204-16 freq 10700 scr_code 1600 ...

先扫 acq_db 里的 10750,AGC 只有 -99,失败;再按阈值 -103/-48 做 raw/fine 扫描,在 10700 上成功,解出 PSC 100。WCDMA 的帧结构是 10ms 帧含 15 个时隙,每时隙 2560 chips,整帧 38400 chips。小区搜索分三步:

第一步时隙同步。p-sch 上每个时隙前 256 chips 发的是同一个主同步码,终端拿本地主同步码做匹配滤波,就能找到每个时隙的开头,即取得了时隙定时。

第二步帧同步与扰码组识别。s-sch 上每时隙前 256 chips 发的是辅助同步码,15 个时隙的 SSC 组合构成一个完整的序列,一个帧周期内不重复。终端在时隙边界上捕获 15 个 SSC,通过组合关系既能确定帧边界,也能确定用的是 64 组主扰码中的哪一组——SSC 组与主扰码组是一一对应的。

第三步主扰码确定。512 个主扰码分成 64 组,每组 8 个。知道组号之后,把组内 8 个主扰码分别与 P-CPICH 做相关,相关值最大的那个就是本小区的主扰码。WCDMA 里

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询