2. Snapdragon硬件平台概览
做BSP移植,第一步不是改代码,而是把目标板“看透”。Snapdragon平台把CPU、GPU、DSP、ISP、内存控制器、外设控制器和一堆启动相关模块集成在一颗SoC里,Linux内核看到的只是这些硬件经过地址映射和设备树描述后的一个“软件视图”。本节围绕这个视图展开:先建立SoC整体架构认知,再逐层看清CPU集群、内存映射、外设子系统和启动硬件模块,最后给出一个可落地的“硬件信息核对”方法。
一、SoC整体架构:从“一颗芯片”到“多个子系统”
Snapdragon SoC不是单一处理器,而是一个以互连总线(NoC/总线矩阵)为骨架的多子系统集合。典型的高通移动/嵌入式SoC(如SM8250、SM8550、QCS系列)内部大致包含:
- 应用处理器子系统(APSS):由多个CPU集群组成,运行Linux和用户态程序。
- 低功耗子系统:如Always-On Subsystem、Sensor Low Power Island,负责待机、传感器采集等场景。
- 多媒体子系统:GPU、VPU(视频编解码)、DPU(显示)、ISP(图像信号处理)、DSP(音频/计算)。
- 内存子系统:DDR控制器、系统Cache、MMU/SMMU。
- 外设子系统:USB、PCIe、UFS、Ethernet、I2C、SPI、UART、GPIO、PMIC接口等。
- 启动与安全子系统:Boot ROM、PBL/SBL、XBL、TZ(TrustZone)、RPMh、电源管理控制器。
这些子系统通过内部互连交换数据,对外则通过一组固定的物理地址窗口暴露给CPU。BSP工程师最关心的,正是“哪个模块挂在哪个总线上、寄存器基地址是多少、中断号是多少、时钟和电源由谁控制”。
二、CPU集群:大小核、缓存与调度域
Snapdragon的APSS通常采用big.LITTLE或DynamIQ架构,把CPU分成若干集群。以SM8250为例,它包含一个由Cortex-A77组成的Gold集群(1颗超大核+3颗大核)和一个由Cortex-A55组成的Silver集群(4颗小核)。每个集群内部共享L2 Cache,集群之间通过L3 Cache和DSU(DynamIQ Shared Unit)连接。对BSP而言,需要关注三点:
- CPU节点与enable-method:设备树中每个CPU节点通过
enable-method = "psci"声明由PSCI固件负责上下电,内核不直接操作CPU寄存器。 - opp-table:每个集群有独立的OPP表,描述频率-电压对,如
opp-hz = /bits/ 64 <1804800000>; opp-microvolt = <1000000>;。调频调压由CPUFreq和regulator协同完成。 - idle-states:描述WFI、电源塌陷等低功耗状态,进入条件与退出延迟直接影响待机功耗。
实际核对时,可在目标板执行cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies,与设备树OPP表比对。若频率列表缺失或与硬件不符,通常是OPP表未正确引用或regulator未就绪。
三、内存映射:物理地址空间如何划分
Snapdragon的物理地址空间在SoC设计阶段就已固定,Linux内核通过设备树的reg属性获知各模块的基地址和长度。典型划分如下(以某SM8250类平台为例,具体数值以实际芯片手册为准):
| 地址区间 | 用途 | BSP关注点 |
|---|---|---|
| 0x0000_0000 – 0x0FFF_FFFF | Boot ROM、IMEM、保留区 | 不可被内核随意映射 |
| 0x1000_0000 – 0x1FFF_FFFF | 外设寄存器窗口(部分) | 设备树reg属性来源 |
| 0x8000_0000 – 0xFFFF_FFFF | DDR 主内存 | 内核启动参数mem=、CMA区域 |
| 0x1_0000_0000 以上 | 高地址外设、PCIe ECAM | 64位地址映射,需检查dma-ranges |
内存映射最容易出问题的地方是“保留内存”。例如TZ安全区、ADSP共享内存、显示帧缓冲往往通过reserved-memory节点声明,若遗漏,内核可能把关键区域当普通内存分配,导致启动后随机崩溃。排查方法:启动日志中搜索Reserved memory:,确认每个区域与设备树一致;再用/proc/iomem查看内核最终认定的内存布局。
四、外设子系统:控制器、引脚与中断
外设子系统的BSP工作可以归纳为“三件套”:控制器驱动、引脚配置、中断与时钟。以I2C为例,一个可用的I2C控制器节点至少需要:
i2c@984000 {
compatible = "qcom,geni-i2c";
reg = <0x984000 0x4000>;
interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc_qupv3_wrap0_s0_clk>;
pinctrl-0 = <&qup_i2c0_default>;
pinctrl-1 = <&qup_i2c0_sleep>;
status = "okay";
};
其中reg给出寄存器窗口,interrupts给出GIC中断号,clocks引用GCC时钟,pinctrl引用TLMM引脚配置。四者缺一,控制器就无法正常工作。调试时先看dmesg | grep i2c是否有probe成功,再用i2cdetect -y 0扫描总线,若全部为--,优先检查引脚复用和上拉电阻,而不是怀疑驱动。
五、启动相关硬件模块:从上电到内核
Snapdragon的启动链是硬件与固件交替接力的过程:上电后Boot ROM(PBL)从启动介质读取XBL,XBL初始化DDR、时钟和关键外设,再加载ABL和Linux内核。BSP工程师需要关注:
- 启动介质选择:通过GPIO或eFuse决定从UFS、eMMC还是USB启动,影响
bootargs中的rootfs定位。 - DDR训练参数:由XBL完成,若更换内存颗粒,必须同步更新XBL中的DDR配置,否则内核可能无法启动。
- 内核启动参数:
console=ttyMSM0,115200n8指定串口,root=/dev/mmcblk0p12指定根文件系统,androidboot.*传递启动模式。
/proc/meminfo是否一致;③ CPU频率列表是否完整;④ 关键外设(UFS、USB、以太网)probe是否成功;⑤ 中断统计/proc/interrupts中目标外设中断号是否增长。五项通过,说明硬件平台与BSP基本匹配。
把上述内容串起来看,Snapdragon硬件平台对BSP工程师而言就是一张“地址+中断+时钟+引脚”的对照表。SoC架构决定了子系统边界,CPU集群决定了调度与功耗策略,内存映射决定了资源分配,外设子系统决定了驱动适配方式,启动硬件模块决定了系统能否走到内核。理解这张表,后续的设备树编写、驱动移植和问题定位才有稳定的参照系。