OAI 5G NR SA tutorial with COTS UE
https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/NR_SA_Tutorial_COTS_UE.md
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一起放入到版本目录中,就可以用于刷机
用Ghidra分析mediatek基带
https://samfw.com/firmware/SM-A415F/XEF/A415FXXU1ATE1
高通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)
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. 安装必须的软件包
apt install p7zip-full libxml-parser-perl scons lib32stdc++6
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
qualcomm subsystem
https://android.googlesource.com/kernel/msm/+/refs/tags/android-13.0.0_r0.46/drivers/soc/qcom/subsystem_restart.c
static const char * const restart_levels[] = { [RESET_SOC] = "SYSTEM", [RESET_SUBSYS_COUPLED] = "RELATED", };
restart level (0 – panic, 1 – related, 2 – independent, etc.)
static int subsystem_shutdown(struct subsys_device *dev, void *data)
static int subsystem_powerup(struct subsys_device *dev, void *data)
static int subsys_start(struct subsys_device *subsys)
static void subsys_stop(struct subsys_device *subsys)
int subsystem_set_fwname(const char *name, const char *fw_name)
int subsystem_restart_dev(struct subsys_device *dev)
int subsystem_restart(const char *name)
restart_level的设置为related, 就只重启该子系统,而不是重启整个系统
init.svc.vendor.ssr_setup
init.svc_debug_pid.vendor.ssr_setup
persist.vendor.ssr.enable_ramdumps
persist.vendor.ssr.restart_level
/vendor/bin/ssr_setup (binary exe)
vendor/qcom/proprietary/ss-restart/ssr_setup/ssr_setup.c
[persist.vendor.ssr.restart_level]: [ALL_ENABLE] 应该设置为 modem
The Peripheral Image Loader (PIL) is a framework that allows services to load and reload firmware images for each subsystem of the chipset into DDR memory. Upon loading, TrustZone’s services are invoked to authenticate the content of the image file using a hash segment. Once the image is authenticated, the processor of that subsystem is taken out of reset, i.e., allowed to execute instructions.
外设映像加载器 (PIL) 是一个框架,它允许服务将芯片组每个子系统的固件映像加载和重新加载到 DDR 内存中。 加载后,将调用 TrustZone 的服务以使用哈希段来认证映像文件的内容。 一旦认证通过,该子系统的处理器就会脱离复位状态,也就是允许执行指令。
Firmware images are written in ELF (Executable and Linkable Format), which consists of a metadata portion and a program portion.
The program portion is further split up into multiple files. This splitting is done for several reasons:
1. If authentication information is found to be invalid, we do not need to load the entire image.
2. It is advantageous in low memory conditions since the amount of memory used at any given instance, when loading one segment at a time, is smaller than loading the whole image as one file.
3. Allows more flexibility for future changes to the loading procedure. The firmware image filenames all begin with a base name that matches the name of the peripheral, e.g., “modem”.
固件映像以 ELF(可执行和可链接格式)编写,由元数据部分和程序部分组成。
程序部分进一步分为多个文件。 进行这种拆分有几个原因:
1.如果发现认证信息无效,我们不需要加载整个映像。
2. 这在低内存条件下是有利的,因为在任何给定实例中,每次加载一个片段时使用的内存量小于将整个映像作为一个文件加载。
3. 为未来加载程序的更改提供更大的灵活性。 固件映像文件名均以与外围设备名称匹配的基本名称开头,例如“modem”。
modem.b01, modem.b02, ….
The metadata file has an extension of .mdt . This comprises the ELF header, program headers, hash, and signature.
The program segment files are named with numbered extensions in the form of .bXX, where XX is the index of the sengment beginning from 00, i.e., .b01, .b02, .b03, etc. Each of these files is referred to as a segment or a “blob”.Firmware files are expected to be placed under /etc/firmware. The PIL loads each segment of the ELF image from the firmware directory using generaic kernel method request_firmware().
This places the segment into the relevant memory hole. Once loaded, TrustZone is invoked to authenticate the segment. After all the firmware segments have been successfully loaded and authenticated, PIL resets the subsystem and initiate its boot sequence.
元数据文件的扩展名为 .mdt 。 这包括 ELF 标头、程序标头、哈希值和签名。
程序段文件以 .bXX 的形式以编号扩展名命名,其中 XX 是从 00 开始的段索引,即 .b01、.b02、.b03 等。
这些文件中的每一个都称为一个 段或“blob”。
固件文件应放置在 /etc/firmware (/vendor/firmware_mnt) 下。
PIL 使用通用内核方法 request_firmware() 从固件目录加载 ELF 映像的每个片段。
这会将段放入相关的内存孔中。 加载后,将调用 TrustZone 来认证该段。
所有固件段均已成功加载并经过认证后,PIL 会重置子系统并启动其引导序列。
PIL is implemented as a kernel driver at the following location: kernel root/drivers/soc/qcom/peripheral-loader.c
Generic PIL drivers: kernel root/drivers/soc/qcom/subsys-pil-tz.c
Drivers implement power up, shutdown, error handling, and RAM dump of the subsystem. Interfaces are encapsulated and registered to the SSR driver.
PIL被实现为一个内核中的驱动,位置在 kernel root/drivers/soc/qcom/peripheral-loader.c
通用的PIL驱动是:kernel root/drivers/soc/qcom/subsys-pil-tz.c
该驱动实现了子系统的power up, shutdown,err handing和RAM dump功能。接口被封装并注册到 SSR 驱动程序。
(SSR subsystem restart子系统重启)
PS: 在kernel/msm-5.4/drivers/remoteproc/qcom_q6v5_mss.c中会调用request_firmware()对modem.bxx进行加载
Device tree configurations Device tree configs for subsystems are at the following locations:/arch/arm64/boot/dts/qcom/ .dtsi
子系统的设备树配置位于: kernel root/arch/arm64/boot/dts/qcom/sdm chipset.dtsi
PS: 在该dtsi文件中可以看到相应的compatible = “qcom,pil-tz-generic”的节点
Support for Modem Self-Authentication (MSA)
PIL loading of Modem Boot Authenticator (MBA)
PIL loading of Primary Modem Image (PMI)
Confidential and Proprietary – Qualcomm Technologies, Inc. | MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATIONPAGE 12 80-NC839-21 A Apr 2013
Reporting Failure Reasons
1 Subsystem should report failure reason to host driver
2 Subsystem software failure reason report should use a preallocated
shared memory location
3 Subsystem failure report should include information about source of
failure
Filename
Line number
Program counter of instruction that generated the exceptio
AP应该支持的功能
1. 关闭子系统 Shutting down the subsystem
AP shall implement recommended subsystem shutdown procedures for the subsystem
AP should support both QXDM and AT power-down command
2. Powering up the subsystem
AP shall implement recommended subsystem power-up procedures for the subsystem
3. Processing the failure reasons
AP host driver on MSM shall record subsystem failure reasons in Kernel log
AP host driver shall erase subsystem failure reason from shared memory before restarting the system
4.
Configuration Options
AP shall provide a runtime configurable option to select between Full Chip Restart or Independent Subsystem Restart handling
AP shall provide a runtime configurable option to enable RAM dump collections for the peripheral subsystem
AP shall provide configuration parameters for the maximum allowed number of restarts within a configurable time window, after which a full chip restart will occur
enable Subsystem Restart (SSR)
3 > restart_level
Phase-3 (Independent Restart)
Trigger Modem restart using the QXDM command: send_data 75 37 03 00 (致命错误) send_data 75 37 03 00 02(软件异常) 75 37 03 00 01( 看门狗复位)
Trigger WCNSS restart using the QXDM command: send_data 75 37 03 32
Trigger ADSP restart using the QXDM command: send_data 75 37 03 48
在qxdm command窗口发送send_data 75 37 03 48 00 (重启音频dsp)
在 Android手机的 属性中 开启/关闭 永久性的 SSR功能(SSR Persistent Flag Enable/Disable )
启用Independent SSR
setprop persist.sys.ssr.restart.level 3
关闭 Independent SSR
setprop persist.sys.ssr.restart_level 1
[persist.vendor.ssr.restart_level]: [ALL_ENABLE]
/system/build.prop
persist.vendor.ssr.enable_ramdumps=1
/vendor/build.prop
# enable all system restart_level to relative
persist.vendor.ssr.restart_level=ALL_ENABLE
SUBSYS_MODEM=”mss”
SUBSYS_MODEM_ESOC0=”esoc0″
/sys/devices/platform/soc/4080000.remoteproc-mss/remoteproc/remoteproc2
cat /sys/class/remoteproc/remoteproc2/name
4080000.remoteproc-mss
persist.vendor.sys.ssr.restart_level=modem,adsp
setprop persist.vendor.ssr.restart_level mss
setprop persist.vendor.ssr.restart_level “ALL_DISABLE”
setprop persist.vendor.ssr.enable_ramdumps 0 setprop persist.vendor.ssr.restart_level ALL_ENABLE
29 02 00 重启整个手机系统
29 01 00 offline
29 04 00 online
/sys/module/subsystem_restart/parameters
write /sys/module/subsystem_restart/parameters/enable_ramdumps 0
on property:persist.vendor.sys.ssr.restart_level=*
start vendor.ssr_setup
service vendor.ssr_setup /vendor/bin/ssr_setup
service vendor.ssr_diag /vendor/bin/ssr_diag
persist.vendor.ssr.restart_level=MODEM
persist.vendor.sys.ssr.restart_level=modem,adsp
persist.vendor.sys.ssr.restart_level=modem,adsp,slpi
persist.sys.ssr.restart_level=venus,AR6320,slpi,modem,adsp
send_data 75 37 03 00 会被转成实际的命令
4B 25 03 00 Debug/Simulate Crash Request
4b 25 03 00 Debug/Simulate Crash Response