简介:《高通平台modem搜网注册流程.pptx》面向通信协议开发、Modem测试及场测问题分析人员,系统梳理终端开机后的搜网注册链路。内容按初始化、PLMN与RAT选择、扫频与小区搜索及小区选择、随机接入与RRC连接建立、注册等阶段展开,并结合协议、代码和日志说明SIM卡读取、MBN加载、policyman策略、SD决策等关键环节,同时涉及注册成功后的终端行为,可用于理解多制式网络下终端如何选择网络并附着核心网,也为掉网、无服务等场测问题提供排查思路。资源包共1个pptx文件,大小约1.59MB,以图文幻灯片组织流程与日志片段,便于按步骤查阅和复盘。已有5132人学习,适合作为5G及多制式网络下Modem搜网注册的入门与查漏补缺材料。
1. 信号格亮起的那两秒:搜网注册这条链路为什么值得逐帧拆
手机重启,或者热插拔一张 SIM 卡,状态栏的信号格往往两三秒就回来了,快到你根本不会去想中间发生了什么。可一旦到了场测现场,「无服务」「有信号上不了网」这类问题复现出来,抓回来的高通平台 modem 日志动辄几十万行,多数人卡在第一步:不知道该从哪一帧切进去看。
这份 pptx 干的就是这件事。它把开机之后的搜网注册拆成四个大步:初始化、PLMN 和 RAT 选择、扫频加小区搜索加小区选择、随机接入加 RRC 连接建立加注册,每一步都对着三样东西讲——3GPP 协议条款、平台侧具体代码文件、实测 log 片段。做协议栈移植的、跑场测定位的、准备入网测试的开发者,都能把它当索引表用。
它不教你怎么写驱动,但能让你在面对「没服务」三个字时,知道该先翻 SD 的rat_acq_order,还是先翻 REG 的 PLMN 匹配。
2. 选网决策链:从 SIM 就绪、MBN 加载到 REG 里的 PLMN/RAT 排序
开机之后到真正开始扫频之前,终端其实已经在做大量决策了。这一段是整个搜网流程里最像「黑匣子」的部分——没有射频动作,没有空口消息,全是模块之间传消息、读文件、跑策略。恰恰是这一段出了问题最难查,因为它不出错,只是「沉默地选错了」。
2.1 卡就绪与系统信息读取:MMGSDI 到 NAS 的两次握手
插卡或上电后,第一个要等的信号是卡初始化完成。卡没 ready,后面的 IMSI、EF 文件、PLMN 列表全都读不出来,整个搜网流程根本启动不了。文档里给的第一段 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 02:42:35.007 [ reg_send.c 1953] DS: SUB 1 =REG= MMR_SIM_AVAILABLE_REQ 02:42:35.018 [ reg_send.c 857] DS: SUB 1 =REG= CM_SIM_AVAILABLE_CNFCARD_INSERTED只是物理层检测到卡在位,真正有意义的节点是MMGSDI_SUBSCRIPTION_READY_EVT,它意味着 USIM 应用已经初始化完成,应用类型app: 0x3对应 USIM,slot: 0x1是卡槽编号。这之后才会向上层 NAS 的 REG 模块发MMR_SIM_AVAILABLE_REQ,REG 回CM_SIM_AVAILABLE_CNF确认。
紧接着是 IMSI 的读取和解析:
02:42:35.008 [ mmsim.c 1621] DS: SUB 1 =MM= SIM IMSI length: 8 02:42:35.008 [ mmsim.c 1625] DS: SUB 1 =MM= SIM IMSI[0] = 73 ... IMSI[7] = 98这里有个坑要提前说清楚:IMSI 是按字节打印的,不是可以直接当字符串读的十进制数字。看到73 6 16 7 118 50 4 98这种序列,别急着拼,它和 BCD 编码的对应关系在不同工具里解释还不完全一样。我一般直接跳过这一行,去找后面 policyman 打印的IMSI PLMN: (MCC xxx, MNC xx),那才是已经解析好、能直接用的结果。
还有一个容易忽略的细节:卡刚插上时系统会先读紧急号码表(ECC),日志里那行Card ecc for session type 6: 110,120,119,999,911,...。这一步和搜网没关系,但它和卡就绪是并行的,排查时看到这行别以为是异常。
2.2 policyman 与 MBN:谁在背后决定终端的「默认性格」
卡读出来之后,真正决定终端「性格」的是两样东西:policyman 和 MBN。
02:42:34.936 Policy Manager/High [ 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) 02:42:34.935 MCFG/High [ mcfg_uim.c 2379] Selecting config using IMSI MCC=460 MNC=1 02:42:34.949 MCFG/Medium [ mcfg_utils.c 913] Config: C3I_CN-LA-7+7_mode-XXXX 02:42:34.949 MCFG/Medium [ mcfg_utils.c 913] Config: VoLTE-CUpolicyman 做的事是把「卡信息 + NV 配置 + 运营商策略」合成一份当前订阅的运行时策略。日志里那句Finished executing policy ... (8 ticks)挺有用——它给了你一个执行耗时的基线数值,正常是几个 tick。哪天在别的项目上看到跑到几百 ticks,先别怀疑算力,去看策略文件是不是加载了不该加载的大表。
MBN(Modem Configuration Binary)才是重头戏。它按 IMSI 的 MCC/MNC 匹配,一个 IMSI 可能命中多份配置,比如上面这份7+7_mode是射频和频段相关的,VoLTE-CU是业务能力相关的。MBN 决定了这个终端支持哪些频段组合、开不开 VoLTE、载波聚合怎么配、射频校准参数取哪一套。
血泪经验在这里:MBN 选错的典型症状不是「没信号」,而是「信号满格但打不了电话、上不了网」。因为扫频、驻留、注册全都正常,唯独业务能力对不上。所以看到这类问题,第一个要查的就是mcfg_uim.c那行Selecting config using IMSI,确认 MCC/MNC 解析对、命中的配置名符合预期。
| 模块 | 关键日志 TAG | 职责 | 出问题时的表现 |
|---|---|---|---|
| MMGSDI | MMGSDI_SUBSCRIPTION_READY_EVT | 卡初始化、USIM 应用就绪 | 一直无服务,连扫频都不启动 |
| Policy Manager | policyman_policy.c | 合成订阅级策略 | 频段、RAT 优先级异常 |
| MCFG | mcfg_uim.c | 按 IMSI 选 MBN | 有信号无业务、VoLTE 不生效 |
| SD | sdss.c | 生成rat_acq_order | 某些制式压根不尝试 |
2.3 SD 的 rat_acq_order:待机能力表的排序与取舍
策略跑完之后,SD(System Determination)模块会输出一份「待机能力表」,也就是rat_acq_order。这是后面所有扫频动作的总纲——扫什么制式、按什么顺序扫,全看这张表。
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 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这段 log 信息密度很高。num_rat 3表示 policyman 一上来先给了三个,[0]: 9在 SD 层一般对应 LTE,后面的 5、3 是别的制式;紧接着 SD 自己又往后追加了 2、4、11 三个,其中 11 在较新平台上通常留给 5G NR。
但注意最后两行:Mode 4 not supported on any stack、Mode 2 not supported on any stack。这说明rat_acq_order只是「想尝试的顺序」,能不能真用还要看对应协议栈有没有起来。栈没起,排在第几位都是白排。
所以看这份表的时候要有两个动作:第一,先到sdss.h或对应头文件里把数字和 RAT 枚举对一遍,别凭记忆;第二,把rat_acq_order和后面的not supported on any stack两段对着看,确认「想扫的」和「能扫的」是不是一回事。
提示:不同平台版本里同一数字对应的 RAT 不一定一致,而且 SD 层、NAS 层各有一套编码,后面第 4 章还会遇到 NAS 侧打印 LTE 为 2 的情况。看到数字先查表,是省后悔药的做法。
2.4 REG 模块的 PLMN/RAT 选择:Reg_mode_*.c 各管哪一段
决定扫什么之前,还得决定找谁。PLMN 和 RAT 的选择在 REG 模块完成,选网顺序严格照 3GPP 23.122 的定义走。
自动模式下,顺序是 RPLMN → HPLMN → UPLMN(用户优先)→ OPLMN(运营商优先)→ other PLMN。RPLMN 是上一次成功注册的 PLMN,存在 SIM 卡或 NV 里,开机优先试它,这是为了「用户在哪待着就在哪快速驻留」;HPLMN 是卡里 IMSI 对应的归属网;UPLMN 和 OPLMN 分别来自卡里的 EF_UPLMN 和 EF_OPLMN 文件,是按优先级排好的备选清单。
手动模式下逻辑不一样:用户指定了 PLMN 就用指定的;没指定但当前是手动模式、开机时又存在 RPLMN,就直接用 RPLMN;两者都没有,调用reg_mode_start_limited_service拿一个限制服务——只能打紧急电话,信号格会显示但没有正常业务。
文档把每个场景落到了具体文件,这张表值得单独记下来:
| 场景 | 代码文件 | 入口函数 |
|---|---|---|
| 自动模式选 RPLMN | Reg_mode_plmn_selection.c | start_plmn_selection |
| 自动模式选 HPLMN | Reg_mode_automatic_plmn_selection.c | start_automatic_plmn_selection |
| 自动模式选 UPLMN/OPLMN | Reg_mode_higher_priority_plmn_selection.c | start_higher_priority_plmn_selection |
| 手动模式选指定 PLMN | Reg_mode_manual_plmn_selection.c | start_manual_plmn_selection |
| 兜底限制服务 | 同目录 | reg_mode_start_limited_service |
REG 模块的主循环,从 CM 收到service request开始分发,结构大致是这样:
/* 依据文档描述整理的 REG 主流程骨架,函数名与日志 TAG 保持一致 */ static void reg_state_process_cm_service_req(subs_id, req_type, rat_list) { /* 1. 先判手动还是自动,模式由 CM 下发 + NV/EFS 共同决定 */ if (reg_is_manual_mode(subs_id)) { if (manual_plmn_valid(&plmn)) { start_manual_plmn_selection(&plmn); /* 用户指定 PLMN 优先 */ } else if (rplmn_available(subs_id)) { start_plmn_selection(subs_id); /* 手动模式下退化为 RPLMN */ } else { reg_mode_start_limited_service(subs_id); /* 只能拿限制服务 */ } return; } /* 2. 自动模式按 23.122 顺序逐级尝试,前一级成功就不再往下走 */ if (start_plmn_selection(subs_id) == REG_PLMN_FOUND) /* RPLMN */ goto rat_pick; if (start_automatic_plmn_selection(subs_id) == REG_PLMN_FOUND) /* HPLMN */ goto rat_pick; if (start_higher_priority_plmn_selection(subs_id) == REG_PLMN_FOUND) /* UPLMN/OPLMN */ goto rat_pick; reg_mode_start_limited_service(subs_id); /* 全失败,落限制服务 */ return; rat_pick: /* 3. PLMN 定了再定 RAT:以 service_req 带下来的 rat list 为底, * 参考 SIM/NV 里的 RPLMN RAT、HPLMN RAT 重排一次顺序, * 取第一个去试,失败了按顺序往下换 */ reg_select_rat(subs_id, rat_list); reg_send_mmr_reg_req(subs_id, &sel_plmn, sel_rat); /* 交给 MM,进入扫频 */ }这里几个参数值得说清楚。req_type区分了请求来源:开机、无服务之后的重新搜网、用户手动操作,走的是不同分支,但最终都汇聚到reg_state_process_cm_service_req。rat_list是 AP 侧通过 NV(NV10)和 EFS 文件共同决定的候选制式列表,REG 拿到它之后不是直接用,而是参考 SIM 卡或 NV 里的 RPLMN RAT、HPLMN RAT 重新排序——这就解释了为什么同一张卡插到不同地区的机器上,第一次搜网的速度会差很多。
最终这一步的产物是reg_send_mmr_reg_req,把「去哪个 PLMN、用什么 RAT」发给 MM 模块。从这里开始,日志的主战场就从 NAS 转移到接入层了。
3. 扫频与小区搜索:LTE 的 PSS/SSS、WCDMA 的主扰码、NR 的 SSB 各走哪条路
MM 收到注册请求后,按initial_rat去激活对应的协议栈,RRC 先拉起 PDCP/RLC/MAC/CPHY,拿到频段、载波聚合这些能力参数,然后才轮到射频真正干活。从「打开接收机」到「知道有个小区在那儿」,不同制式的技术路线差别很大。
3.1 LTE 扫频:system scan 与 band scan 的取舍
LTE 扫频分两种。system scan 是按频点扫,扫的频点来自 EFS 里的acq_db——一份历史上成功驻留过的 (PLMN, freq) 记录表;band scan 是全频段扫,按支持的频段一格一格过。
选哪种由scan_scope决定,枚举定义得很直白:
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;日志里能看到它被塞进服务请求一路带下去:
02:41:36.455 NAS MM/High [ emm_rrc_if.c 552] DS: SUB 1 EMM: Sent LTE_RRC_SERVICE_REQ scan_scope 1scan_scope 1对应SYS_SCAN_SCOPE_ACQ_DB,也就是开机优先走历史频点。这个设计在绝大多数场景下是对的:用户每天在同一个地方开机,acq_db 里存的就是本地频点,几百毫秒就能锁定小区。
但它是把双刃剑。跨地市、换卡、漫游回来之后,acq_db 里可能全是异网或者过期的频点,system scan 挨个试一遍全部落空,然后才降级到 band scan 全扫。这就是「明明信号很好却要等十几秒才出信号格」最常见的原因,我在第 5 章还会展开。
3.2 LTE 小区搜索:PSS 定时隙、SSS 定帧
锁定频点之后,接收机拿到的还只是一堆模拟采样,得先找到同步信号才能解出小区标识。
LTE FDD 的帧结构是:一个无线帧 10ms,含 10 个子帧,每个子帧 2 个 slot,每个 slot 在常规 CP 下 7 个符号。PSS(主同步信号)放在子帧 0 和子帧 5 的第一个 slot 的最后一个符号里,一帧内出现两次,间隔 5ms。所以 UE 一旦捕获到 PSS,就拿到了 5ms 级别的定时基准。
SSS(辅同步信号)在 PSS 前一个符号发送。子帧 0 和子帧 5 上的 SSS 内容不同,所以盲检 SSS 成功之后,能同时确定两件事:这个 SSS 落在子帧 0 还是子帧 5,以及无线帧中子帧 0 的边界在哪里。到这一步,帧同步完成。
小区标识 PCI 由两个同步信号共同决定:PSS 携带组内 ID(N_id_2,取值 0-2),SSS 携带组 ID(N_id_1,取值 0-167),最终PCI = 3 × N_id_1 + N_id_2。日志里搜到 PCI 422 的那次,反推就是 N_id_1 = 140、N_id_2 = 2。
20:10:27.679 [ lte_rrc_csp.c 6509] CSP: Acq requested on earfcn 41292 20:10:27.720 [C4] 0xB115 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这张 SSS Results 表的列,不同解析工具给出的表头不完全一致,但 PCI 那一列是能直接对上的,一次扫出 6 个候选小区。Pre/Mid表示检测到的定时位置落在相关窗的哪一段,通常Pre和Mid混合出现是正常现象。Acq succeeded之后马上Adding cell to Acq DB,把这个 EARFCN 写回历史库,下次开机就直接扫它——这就是 acq_db 自我更新的闭环。
3.3 WCDMA 扫频与三步小区搜索
WCDMA 的扫频比 LTE 复杂一层,因为它分两级:raw scan 和 fine scan,另外同样有 acq_db 快速通道。
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 = -106 08:32:06.233 [ rrccspdb.c 3350] LFS_COOS: Exhausted list scan db. Initialization done for RAW/FINE 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 xxx-xx freq 10700 scr_code 1600 band 1024这段日志的叙事很完整:acq_db 里的 10750 先试,AGC -99 太弱,Acq failed;历史库耗尽之后进入 raw/fine 阶段,阈值分别是 -103 和 -48 dBm;然后在 10700 上ACQ SUCCESS,拿到 PSC 100,回写 acq_db。scr_code 1600是主扰码号,PSC 100 乘上 16 得 1600,扰码和 PSC 的换算关系在这里能直接对上。
WCDMA 的小区搜索分三步,每步盯一个物理信道:
第一步,时隙同步。P-SCH(主同步信道)在每个时隙前 256 chips 发送相同的主同步码,本地匹配一遍就能找到每个时隙的开头。
第二步,帧同步和主扰码组识别。S-SCH 上每个时隙发送辅助同步码,15 个时隙的 SSC 组合起来对应一个码组,系统一共 64 组,正好和 512 个主扰码分成的 64 组一一对应。所以解出 SSC 序列,就同时拿到了帧边界和主扰码组号。
第三步,主扰码确定。每组 8 个主扰码,用这 8 个候选分别和 P-CPICH(公共导频信道)做相关运算,相关值最大的那个就是本小区的主扰码。WCDMA 里小区是靠主扰码区分的,所以这一步等价于「识别出是哪个小区」。
注意:原文在描述 WCDMA 帧结构时写「一个帧含有 384chips」,按 15 个 slot × 2560 chips 算应该是 38400 chips。看到这类数字对不上不用慌,按 3GPP 的定义走就行,文档里的笔误在实地排查时不会影响判断,但如果你把这页拿去做分享,记得改过来。
3.4 换到 5G NR:SSB、GSCN 与 CORESET0
流程走到这里,如果rat_acq_order把 5G 排在前面,终端第一步试的就是 NR。NR 的小区搜索逻辑和 LTE 一脉相承——同步、解广播、判合适——但坐标系换了一套。
LTE 用 EARFCN 标频点,NR 用 GSCN(Global Synchronization Channel Number),因为 NR 的同步信号不占满整个载波,它只是带宽里的一块。这块就叫 SSB(Synchronization Signal Block):PSS、SSS、PBCH 打包在 4 个 OFDM 符号、20 个 RB(240 个子载波)里,按不同的子载波间隔以 5ms 到 20ms 的周期重复发送。
终端扫频时要先按 GSCN 栅格去找 SSB 的位置,找到之后解 PSS 拿定时、解 SSS 拿 PCI(NR 的 PCI 范围是 0-1007,比 LTE 的 0-503 大了一倍),再用 PBCH 的 DMRS 做信道估计、解出 MIB。MIB 里最关键的字段是pdcch-ConfigSIB1,它告诉你 CORESET#0 在哪个频域位置、用什么参数——不去解 CORESET#0,就拿不到 SIB1,也就不知道这个小区的 PLMN、TAC、小区禁止状态。
从排查角度看,NR 和 LTE 的差异体现在三个地方:GSCN 扫不出来通常是频段和band_cap对不上;SSB 找到了但 SIB1 解不出来,要看k_ssb和 CORESET#0 的配置;cellBarred在 SIB1 里,被禁的小区不能驻留,但信号格可能是满的。
4. 小区选择到注册完成:S 准则、竞争随机接入与 Attach 的落地细节
同步做完、PCI 拿到,只是知道「这儿有个小区」。要真正驻留上去、挂到核心网,中间还有三道关:判断这个小区合不合适、和基站建立上行同步、把 NAS 消息送上去。这一段是掉网问题最集中的地方。
4.1 小区选择:PLMN 匹配与 S 准则手算一遍
第一道关是 PLMN 匹配。终端从广播消息里解出这个小区属于哪个 PLMN,和 REG 层选定的 PLMN 比对,对不上
本文还有配套的精品资源,点击获取