首页
社区
课程
招聘
16
[原创]深度揭密高通4/5G移动基带消息系统和状态机
发表于: 2021-4-9 15:25 19764

[原创]深度揭密高通4/5G移动基带消息系统和状态机

2021-4-9 15:25
19764

深度揭密高通4/5G移动基带消息系统和状态机

​ 阿里安全 谢君

背景

本技术分析文章通过对高通的4/5G移动基带系统进行深入逆向工程提示其内部消息通信机制以及核心架构设计逻辑,本文的研究基于高通的4G基带MDM9707以及5G基带模块sdx55的固件之上分析完成,高通基带系统现在都是基于高通主流的hexagon DSP指令架构来实现,该架构非常适合应用于音视频编解码,计算机视觉等,软件无线电等应用中的浮点和向量计算,在高通骁龙处理器的子系统中大量使用,大多应用于手机,汽车,可穿戴设备以及移动通信设备中,Hexagon DSP相关信息可以从这里获取,运行在Hexagon DSP芯片上的操作系统QuRT是由高通设计的实时操作系统,高通基带系统所有的上层业务将会运行在该操作系统之上,阅读该技术分析文章之前,假定你已经对操作系统的原理有所了解,例如CPU调度,IPC(进程间通信),以及基本的数据队列enqueue/dequeue的操作。

消息机制简介

一个系统里面运行着不同的任务,不同任务在不同的运行状态在处理相应的业务逻辑时可能需要与其它任务交换数据或者同步信息,这里面就需要操作系统的底层IPC机制来完成了,3GPP组织定义了不同移动通信技术从物理层/链路层/逻辑处理层等各种标准,例如(5GNR/4GLTE/3G WCDMA/TD-SCDMA/CDMA2000/2G /GSM等通信技术),这些技术标准在基带系统里面实现会被划分成不同的任务来维护不同的状态,处理不同的消息信令,以及维护不同通信技术的切换等操作,比如现在的大部分智能手机基带系统基本上都支持2/3/4G通信相关的技术,这些基带系统根据移动运营商支持的移动通信技术和国家区域支持的标准的不同会使用相应的移动通信技术,比如中国在3G时代中国移动使用的TD-SCDMA,而中国联通使用的是WCDMA技术,为了保证移动设备的一些基本功能的可用性(语音通信和sms短信息),比如某些地方部署了4G基站,你可以在那里使用4G LTE的(Voice-over-IP/SMS-over-IP)通信技术,在一些偏远的地区可能只部署了2G基站,这时基带系统根据环境切换到GSM的协议栈,这些功能的维护与切换从基带系统层面来讲都需要系统消息机制来配合完成。

 

高通基带系统的消息机制建立在运行的实时操作系统QuRT之上,之前我有一篇文章有简单介绍过底层IPC机制,今天我将详细介绍上层业务逻辑相关的消息传递机制与数据结构。我们把运行在基带系统上的业务逻辑实体的最小单位定义为线程(thread),根据线程生命周期的不同分为以下两大类:

  • 短生命周期线程
    • 驱动/任务初始化线程(Driver initiator/Services Launcher)
    • 中断服务例程(IST)
  • 长生命周期线程
    • 阻塞型消息接受线程

image-20210308164203970

 

消息通信底层API封装简介:

1
2
3
4
5
6
7
8
9
//信号发送
int rex_send_sigs(utcb *dst_task_obj,unsigned int signal_id);
//第一个参数为向目标任务发送消息的结构定义,第二个参数为要发送的信号id
int rex_wait_sigs(unsigned int recv_sigs_masks);
//第一个参数为可以允许接受信号id的掩码,每个任务最多可以设置可接受信号id个数为32个,每个任务可以接受多个信号id时,通过信号id的或操作来得到该任务可以接受信号的掩码,返回值为接受到的信号id
 
//如果是带数据的信号发送,封装底层API,类似如下
int send_sigs_with_dat(utcb *dst_task_obj,unsigned int signal_id,data_queue *send_data_queue);
int recv_sigs_with_dat(unsigned int recv_sigs_masks,data_queue *recv_data_queue);

而根据任务线程的业务功能的不同划分成以下几大类:

  • 系统功能任务
  • 通信技术协议栈分层任务
    • GSM/WCDMA/TDSCDMA/LTE L1/L2/L3相关的协议栈的任务等
  • 上层应用任务
    • IMS volte/ecall/数据服务/包服务等
  • 外设相关的任务
    • UIM/SIO/A2等

我在这里记录了高通MDM9607基带系统一次实时运行的任务快照列表。

高通基带系统消息机制

消息通信核心架构设计逻辑

  • 兼容性
    • 在新的基带芯片上面开发新的移动通信技术单元的同时,保证老的功能模块能够正常使用,例如在开发5G功能的同时,以往的4G/3G/2G功能都能够正常使用和切换。
  • 可扩展性
    • 在已有的功能模块上增加新的功能,具备灵活的扩展性,而不需要作太大的软件和硬件改动。
  • 低耦合性
    • 新增的功能模块与已有系统上功能模块的耦合度低,接口少,减少引入问题的接口点和测试成本。

基于以上的设计理念,高通设计一套灵活的消息通信系统,一直到现在5GNR的基带系统也在用,接下来我将详细介绍该消息系统的架构,相关的算法和数据结构。

消息通信架构

为了区分不同任务所接受到的消息以及任务所能处理相应消息的原语操作权限,通过接受到的消息来区分消息来源以及接受到相应消息后的相应的处理动作,高通的消息系统引入了任务消息接受体(msgr_client)和UMID(Unique Message ID)的机制,任务消息接受体由相应的任务创建生成,并通过初始注册可接受消息UMID来设置任务相应原语操作的权限,每个任务可以创建一个或者多个msgr_client,每一个UMID消息也可以注册给多个msgr_client,每一个UMID消息标示着一次相应的原语操作,在MDM9607里面定义的UMID数量多达1万多个,而在最新高通的5G基带里面可使用的UMID高达2万多,每个UMID背后都对应着相应的原语操作,UMID的值与相应的命名规则如下。

UMID由32位组成,结构如下表

Name offset and length Comment
tech_id 24~31 8bits eg, LTE->0x04, IMS->0x15, MDM9607 0x1b, SDX55 0x20
mod_id 16~23 8bits eg, 0xd -> RRC 0xf -> MAC 0x11-> RLC DL
type_id 8~15 8bits type <= 0x09) || (type >= 0x11 && type <= 0x17,totally 0x11 type_ids
op_type_id 4~8 4bits Op entity ,eg IRAT_FROM_LTE_TO_G
op_id 0~3 4bits Opcode seq, eg abort/search/startup/deinit/init/cfg etc
 

注:if type_id>9 ,type_id=type_id-6
offset bit 8~15 8bits type_id list

Type_name value Comment
CMD 1 Command primitive
REQ 2 request
RSP 3 response
IND 4 indication
DLM 7 downlink message
CNF 8 confirm
TMR 9 timer
REQI 0x12 request Internal
RSPI 0x13 Response internal
INDI 0x14 indication internal
CNFI 0x15 confirm internal
TMRI 0x16 timer internal
 

举个例子UMID 0x40D120E 对应的描述原语是LTE_RRC_IRAT_FROM_LTE_TO_G_RESEL_REQI,拆分结果如下:

name value
LTE 0x04
RRC 0x0d
REQI 0x12
RESEL 0x0
IRAT_FROM_LTE_TO_G 0x0e
 

注:这种UMID值的解析方法在某些定义里面并不适用,比如LTE_ML1_DLM_TST_SKIP_RACH_REQ的值为6,就没法用上面的方法解析,有些值并不严格遵循这种解析算法,可能是由于历史原因,定义UMID值的规则不一样。

 

基带系统把任务标示为多个不同的技术大类,来标示和模块化相应的子功能,以MDM9607为例:

tech_id Tech_name
0 MCS(Modem Common Service)
2 MM_CM(0x201) UI(0x20a) (Unnumbered Information) MM_DOM(0x202),MM_MMOC(0x251)
4 LTE
5 FTM
6 rfa_tech (0x600 rf_fwrsp,0x603 rfgsm, 0x604 rf_1x ,0x601 0x605 rf_hdr ,0x606 rfgsm_ftm,0x607 rf_lte,0x608 rf_lte_ftm,0x60b rf_qmi, 0x60c rf_meas,0x40f/0x1a04 rf_lte ,0x120f rf_tdscdma)
7 cdma
8 hdr
9 gsm
0x0a location(gps/gnss)
0x0b wcdma
0x0c ds(data service)
0x0d 1x(csfb)
0x0f nas(0xf19 mm, 0xf1c esm)
0x10 gstk(Generic SIM Application Toolkit)
0x12 tdscdma
0x13 wms
0x15 ims
0x16 qmi
0x17 ecall 0x1701 ecall_app ,0x1702 ecall_ivs
0x18 policyman
0x1a rflm

模块ID

下图是MDM9607 LTE的部分子模块ID的对应关系

tech_id+mod_id name
0x401 ML1 MGR
0x407 LL1_SRCH
0x408 LL1_DL
0x409 LL1_UL
0x40a LL1_SYS
0x40b LL1_Async
0x40d RRC
0x40f MAC
0x411 RLC DL
0x412 RLC UL
0x413 PDCP DL
0x414 PDCP UL
0x41b ML1_GM
0x41e SW.app
0x420 ML1_GM_SCHDLR
0x427 TLB(Test Loop )
0x42b ML1_GM_Sleep
0x434 ML1_AFC
0x43b PDCP offload
0x43e ML1 offload
0x43f ML1 Co-existence
0x441 ML1 GM MSMGR
0x442 PDCPCOMP
0x445 ML1 SM FSCAN
 

关键消息发送API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
msgr_send(umsg *buf,uint32 buf_size);
struct umsg{
       struct msgr_hdr_struct_type{   
                uint32  dest_umid;  //offset 0      ,要发送的UMID号
                uint16  src_tech_mod_id; //offset 4,发送源tech_mod_id的标识
                uint8    num_attach;// offset 7
                uint8    tail_flag ;// offset 8 ,头部结尾标志0x7f
                uint8    inst_id;// offset 9
    }
         uint8 send_dsm_flag;//offset 0x10 ,置1表示发送数据通过dsm结构承载的标志
         dsm *dsm_obj;//offset 0x14 , 发送数据dsm结构指针
 
 }
msgrq_wait(void *msgr_client_ptr,void *msg_recv_buf,uint32 msg_recv_buf_size,uint32 *msg_recvd_size_ptr);//接受消息的函数
msgr_register(uint16 mod_id,void *msgr_client_ptr,void *mailbox_obj,uint32 umid);//msgr_client注册umid的消息路由

消息路由

我们已经了解到UMID所对应原语操作的含义,如果需要执行相应的原语操作,只需要向注册过UMID的模块发送umid消息即可,接下来我们需要了解umid消息是如何路由到相应模块(tech_mod_id)的消息接收器(msgr_client)的,下面会详细介绍相应的算法和数据结构,我整理了几张表来描述。

map_name map_size key value value_size Memory Attribution
techs_map techs * 8 tech_id module_counts, modules_map 8 bytes Read Only
modules_map module_counts 0x11 2 (mod_id 0x11+type_id) 2 types_map_id 2 bytes Read Only
types_map types_map_ids * 0x20 types_map_id * 0x20 +(op_type_id&0x1e) tech_mod_type_seq 2 bytes Read/Write
umids_map umid_seq_id * 0x8 8 * (tech_mod_type_seq+op_id) umid, next_umid_seq_id,msgr_client_id 8 bytes Read/Write
msgr_clients_map 0x34*total_msgr_client_counts msgr_client_seq_id msgr_client_desc 0x34 Read/Write
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
struct msgr_client_desc{ //全局msgr_client结构描述
    uint32 umids_registered;
    uint16 msgr_client_reg_type;//1 ->msgrq_sig type,2-> rexq_sig
    uint16 tech_mod_id;//
    union *msg_sig_p{ //offset 0x10
        struct msgrq_sig *msgq_p;//msgr reg type 1,4G及以后使用的mailbox消息传递系统
        struct rexq_sig *rexq_p;//msgr reg type 2,兼容2G/3G时代使用的Rex IPC消息传递系统
    }
    struct msgrq *msgrq_p;//offset 0x14 ,if reg type 1   
    struct msgr_client_obj *msgr_client_obj_ptr;//offset 0x30
 
}
 
struct msgr_client_obj{//msgr_client结构体
     unsigned int msgr_client_reg_type;//1-> msgrq aka mailbox,2->rex_q,接受消息的方式
     unsigned int register_umid_counts;//offset 8 ,消息接受器注册的umid的总数
     unsigned int total_reged_recv_signal_counts;//offset 0x0c,注册的接受消息的signal的个数
     union sig_recv_obj{
       msgrq_sig  *msgrq_signal_obj;// offset 0x10 msgrq_sig type,4/5G未来的主流类型
       rexq_sig *rex_signal_obj;//offset 0x10  rexq_sig type ,这个主要是为了兼容之前2/3G的系统的数据结构
     }    
     unsigned int task_recv_signal_set_mask;//offset 0x14 ,注册的接受消息的signal号的掩码
     uint32 err_counts;//offset 0x18
     unsigned int recvd_signal_id;//offset 0x1c,当前接受到的signal id,msgr_client_reg_type为1
     struct msgrq *recvd_msgrq_ptr;//offset 0x20,当前接受消息承载的msgrq对象,msgr_client_reg_type为1
     struct msgrq *msgrq_first_entry;// offset 0x24,接受msgrq消息链表结构指针,msgr_client_reg_type为1
     unsigned int total_msgrq_counts;//offset 0x28, 可以接受msgrq消息的总数,通过可以task_recv_signal_set_mask来确定,msgr_client_reg_type为1
 }
 
 struct msgrq_sig{
    uint32 sig_ready_flag;//must be 1
    struct sig_def{
        uint32 signal_id_for_recv;//offset 8
        uint32 signal_reged_wait_mask;//offset 0xc
        void * kernel_msg_queue;
        unsigned int attribute;
    };
 
 
 }
 struct rexq_sig{ //size 0x1c, 兼容2/3G系统的数据结构
     utcb *msgr_client_utcb_ptr;//offset 0  任务接受消息使用的utcb标识
     uint32 msgr_client_signal_id;//offset 4 接受消息使用的signal id
     msg_queue *msgr_out_msg_q;//offset 0x8
     msg_queue *rex_msg_in_q;//offset 0xc
     uint16 msg_data_q_used_size;//offset 0x10
     uint16 rexq_id;//offset 0x12
     uint16 msg_data_q_size;//offset 0x14
 }
  struct msg_data_q{
         struct msg_data_q *prev_q;
         struct msg_data_q *next_q;
         char data[msg_data_q_size-8];
     }
 struct msg_queue{
    struct msg_data_q *headp;
    struct msg_data_q *tailp;
    uint32 total_q_counts;
 }
 
 struct msgrq{
     void *msg_recv_buf_header;//offset 0
     void *msg_recv_end_buf;//offset 4
    char msgrq_name[16];//offset 0x10
    int msgrq_recvd_seq;//ofset 0x18
    unsigned int reged_recv_signal_id_mask;//offset 0x1c,可供接受消息signal的掩码
    void *msgr_buf_remain_ptr;//offset 0x20,可供接受消息的剩余空间起始地址
    void *msgr_recv_buf;//offset 0x24,当前接受到消息的buf地址
    uint32 msgr_buf_remain_size;//offset 0x28
    unsigned int total_msg_recv_buf_size;//offset 0x30
    int8 is_buf_in_use;//offset 0x70 ,0-> in use, 1-> not in use
    uint32 recvd_msg_blocks;//offset 0x58 ,收到的消息次数总和
    struct msgrq *next_msgrq;//offset 0x74
 }

为了更方便的理解上述的数据结构的关系与操作算法,画了一张简单的图来加深该消息系统的理解。
通过以上算法和数据结构,可以很方便的完成UMID与tech_mod_id的消息路由的注册,消息发送等操作。

 

image-20210322162235900

 

需要说明的一点就是一个tech_mod_id可能会关联多个msgr_client,所以msgr_client_id就成了消息传递的唯一标识,通过msgr_client_id得到全局的msgr_client_desc的结构定义,该结构体里面包含接受消息的任务utcb和接受消息的signal id,这里通过tech_mod_id 0xf19对应的MM(Mobility Management)任务进行举例。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-9-8 18:17 被kanxue编辑 ,原因:
收藏
免费 16
支持
分享
赞赏记录
参与人
雪币
留言
时间
PLEBFE
为你点赞~
2022-7-27 01:09
心游尘世外
为你点赞~
2022-7-26 22:58
飘零丶
为你点赞~
2022-7-17 02:30
zx_838741
为你点赞~
2021-4-27 21:31
jmpcall
为你点赞~
2021-4-14 09:09
Seclusion
为你点赞~
2021-4-13 23:28
qifuadmin
为你点赞~
2021-4-12 09:10
bluefish蓝鱼
为你点赞~
2021-4-11 15:49
mb_cwlqrkbj
为你点赞~
2021-4-11 11:16
欧阳休
为你点赞~
2021-4-10 09:15
0x指纹
为你点赞~
2021-4-9 19:52
谖草
为你点赞~
2021-4-9 17:22
Editor
为你点赞~
2021-4-9 16:56
pureGavin
为你点赞~
2021-4-9 16:54
dx苹果的心愿
为你点赞~
2021-4-9 16:13
bxc
为你点赞~
2021-4-9 15:27
最新回复 (14)
雪    币: 7059
活跃值: (3537)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
2
这个厉害了!
2021-4-9 15:28
0
雪    币: 4536
活跃值: (902)
能力值: ( LV16,RANK:480 )
在线值:
发帖
回帖
粉丝
3

不好意思啊,不知道为什么markdown的格式有问题,如果看的不舒服,可以移步https://github.com/vessial/baseband/blob/master/Qualcomm_BaseBand_Messaging_and_State_Machine.md

最后于 2021-4-9 15:32 被vessial(xee)编辑 ,原因:
2021-4-9 15:30
0
雪    币: 53082
活跃值: (21135)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4

太强了!

全球范围内公开渠道还没有人写过这个类型的技术文章!

最后于 2021-4-10 10:04 被kanxue编辑 ,原因:
2021-4-9 16:14
0
雪    币: 14938
活跃值: (18125)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2021-4-9 16:54
0
雪    币: 32806
活跃值: (64396)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
6
666 感谢分享~
2021-4-9 16:57
0
雪    币: 8715
活跃值: (8619)
能力值: ( LV13,RANK:570 )
在线值:
发帖
回帖
粉丝
7
第二弹来了~
2021-4-9 22:33
0
雪    币: 5044
活跃值: (19290)
能力值: ( LV13,RANK:317 )
在线值:
发帖
回帖
粉丝
8
膜拜前辈
2021-4-9 23:57
0
雪    币: 15619
活跃值: (16982)
能力值: (RANK:730 )
在线值:
发帖
回帖
粉丝
9
这个太强了啊
2021-4-10 08:41
0
雪    币: 53082
活跃值: (21135)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
10
vessial(xee) 不好意思啊,不知道为什么markdown的格式有问题,如果看的不舒服,可以移步https://github.com/vessial/baseband/blob/master/Qualcomm_Base ...
论坛md显示优化了一下,现在界面调整好了
2021-4-10 10:04
0
雪    币: 4915
活跃值: (4757)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
好像还是有图片丢失了
2021-4-10 10:50
0
雪    币: 8441
活跃值: (2920)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
虽然看不懂,感觉很牛
2021-4-11 06:49
0
雪    币: 3867
活跃值: (4122)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
感谢分享!
2021-4-11 14:44
0
雪    币: 690
活跃值: (1846)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
14
只能膜拜了,看不懂
2021-4-13 17:39
0
雪    币: 51
活跃值: (632)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
15
看不懂 膜拜
2021-4-15 10:49
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册