红米Note 10 Pro启动modem分析

Redmi Note 10 Pro
天玑1100
CPU型号为 MT6891Z/CZA
( MT6885,天玑1000L, 联发科的首款5G芯片)

sysfs

/sys/kernel/ccci
/sys/class/ccci_node/ccci_ccb_meta
/sys/class/ccci_node/ccci_ccb_md_monitor
/sys/class/ccci_node/ccci_raw_mdm
/sys/class/ccci_node/ccci_mdl_monitor

/sys/class/ccci_md_sta/ccci_md1_sta
/sys/firmware/devicetree/base/mddriver/ccci,modem_info_v2

代码

drivers/misc/mediatek/ccci_util/ccci_util_lib_load_img.c

drivers/misc/mediatek/ccci_util/ccci_util_lib_sys.c


drivers/misc/mediatek/eccci/ccci_core.c
    ccci_init(void)



drivers/misc/mediatek/eccci/mt6885/ccci_platform.c
     ccci_plat_common_init


配置地址

drivers/misc/mediatek/eccci/ccci_modem.c
void ccci_md_config(struct ccci_modem *md)
{
	phys_addr_t md_resv_mem_addr = 0,
		md_resv_smem_addr = 0, md1_md3_smem_phy = 0;
	unsigned int md_resv_mem_size = 0,
		md_resv_smem_size = 0, md1_md3_smem_size = 0;
	int amms_pos_size = 0;
	phys_addr_t bank4_phy_addr;
......
......
	/* Get memory info */
	get_md_resv_mem_info(md->index, &md_resv_mem_addr,
		&md_resv_mem_size, &md_resv_smem_addr, &md_resv_smem_size);
	get_md1_md3_resv_smem_info(md->index, &md1_md3_smem_phy,
		&md1_md3_smem_size);
	/* setup memory layout */
	/* MD image */
	md->mem_layout.md_bank0.base_ap_view_phy = md_resv_mem_addr;
	md->mem_layout.md_bank0.size = md_resv_mem_size;
	/* do not remap whole region, consume too much vmalloc space */
	md->mem_layout.md_bank0.base_ap_view_vir =
		ccci_map_phy_addr(
			md->mem_layout.md_bank0.base_ap_view_phy,
			MD_IMG_DUMP_SIZE);
	/* Share memory */
	/*
	 * MD bank4 is remap to nearest 32M aligned address
	 * assume share memoy layout is:
	 * |---AP/MD1--| <--MD1 bank4 0x0 (non-cacheable)
	 * |--MD1/MD3--| <--MD3 bank4 0x0 (non-cacheable)
	 * |---AP/MD3--|
	 * |--non-used_-|
	 * |--cacheable--| <-- MD1 bank4 0x8000000 (for 6292)
	 * this should align with LK's remap setting
	 */



eccci/modem_sys1.c
    ccci_set_mem_access_protection_1st_stage(md);


eccci/fsm/ccci_fsm.c

    ccci_set_mem_access_protection_second_stage








modem firmware的结构
代码位于 drivers/misc/mediatek/ccci_util/ccci_util_lib_load_img.c



#define IMG_MAGIC		0x58881688
#define EXT_MAGIC		0x58891689

#define IMG_NAME_SIZE		32
#define IMG_HDR_SIZE		512
union prt_img_hdr {
	struct {
		/* always IMG_MAGIC */
		unsigned int magic;
		/* image size, image header and padding are not included */
		unsigned int dsize;
		char name[IMG_NAME_SIZE];
		/* image load address in RAM */
		unsigned int maddr;
		/* maddr is counted from the beginning or end of RAM */
		unsigned int mode;
		/* extension */
		/* always EXT_MAGIC */
		unsigned int ext_magic;
		/* header size is 512 bytes currently,
		 * but may extend in the future
		 */
		unsigned int hdr_size;
		/* see HDR_VERSION */
		unsigned int hdr_version;
		/* please refer to #define beginning with SEC_IMG_TYPE_ */
		unsigned int img_type;
		/* end of image list?
		 * 0: this image is followed by another image
		 * 1: end
		 */
		unsigned int img_list_end;
		/* image size alignment setting in bytes,
		 * 16 by default for AES encryption
		 */
		unsigned int align_size;
		/* high word of image size for 64 bit address support */
		unsigned int dsize_extend;
		/* high word of image load address in RAM
		 * for 64 bit address support
		 */
		unsigned int maddr_extend;
	} info;
	unsigned char data[IMG_HDR_SIZE];
};

USRP B210

SMA天线接口 有3个输入信号:
1. 外部 PPS 参考
2. 10 MHz 时钟 参考
3. GPS信号
都是所谓 Timing Reference Input (定时基准输入)

1 PPS
秒脉冲 (Pulse Per Second)

PPS 时间参考 和 10MHz 时钟参考,主要用于多个 B210之间进行同步。
B210接受外部PPS信号进行时间校准,以及10 MHz参考频率校准—这允许外部时间和频率源用于更精确的同步
GPS则可实现 在物理位置上相距非常大的 多个B210之间 的时间同步。

GPS时钟主要分为两类,
一类是GPS授时仪,主要输出时标信息,包括1 PPS及TOD信息;
另外一类是GPS同步时钟,后者输出利用卫星信号驯服OCXO或者铷钟得到的高稳定频率信息,以及本地恢复的更平稳的时标信号。

高精度1 PPS信号,精度优于50ns,占空比为50%,1 PPS信号 上升沿为时间同步点,上升沿时间小于5ns。


两个接收前端共享RX LO(本振),而两个发射前端共享TX LO。每个本振可在50mhz和6ghz之间独立调谐,可用于1或2个信道;所有使用相同本振的信道必须使用相同的采样参数,包括采样率和射频中心频率。


附带的USB 3.0电缆为USRP总线系列提供电源和数据连接。
我的板子带了GPSDO,必须连接外部直流电源(12V 3A)

所有GPSDO都有一些共同的特性。每个GPSDO包括一个10 MHz振荡器,可以是TCXO或OCXO。10MHz振荡器可以独立工作,也就是说,
即使GPSDO没有锁定到卫星星座,它也可以提供时钟。

根据GPSDO型号,解锁振荡器将提供20~75 ppb之间的系统频率精度。
GPSDO模块还将产生1-pps信号,用于定时同步。如果连接了GPS天线,GPSDO将锁定到GPS卫星星座,并且10 MHz振荡器可以按照全球GPS标准进行调节。在这种情况下,1-pps信号也将在50ns内与全球标准对齐。

共享一个时钟总是比尝试通过GPS同步要好。gpsdo将代替共享时钟,提供下一个最佳的同步级别,这对于大多数应用程序来说已经足够了。

但前面也说了,GPS也更加灵活,因为设备可以在地理上相隔十万八千里,但依然保持同步。

板载OCXO和板载TCXO的结构和工作原理是相同的。然而,TCXO消耗较少的功率,在其整个温度范围内提供较少的精度,并且具有不同的相位噪声特性。

我的是 OCXO, 需要外接电源。


输入/输出阻抗
所有射频端口通常匹配50欧姆,回波损耗为-10dB或更好


LED600 电源指示
灭 = 无供电 或者 外部供电,但初始化 未完成
蓝 = USB供电
红 = 外部供电成功(初始化完成)

LED800 通道2 接收2
灭 = 无供电
绿色 = 正在接收

LED801 通道2 发送/接收
灭 = 无供电
绿色 = 正在接收
红色 = 正在发送
橙色 = 正在切换(发送或接收)

LED802 通道1 发送/接收
灭 = 无供电
绿色 = 正在接收
红色 = 正在发送
橙色 = 正在切换(发送或接

LED803 通道1 接收2
灭 = 无供电
绿色 = 正在接收

LED100 GPS锁定指示
灭 = 没有锁定
绿色 = 已经锁定


J601 外部供电接口 6V 3A
J701 USB3 接口
J104 外部PPS 输入 (1.8 V – 5 V )
J101 GPS天线 (GPSDO will supply nominal voltage to antenna)
J100 外部10 MHz输入 (最大 +15 dBm )
J800 射频天线B TX/RX (发射功率 最大+20 dBm, 接收 -15 dBm)
J802 射频天线B 接收2 ( 接收 -15 dBm)
J803 射频天线A 接收2 ( 接收最大 -15 dBm)


当使用 GPSDO 时, 不能使用 外部10MHz 输入, 除非将 GPSDO从板子上拿走

MIPS16

MIPS16
MIPS16是从MIPS I到V的特定应用扩展,由LSI Logic和MIPS科技设计,于1996年10月21日与其第一个实现LSI Logic TinyRISC处理器一起发布

MIPS16使用16位指令而不是32位指令,减少应用程序的大小多达40%,并且还提高了电源效率、指令缓存命中率,并且在性能方面与其基础架构相当。它由MIPS科技和其他供应商的硬件和软件开发工具提供支持。

MIPS16e是MIPS16的改进版本,首先由MIPS32和MIPS64 Release 1支持。MIPS16e2是MIPS16的改进版本,由MIPS32和MIPS64(直到Release 5)支持。Release 6将其替换为microMIPS。

microMIPS32/64架构(分别)是MIPS32和MIPS64架构的超集,旨在取代MIPS16e ASE。MIPS16e的一个缺点是在处理任何16位指令之前需要切换模式。microMIPS将最常用的32位指令编码为16位指令版本。允许程序混合16位和32位指令而无需切换模式。microMIPS与MIPS32/64 Release 3一起推出,MIPS32/64的每个后续版本都有相应的microMIPS32/64版本。处理器可以单独实现microMIPS32/64,或同时实现microMIPS32/64及其相应的MIPS32/64子集。从MIPS32/64 Release 6开始,对MIPS16e的支持结束,microMIPS是MIPS中唯一的代码压缩形式。

nanoMIPS32


MIPS有几个调用约定,尤其是在32位平台上。

O32 ABI是最常用的ABI,因为它是MIPS的原始System V ABI。它严格基于堆栈,只有四个寄存器$a0-$a3可用于传递参数。堆栈上的空间是保留的,以防被调用者需要保存其参数,但调用者不会将寄存器存储在那里。返回值存储在寄存器$v0中;第二个返回值可以存储在$v1中。ABI形成于1990年,最后一次更新是在1994年。这种肉眼可见的缓慢,以及只有16个寄存器的老式浮点模型,促进了许多其他调用约定的扩散。它仅针对32位MIPS定义,但GCC创建了一个名为O64的64位变体

对于O32及N32/N64,返回地址存储在$ra寄存器中。这是使用JAL(跳转和链接)或JALR(跳转和链接寄存器)指令自动设置的。(非叶子)MIPS子例程的函数序言将返回地址(在$ra中)推入堆栈


MediaTek has adopted multi-threaded MIPS I-class CPUs for smartphone LTE modems. The first device from MediaTek featuring MIPS technology is the new flagship MT6799 Helio™ X30 processor which uses MIPS in its Cat-10 LTE modem.

自从 2014 年发布 MIPS R6 版本之后, MIPS 公司的 IP Core 产品全面转向 MIPS R6 版本,形成覆盖高中低不同性能和应用需求的 Warrior 产品系列, 而把 R6 之前的产品全部归为 Classic 系列。 Warrior 产品系列又分为 M-Class, I-Class 和 P-Class 三个级别,覆盖了从 32 位微控制器到 64 位服务器与基础设施之间的所有领域。

P-class 采用 MIPS R6 MIPS 指令集,当前的产品是 P6600 (MIPS64 R6) 和 P5600 (32-bit MIPS32 R5)。
I-class 采用 MIPS R6 nanoMIPS 指令集,用于嵌入式设备,当前的产品是 I7200 (2.1 GHz, 32-bit nanoMIPS),I6500-F (MIPS64 R6),I6500 (MIPS64 R6) 和 I6400 (MIPS64 R6)。
M-class 采用 MIPS R6 microMIPS 指令集,用于微控制器,当前的产品是 M6250 (64 bit,4GB Virtual Memory,750 MHz),M6200,M51xx。

联发科用于modem的就是I系列, nanomips指令集

nanoMIPS designed for embedded devices, it can deliver up to 40% smaller code than MIPS32. With smaller memory accesses and efficient use of the instruction cache, nanoMIPS also helps to reduce system power consumption.


联发科的4G处理器 Helio 系列的是 MIPS16e2
5G处理器 Dimensity的是 nanoMIPS

MT6763 modem 编译

modem部分,MTK给 大的手机公司(小米、OPPO、vivo) 比如大的设计公司 (华勤通讯、龙旗科技、闻泰科技) 和 模块厂商 (移远,广和通,美格,日海) 才是全部源代码。

小厂家拿到 都是 二进制的lib 和 部分定制参数的 源代码

magnet:?xt=urn:btih:f677fe1da33fd349130cdb2404a13c8ecdf7da4f&dn=t-alps-q0.mp1-V9.122.1
里面的
TK_MD_BASIC_MOLY.LR12A.R2.MP.V143.7.tar.zst

推荐的编译环境

 Recommended Build Environment
*******************************************
* [OS]         : Linux
* [PERL]       : v5.14.2 or v5.18.4  / v5.26.1
* [MAKE]       : GNU Make v3.81   / v4.1
* [SHELL]      : GNU bash v4.2.25 or v4.3.11
* [COMPILER]   : v4.9.2 or above
* [Host GCC]   : gcc version 4.8.4
* [Perl Module]: Switch.pm, File/Copy/Recursive.pm, XML/Simple.pm

实际的编译环境
Debian Buster
[PERL] : v5.28.1
[MAKE] : GUN Make v4.2.1
[COMPILER] : v4.9.2(2016.05-08) [OK]
[HOST GCC] : v8.3.0

apt install build-essential
apt install libswitch-perl    libfile-copy-recursive-perl  libxml-simple-perl

https://codescape.mips.com/components/toolchain/2016.05-08/Codescape.GNU.Tools.Package.2016.05-08.for.MIPS.MTI.Bare.Metal.CentOS-5.x86_64.tar.gz
(MTI Bare Metal Toolchain MIPS32R2-MIPS32R5, MIPS64R2-MIPS64R5 and microMIPS)

编译 硬件配置 16G RAM, 100G Storage

mkdir ~/modem
cd  ~/modem
tar xvaf ~/Downloads/TK_MD_BASIC_MOLY.LR12A.R2.MP.V143.7.tar.zst
cd mcu/common/tools
mkdir -p GCC/MIPS/4.9.2
cd GCC/MIPS/4.9.2
tar xvaf ~/Downloads/Codescape.GNU.Tools.Package.2016.05-08.for.MIPS.MTI.Bare.Metal.CentOS-5.x86_64.tar.gz
cd mips-mti-elf
mv 2016.05-08/ ../linux
cd  ~/modem/
cd mcu
common/tools/GCC/MIPS/4.9.2/linux/bin/mips-mti-elf-gcc -v

MIPS gcc 的版本应该是 2016.05-08

cd ~/modem
cd mcu
ls -a make/projects

可以看到
'TK_MD_BASIC(LWCTG_R2_6763).mak'  'TK_MD_BASIC(LWTG_R2_6763).mak'

开始编译

./m  "TK_MD_BASIC(LWTG_R2_6763).mak"  new

在编译前,可以对定制目录 mcu/pcore/custom 的内容进行修改

编译生成的 结果在 mcu/build/TK_MD_BASIC/LWTG_R2_6763/bin 目录下

TK_MD_BASIC_MDBIN_PCB01_MT6763_S00.MOLY_LR12A_R2_MP_V143_7.bin
就是
md1bin.img (也就是 md1rom)

DbgInfo_LR12A.R2.MP_TK_MD_BASIC_MOLY_LR12A_R2_MP_V143_7_2024_02_15_09_49

md_all_in_one/single_bin_modem.bin


perl device/mediatek/build/build/tools/modemRenameCopy.pl ./ “TK_MD_BASIC(LWTG_R2_6763).mak”

执行modemRenameCopy.pl脚本,这个步骤一定不能漏掉。

它的作用是把所有需要拷贝到AP端的文件收集到temp_modem文件夹中(modem codebase根目录下),并且还会生成一个Android.mk文件。
————
在Android源码目录device/mediatek/build/build/tools 下执行命令来重命令打包modem镜像
在Linux环境下进入如上Android目录,执行命令
./modemRenameCopy.pl ~//mtk/modem/mcu “TK_MD_BASIC(LWCTG_R2_6763).mak”

然后在modem代码目录modem/mcu/temp_modem下会生成新的modem镜像文件

将md1bin.img修改成md1img.img和md1dsp.img一起放入到版本目录中,就可以用于刷机

高通modem启动过程

HLOS kernel通过PIL加载MBA(Modem Boot Authenticator)到DDR
TrustZone 按照 mba.mdt的签名信息 对 mba 进行验证
HLOS kernel对Hexagon modem DSP 复位
Modem PBL(Primary BootLoader,位于rom中) 开始启动
HLOS kernel 通过PIL (Peripheral image loader) 加载modem image到DDR
Modem PBL验证MBA, 然后跳转到MBA

在msm8909平台上,需要签名的文件如下:

 boot_images/build/ms/bin/8909/emmc/sbl1.mbn 
 boot_images/build/ms/bin/8909/emmc/unsigned/prog_emmc_firehose_8909_ddr.mbn 
 LINUX/android/out/target/product/msm8909/emmc_appsboot.mbn 
 modem_proc/build/ms/bin/8909.gen.prod/mba.mbn 
 modem_proc/build/ms/bin/8909.gen.prod/qdsp6sw.mbn 
 rpm_proc/build/ms/bin/8909/pm8909/rpm.mbn 
trustzone_images/build/ms/bin/MAZAANAA/tz.mbn 
 wcnss_proc/build/ms/bin/SCAQMAZ/reloc/wcnss.mbn 

Modem Primary Boot Loader 的功能:

Sets up Hexagon TCM, copies MBA from LPDDR3 into Hexagon TCM, and authenticates MBA in Hexago TCM

Modem Boot Authenticator 的功能:
Authenticates the modem image, xPU protects the DDR regions for modem, and memory dump


签名镜像格式
Qualcomm Technologies 固件镜像使用标准 ELF 格式

ELF 标头主要用于定位 ELF 镜像文件中的程序标头。程序标头包含 ELF 镜像文件中所有段的位置,特别是用于定位 ELF 文件中的哈希段,其中包含用于验证 ELF 镜像的验证信息。

哈希段(hash segment)按顺序包含以下信息:

(1) 哈希段标头(元数据)是一个 48 字节的字段(Field),其中包含有关哈希段其他部分大小的信息。这允许在哈希段内识别字段。
(2) QTI 和设备制造商元数据字段都是 128 字节的字段,其中包含有关镜像的信息,例如镜像的类型和设计用于运行镜像的硬件。 QTI 元数据仅在镜像由 QTI 和设备制造商双重签名时才存在。
(3) 哈希表字段包含 ELF 文件中每个段(Segment)的哈希值。第一个条目(Entry)始终是 ELF 标头和程序标头的哈希值。这是为了确保标头段中的重要信息也得到验证(包括 ELF 标头中包含的镜像入口点地址)。
hash table field

(4) QTI签名和证书链。数字签名是根据哈希段标头、镜像元数据和哈希表(hash table)计算的。可以使用叶证书(Leaf Certificate)中的公钥对其进行验证。证书链最终由一个根证书验证,该根证书根据硬件中保存的 QTI 特定值进行验证。仅当镜像由 QTI 和设备制造商双重签名时,才应存在 QTI 签名和证书链。

(5) 设备制造商签名和证书链。与 QTI 签名和证书链一样,数字签名是根据哈希段标头、图像元数据和哈希表计算的,它可以使用证书链叶节点中的公钥进行验证,该公钥可以最终通过根证书进行验证,根证书根据硬件中的 OEM 特定值进行验证

镜像元数据(Image Metadata)描述了镜像的意图(intent)。最重要的是,它描述了镜像的意图(以便在要加载 Qualcomm TEE 镜像时系统不会加载 WLAN 镜像)和用于执行镜像的硬件(以便系统不会在 Qualcomm® Snapdragon™ 845 设备上加载 Snapdragon 835 的 Modem 镜像)。

在旧版本的 QTI 安全启动架构中,此信息已被编码到证书链中叶证书的组织单位(OU,Organizational Unit)字段中。新版本的安全引导格式将此信息移动到独立的元数据字段中。这旨在通过降低解析或证书创建错误的可能性来提高安全性,这些错误可能导致镜像不具有设备制造商预期的属性。

元数据字段允许签名者指定有关镜像的信息,包括以下内容:

镜像的软件标识(SW_ID)。每种不同的镜像类型都有不同的软件标识。这是为了确保在引导过程中正确的时间点加载正确的镜像。
设备的硬件标识(HW_ID)。每个 QTI 芯片组都有不同的硬件标识。这是为了确保只有那些被设计为在该硬件上执行的镜像才能在该硬件上执行。
设备制造商标识(OEM_ID)。这是为了确保由一个设备制造商签名的软件不能在另一个制造商的设备上运行,即使它们共享一个公共根证书。
设备的调试功能。某些镜像允许签名者在设备上启用调试功能;但是,签名者只能在特定设备(必须在镜像签名时标识)上使用这些功能。
镜像是绑定到单个设备还是可以在所有设备上使用。出于开发和调试目的,可以通过指定设备的序列号并在镜像元数据字段中设置标志来将镜像绑定到单个设备。每个设备都有一个不同的序列号,该序列号在制造过程中被烧入芯片中。
镜像的防回滚版本号。如果启用,则防回滚系统将防止已知存在错误的镜像在设备上运行。该架构旨在防止设备在成功加载具有更大防回滚版本号的镜像时接受镜像。

如果镜像由 QTI 和设备制造商签署,则 QTI 和设备制造商都将提供镜像元数据字段。两个元数据字段中的所有条件都必须有效才能加载镜像。

镜像加载

所有镜像加载都遵循相同的通用过程。在本节中,我们将加载镜像的软件称为“加载程序”(Loader)。流程如下:

加载程序分配一个安全的内存区域来加载 ELF 标头,该内存将被映射(mapped)以防止它被设备中的其他执行环境篡改,加载程序将 ELF 标头从(不受信任的 untrusted)存储(storage)复制到此内存中。如果因 ELF 标头太大而无法放入此内存区域,则镜像将被拒绝。

加载程序分配一个安全的内存区域来加载程序头(Program Header),该内存将被映射以防止它被设备中的其他执行环境篡改,加载程序将程序标头从(不受信任的)存储复制到此内存中。如果因程序标头太大而无法放入此内存区域,则镜像将被拒绝。

加载程序分配一个安全的内存区域来加载哈希段(hash segment),该内存将被映射以防止它被设备中的其他执行环境篡改,加载程序将哈希段从(不受信任的)存储复制到此内存中。如果因哈希段太大而无法放入此内存区域,则镜像将被拒绝。

加载程序通过验证根证书、证书链、镜像元数据和哈希表(hash table)来验证哈希段(hash segment)。

加载程序通过计算(已加载的)ELF 头 和 程序头 的哈希值并将哈希值与哈希表中的第一个条目进行比较来验证它们。如果哈希值不匹配,则镜像将被拒绝。

The loader validates the (already loaded) ELF Header and Program Header by hashing them and
comparing the hash value with the first entry in the hash table. If the hashes do not match, the
image is rejected.

然后加载程序将尝试加载镜像中的其他每个 ELF 段。对于每个段,加载程序检查整个段是否可以加载到其已批准(列入白名单)的安全且适合该镜像的内存区域中,如果无法加载段到内存的白名单区域,则镜像将被拒绝。

The loader will then attempt to load each of the other ELF segments in the image. For each
segment, the loader checks that the entire segment can be loaded into an area of memory that
has been approved (whitelisted) by the loader as safe and appropriate for that image. If a
segment cannot be loaded into a whitelisted area of memory, the image is rejected.

加载程序通过计算每一个加载的 ELF 段的哈希值并将哈希值与哈希表中的相应条目进行比较来验证。如果任何计算的哈希值与哈希表中的值不同,则镜像将被拒绝。
The loader verifies each of the loaded ELF segments by hashing them and comparing the hash
value with the corresponding entry in the hash table. If any of the computed hash values differ
from the value in the hash table, the image is rejected.

如果合适,加载程序使用在(已经加载和验证的)ELF 标头中定义的入口点将执行传递给镜像。

If appropriate, the loader passes execution to the image using the entry point defined in the
(already loaded and validated) ELF Header.

此过程旨在确保加载程序永远不会意外覆盖包含从不受信任的存储中加载的镜像数据的内存中的重要数据(包括加载程序自己的代码和数据)。


Modem Image modification
Modem image patching

Modem binaries are unencrypted on disk
modem 二进制代码以未加密的形式保存在 文件系统中
This facilitates easy disassembly, and easy patching
这有助于 反汇编 和打补丁
Secboot prevents unsigned images from loading
但是,安全启动机制,阻止 载入未签名的映像。
Signature verification performed in secure world
签名验证 执行在 安全世界 (Trustzone)

Leverages a integer overflow to achieve an arbitrary write into the trustzone, and patches two bytes to neuter signature checking.

Prereqs: ability to compile your own kernel and flash it,
Modem internal hashes still need to be consistent

https://github.com/eti1/tzexec
https://github.com/eti1/pymdt
https://github.com/laginimaineb/unify_trustlet


mdt: contains headers and information (certificate chain and signature blob) used to verify *.bxx

———————-
A bug can bypass the MBA to inject Hexagon code
– Ability to read/write modem memory at any time from the Linux kernel
– Reported to Qualcomm, patch in development
————————-

missing sections with critical OTA vectors code (q6zip decompressed & relocated in runtime)

——————
hash table segment 也是一个elf segment,只是qualcomm为这个hash table segment设置了自定义的格式。

hash table segment 包含:
mbn header: hash table segment各个field的位置信息
QTI metadata: Qualcomm对当前image设置的一些信息
OEM metadata: OEM对当前image设置的一些信息
Hash Table: 该ELF文件的{ elf header + program header}的hash、其他elf segments的hash
QTI signature
QTI Cert Chain
OEM signature
OEM Cert Chain
0xFF padding


QTI signature/OEM signature所对应的原文范围都是 { mbn header, QTI metadata, OEM metadata, Hash Table }

Qualcomm Hexagon DSP

QDSP6 V4, 用于 S400 和 S600产品中,3G 4G换代的时代, 如8926, 8930, 8230, 8630, 8930AB, 8230AB, 8630AB, 8030AB, 8226, 8626
8064T, 8064M等
QDSP6 V5(V5A, V5H) 用于 Snapdragon 410/412/800/801 (如8974, 8274, 8674, 8074) 处理器中,2013-2015年产品
Hexagon 536 DSP, 用于 Snapdragon 205/208/210/212, 425/427/429/430/435/439 处理器中
V50 , 用于 Snapdragon 415/610/615/616/805
546 , 用于 Snapdragon 450/617/625/626/632
V56 , 用于 Snapdragon 650/652/653/808/810
642 , 用于 Snapdragon 630
QDSP6 V6/680, 用于 Snapdragon 820/821/636/660
682, 用于 Snapdragon 835
683 , 用于 Snapdragon 662/460
685 , 用于 Snapdragon 850/845/670/675/678/710/712
686 , 用于 Snapdragon 695/685/680/665/480/480+
688 , 用于 Snapdragon 730(G)/732G
690 , 用于 Snapdragon 855/855+/860/8c/8cx , Microsoft SQ1/SQ2
692 , 用于 Snapdragon 720G/690/7c
694 , 用于 Snapdragon 750G
696 , 用于 Snapdragon 765(G)/768G
698 , 用于 Snapdragon 865(SM8250)/865+/870
770 , 用于 Snapdragon 778G/778G+/780G/782G
780, 用于 Snapdragon 888((SM8350), 888+ ((SM8350P) ,
790 , 用于 Snapdragon 8 gen 1 ((SM8450), 8+ gen 1 ((SM8475)
Hexagon V73 , 用于 Snapdragon 8 gen 2 ((SM8550)

https://en.wikipedia.org/wiki/Qualcomm_Hexagon

https://github.com/n-o-o-n/idp_hexagon
Supports all Hexagon versions: V4, V5, V55, V60, V61, V62, V65, V66, V67, V67t, V68, V69, V71, V73

https://github.com/gsmk/hexagon

编译MSM8626 modem

参考:
Building Qualcomm modem from sources (msm8626)

Assembling a Qualcomm modem from source(msm8916)

Assembling a Qualcomm modem from source(msm8626)(原文是俄语)

https://projects.osmocom.org/projects/quectel-modems/wiki/Lenovo_A6000__Other_phones_with_leaked_qualcomm_sources

 

 

0.    首先在磁力链上下载

(1)

qcom_msm8x26_modem

magnet:?xt=urn:btih:61e8b8a520181ade801c251e5ec9352e33a7bb8c&dn=qcom_msm8x26_modem

(2)

qcom_leaked_sources.zip

magnet:?xt=urn:btih:ef3bf4fd7388657ff35c3dbf2b6367f924f8cdbc&dn=qcom_leaked_sources.zip

 

在gitlab也可以下载

https://gitlab.com/qcom-sources15

 

(3)

THE-CODE-8916.zip

http://www.mediafire.com/file/0t1znbr1sl2y6fm/THE-CODE.zip

http://www.mediafire.com/file/awo4z3i3j4qdz45/THE-CODE-8916.gz

 

1.  安装 Debian 或者 Ubuntu系统

我安装的是 Debian Buster  (Debian 10.1.3)  amd64

 

2.  安装必须的软件包

<pre>

apt install      p7zip-full    libxml-parser-perl      scons       lib32stdc++6

</pre>

p7zip-full  用来解压缩 下载的源代码

libxml-parser-perl  用来分析xml配置文件, debian系统 安装基本系统时就默认装好了

libc6-i386    lib32stdc++6  是因为  qcom 的 dsp编译程序实际是 32位的,必须装上32位的支持包

 

3.  安装HEXAGON Tools 到 特定的目录

HEXAGON_ROOT=$HOME/Qualcomm/HEXAGON_Tools
7za x -y -o$HEXAGON_ROOT $HOME/Downloads/hexagon_tools_6.4.06.a.7z

假设 将 hexagon_tools_的压缩包,放在了 $HOME/Downloads 目录下, 如果放在其他目录,对上面的命令自行修改

4. 解压缩 msm8626 modem的源代码

ROOTDIR=$HOME/qcom/msm8626
mkdir -p $ROOTDIR
cd $ROOTDIR
7za x -y -0$ROOTDIR     $HOME/Downloads/qcom_msm8626_modem_proc.7z
mv   qcom_msm8626_modem_proc   modem_proc
cd $ROOTDIR/modem_proc

因为压缩包没有保持 UNIX文件属性,sh脚本没有执行权限,需要修复

find . -name '*.sh' -exec chmod -f 775 {} \;
find . -name '*.mk' -exec chmod -f 775 {} \;
find . -name '*.py' -exec chmod -f 775 {} \;
find . -name '*.pl' -exec chmod -f 775 {} \;
find . -name '*.lcs' -exec chmod -f 775 {} \;
find . -name '*.api' -exec chmod -f 775 {} \;
find . -name '*.xml' -exec chmod -f 775 {} \;
find . -name '*.scons' -exec chmod -f 775 {} \;
find . -name 'scons' -exec chmod -f 775 {} \;
find . -name 'SConscript' -exec chmod -f 775 {} \;
find . -name 'SConstruct' -exec chmod -f 775 {} \;
find . -name 'Makefile' -exec chmod -f 775 {} \;
find . -name 'makefile' -exec chmod -f 775 {} \;
find . -name 'qaic' -exec chmod -f 775 {} \;
find . -name 'doxygen' -exec chmod -f 775 {} \;
find . -name 'qdsp6-image-build' -exec chmod -f 775 {} \;
find . -name 'SleepSynth' -exec chmod -f 775 {} \;
find . -name 'crypto_cbc' -exec chmod -f 775 {} \;
find . -name 'crypto_ccm' -exec chmod -f 775 {} \;

5. 开始编译

cd $ROOTDIR/modem_proc/build/ms/
./build.sh 8626.gen.prod BUILD_ID=AAAAANAZ -k

编译成功,提示

Elfparser Merge: Copying 4376 bytes from ELF file /home/softsim/qcom/msm8626/modem_proc/build/ms/M8x26AAAAANAZQ00772_DEVCFG.elf section ".8626_PLATFORM_CDP_DEVCFG_DATA" at offset 0x1e1a0 into merged_elf_8626_PLATFORM_MTP_MSM_DEVCFG_DATA.elf at offset 0x1b931a0                
Install file: "/home/softsim/qcom/msm8626/modem_proc/core/bsp/devcfg_img/build/devcfg_img/qdsp6/AAAAANAZ/M8x26AAAAANAZQ00772.elf" as "M8x26AAAAANAZQ00772.elf"                                                                                                                      
=== Generating  devcfg_img/qdsp6/AAAAANAZ/M8x26AAAAANAZQ00772_reloc.elf
=== Generating  devcfg_img/qdsp6/AAAAANAZ/M8x26AAAAANAZQ00772.mbn
=== Generating  devcfg_img/qdsp6/AAAAANAZ/M8x26AAAAANAZQ00772_relocflags.elf
Install file: "/home/softsim/qcom/msm8626/modem_proc/core/bsp/devcfg_img/build/M8x26AAAAANAZQ00772.mbn" as "bin/AAAAANAZ/qdsp6sw.mbn"
=== Generating  devcfg_img/qdsp6/AAAAANAZ/M8x26AAAAANAZQ00772.mbn
Install file: "/home/softsim/qcom/msm8626/modem_proc/core/bsp/devcfg_img/build/reloc/M8x26AAAAANAZQ00772.mbn" as "bin/AAAAANAZ/reloc/qdsp6sw.mbn"                                                                                                                                   
scons: done building targets.

==============================================================================
   SCons build summary
==============================================================================
** Build time...
 Build start  : Sat Jan 27 19:06:15 2024
 Build end    : Sat Jan 27 19:19:38 2024
 Elapsed time : 0:13:24
#-------------------------------------------------------------------------------
# BUILD END: AAAAANAZ
#-------------------------------------------------------------------------------
Build AAAAANAZ: Start Time: Sat Jan 27 19:06:15 2024,  End Time: Sat Jan 27 19:19:40 2024
Build AAAAANAZ: Delta Time: 13 minutes, 24 seconds
#-------------------------------------------------------------------------------
Overall Start Time: Sat Jan 27 19:06:15 2024,  Overall End Time: Sat Jan 27 19:19:40 2024
Overall Delta Time: 13 minutes, 24 seconds
#-------------------------------------------------------------------------------

可以看到,生成了 bin/AAAAANAZ/qdsp6sw.mbn 这个 modem文件

6. 清除编译的结果

./build.sh 8626.gen.prod BUILD_ID=AAAAANAZ --clean

遇到错误,修正后,重新编译前,可以先清楚。

7. mba.mbn 和 qdsp6sw.mbn 都没有做数字签名
准确地说,是用的高通给的测试签名, 可以在 firmware/image/modem.mdt 文件里看到 “General Use Test Key (for testing only)” 字符串
说明就是测试签名

编译骁龙400 modem固件

2013年上市, ARM Cortex-A7 , 28nm LP 工艺生产

8226, 8626, 8228, 8628
红米手机1S, 酷派8702, 中兴Q505T, 联想s810t,天语touch2

准备工作

apt install p7zip-full
apt install lib32z1 lib32ncurses5
apt install scons
apt install libxml-parser-perl