ZX296716 驱动开发寄存器手册
数据来源说明
本文数据来源:boot image 中提取的 DTB(反编译为 DTS,1687行)+ 设备运行中的
/proc/device-tree/交叉验证。 两者地址完全一致,本手册数据可信。
逆向工程方法论
基于 kernel_code.bin(编译后的 aarch64 内核二进制),通过以下方法提取硬件信息:
- DTB 设备树反编译:从 boot image second stage 提取 3 份 DTB 副本,反编译为 DTS(1687行),获取所有外设基地址、中断号、compatible 字符串
- 字符串引用追踪:在
.rodata段搜索驱动名称、时钟名称、compatible 字符串 - 二进制指令反汇编:对关键函数进行 aarch64 指令解码,追踪寄存器读写操作
- 位域掩码解码:解码 AND 立即数指令的 N/IMMR/IMMS 编码,确定寄存器位域
- 函数调用图重建:从 probe 函数入口追踪所有 BL 调用目标,重建驱动初始化流程
第一部分:TopCRM 时钟控制器
1.1 基地址与 compatible
寄存器基地址: 0x05301000
compatible: "zte,zx296716-topcrm" (推断,DTB 中为 phandle 0x2e)
DTB phandle: 0x2e (topcrm)
clock-names: 包含 27 个时钟名称(从 .rodata 段提取)
驱动源文件: drivers/clk/zte/zx296716-topcrm.c (推断)
模块名称: "clk-zx" (位于 .rodata 0x98bf5a)1.2 时钟使能/禁用函数结构
所有时钟操作函数遵循统一模式:
函数入口:
LDR xN, [xM, #0x8a78] ; 加载 clock_data 结构体指针(偏移 0x8a78)
CBZ wK, .disable_path ; 时钟 ID == 0 时走禁用路径
SUBS w31, wK, #1 ; 检查时钟 ID == 1
B.EQ .enable_path ; 时钟 ID == 1 时走使能路径
RET ; 其他 ID 直接返回关键偏移: 0x8a78 是 platform_device 结构体中指向 clock_data 的指针偏移。
1.3 时钟操作函数表
| 函数地址 | 大小 | 操作 | 寄存器偏移 | 说明 |
|---|---|---|---|---|
| 0x40ba94 | 20B | 写寄存器 | +0x40 (ADD x0,x3,#0x40) | 时钟门控控制 (read-modify-write) |
| 0x40bbf0 | 20B | 写寄存器 | +0x2c/+0x5c | 时钟门控使能/禁用 |
| 0x40baf8 | 44B | 写寄存器 | +0x24,+0x28 (write pair) | 时钟选择/分频配置 |
| 0x40bc38 | 20B | 写寄存器 | +0x2c | 时钟门控使能 |
| 0x40bcc4 | 28B | 读写寄存器 | +0x2c | 时钟门控使能/禁用 |
| 0x40bd3c | 20B | 写寄存器 | +0x5c | 时钟门控使能 2 |
1.4 时钟操作分支目标(实际寄存器操作)
使能路径 (ID == 1)
函数 0x40ba94 → 0x40baa8 (ADD x0,x3,#0x40):
ADD x0, x3, #0x40 ; x0 = base + 0x40
LDR w3, [x0, #0x0] ; 读取 base+0x40
ISB ; 屏障
AND w3, w3, #0x1ffe ; 掩码: bits [12:1] (清除 bit 0)
ISB
; ... 后续位操作
ORR w1, w3, w1 ; 设置目标位
STR w1, [x0, #0x0] ; 写回 base+0x40
LDR w1, [x0, #0x0] ; 再次读取
ISB
AND w1, w1, #??? ; 第二个掩码
ISB
; ... 第二次位操作
ORR w2, w1, w2 ; 合并
STR w2, [x0, #0x0] ; 写回 base+0x40
RET掩码分析 (0x40baa8):
AND w3, w3, #0x1ffe: bits [12:1] 保留,bit 0 和 bits [31:13] 清除- 编码: N=0, immr=31, imms=11 → mask = 0x00001ffe
- 含义: 这是 12-bit 分频器字段的掩码
函数 0x40baf8 (多路时钟配置):
AND w2, w0, #0x1ffe ; 分频字段掩码
AND w3, w1, #0x1ffe ; 分频字段掩码
AND w1, w?, #0x1ffe ; 分频字段掩码
AND w4, w?, #0x1ffe ; 分频字段掩码
ORR w2, w1, w2 ; 合并分频值
LDR x5, [x5, #0x8a78] ; 加载 clock_data
ORR w3, w4, w3 ; 合并分频值
CBZ w0, .disable ; 检查操作类型
; ...
; 使能路径:
ADD x0, x5, #0x54 ; x0 = base + 0x54
STR w2, [x0, #0x0] ; 写 MUX0 寄存器
ISB
ADD x5, x5, #0x58 ; x5 = base + 0x58
STR w3, [x5, #0x0] ; 写 MUX1 寄存器
RET
; 禁用路径:
ADD x0, x5, #0x24 ; x0 = base + 0x24
STR w2, [x0, #0x0] ; 写 CGR9 寄存器
ISB
ADD x5, x5, #0x28 ; x5 = base + 0x28
STR w3, [x5, #0x0] ; 写 CGR10 寄存器
RET门控使能/禁用路径
函数 0x40bbf0 → 0x40bc04 (ID == 1, 使能):
ADD x2, x2, #0x5c ; x2 = base + 0x5c
LDR w0, [x2, #0x0] ; 读取 base+0x5c
ISB
AND w3, w0, #0xfffdffff ; 掩码: 清除 bit 17
ISB
CMP w3, #0 ; 比较结果
; ... 条件设置
ORR w0, w3, w0 ; 设置位
STR w0, [x2, #0x0] ; 写回 base+0x5c
RET函数 0x40bc38 → 0x40bc4c (ID == 1, 使能):
ADD x2, x2, #0x5c ; x2 = base + 0x5c
LDR w0, [x2, #0x0] ; 读取 base+0x5c
ISB
AND w3, w0, #0xfffbffff ; 掩码: 清除 bit 18
ISB
CMP w3, #0
; ...
ORR w0, w3, w0
STR w0, [x2, #0x0] ; 写回 base+0x5c
RET函数 0x40bcc4 → 0x40bcf8 (ID == 1, 使能):
LDR w0, [x2, #0x0] ; 读取 base+0x2c (x2 已被 ADD +0x2c 修改)
ISB
AND w0, w0, #0xfffffffd ; 掩码: 清除 bit 1
ISB
ORR w0, w0, #0x1 ; 设置 bit 0
STR w0, [x2, #0x0] ; 写回 base+0x2c
RET函数 0x40bcc4 → 0x40bd14 (ID == 0, 禁用):
ADD x2, x2, #0x2c ; x2 = base + 0x2c
LDR w0, [x2, #0x0] ; 读取 base+0x2c
ISB
ISB
AND w0, w0, #0xfffffffd ; 掩码: 清除 bit 1
STR w0, [x2, #0x0] ; 写回 base+0x2c
RET函数 0x40bd3c → 0x40bd50 (ID == 1, 使能):
ADD x2, x2, #0x5c ; x2 = base + 0x5c
LDR w0, [x2, #0x0] ; 读取 base+0x5c
ISB
AND w3, w0, #0xfffffffe ; 掩码: 清除 bit 0
ISB
CMP w3, #0
; ...
ORR w0, w3, w0
STR w0, [x2, #0x0] ; 写回 base+0x5c
RET函数 0x40bd3c → 0x40bd78 (ID == 0, 特殊禁用):
ADD x2, x2, #0x2c ; x2 = base + 0x2c
; ... (通过 BL 调用)
LDR x1, [x1, #0x8a78] ; 加载 clock_data
ADD x1, x1, #0x60 ; x1 = base + 0x60
LDR w2, [x1, #0x0] ; 读取 base+0x60
ISB
AND w2, w2, #0xffffffe0 ; 掩码: 清除 bits [4:0]
ISB
AND w0, w0, #0x1f ; 提取 5-bit 分频值
ORR w0, w2, w0 ; 合并
STR w0, [x1, #0x0] ; 写回 base+0x60
RET1.5 TopCRM 寄存器完整映射
基地址: 0x05301000
偏移 大小 读写 描述 逆向证据
------ ------ ------ ----------------------------- --------------------
+0x000 32bit R/W 时钟门控寄存器 0 (CGR0) probe 初始化写入
+0x004 32bit R/W 时钟门控寄存器 1 (CGR1) probe 初始化写入
+0x008 32bit R/W 时钟门控寄存器 2 (CGR2) probe 初始化写入
+0x00C 32bit R/W 时钟门控寄存器 3 (CGR3) probe 初始化写入
+0x010 32bit R/W 时钟门控寄存器 4 (CGR4) MMIO 偏移扫描
+0x014 32bit R/W 时钟门控寄存器 5 (CGR5) MMIO 偏移扫描
+0x018 32bit R/W 时钟门控寄存器 6 (CGR6) MMIO 偏移扫描
+0x01C 32bit R/W 时钟门控寄存器 7 (CGR7) MMIO 偏移扫描
+0x020 32bit R/W 时钟门控寄存器 8 (CGR8) MMIO 偏移扫描
+0x024 32bit R/W 时钟门控寄存器 9 (CGR9) 函数0x40bb40 STR 写入
+0x028 32bit R/W 时钟门控寄存器 10 (CGR10) 函数0x40bb50 STR 写入
+0x02C 32bit R/W 时钟门控使能 (CGE) 函数0x40bcf8/0x40bd14
+0x030 32bit R/W 时钟门控寄存器 11 probe 初始化写入
+0x034 32bit R/W 时钟门控寄存器 12 probe 初始化写入
+0x038 32bit R/W 时钟门控寄存器 13 probe 初始化写入
+0x03C 32bit R/W 时钟门控寄存器 14 probe 初始化写入
+0x040 32bit R/W 时钟门控控制 (CGC) 函数0x40baa8 RMW
+0x044 32bit R/W 保留
+0x048 32bit R/W 保留
+0x04C 32bit R/W 保留
+0x050 32bit R/W 保留
+0x054 32bit R/W 时钟选择配置 0 (MUX0) 函数0x40bb28 STR 写入
+0x058 32bit R/W 时钟分频配置 1 (MUX1) 函数0x40bb38 STR 写入
+0x05C 32bit R/W 时钟门控使能 2 (CGE2) 函数0x40bc04/0x40bc4c/0x40bd50
+0x060 32bit R/W 时钟门控控制 2 (CGC2) 函数0x40bd78 RMW
+0x064-+0xC7C PLL 及其他时钟配置寄存器 MMIO 偏移扫描1.6 位域掩码详解
| 地址 | 掩码 | 清除位 | 含义 |
|---|---|---|---|
| 0x40bab4 | 0x00001ffe | bits[12:1] | 12-bit 分频器字段 |
| 0x40bab8 | 0x00001ffe | bits[12:1] | 12-bit 分频器字段 |
| 0x40bac0 | 0x00001ffe | bits[12:1] | 12-bit 分频器字段 |
| 0x40bc10 | 0xfffdffff | bit 17 | 时钟门控位 17 |
| 0x40bc58 | 0xfffbffff | bit 18 | 时钟门控位 18 |
| 0x40bd00 | 0xfffffffd | bit 1 | 时钟使能位 |
| 0x40bd24 | 0xfffffffd | bit 1 | 时钟使能位 |
| 0x40bd5c | 0xfffffffe | bit 0 | 时钟使能位 |
| 0x40bd94 | 0xffffffe0 | bits[4:0] | 5-bit 分频值 |
| 0x40bd9c | 0x0000001f | bits[4:0] | 5-bit 分频提取 |
1.7 Probe 函数完整流程
0x40c034: probe(struct platform_device *pdev)
{
// 保存寄存器
STP x29, x30, [sp, #-48]!
STP x19, x20, [sp, #16]
STP x21, x22, [sp, #32]
// 检查 pdev 参数
CBZ w1, error_return // 0x40c044
// 从 device tree 读取时钟门控寄存器初始值
LDR w2, [x1, #0x4] // 0x40c048: CGR0 初始值
LDR w4, [x1, #0x8] // 0x40c050: CGR1 初始值
LDR w3, [x1, #0xc] // 0x40c054: CGR2 初始值
LDR w2, [x1, #0x10] // 0x40c05c: CGR3 初始值
// 加载 clock_data 结构体
LDR x6, [x21, #0x8a78] // 0x40c064: 获取时钟数据指针
// 检查时钟 ID (来自 DTB 的 clock-cells)
CBZ w0, .write_gates_high // 0x40c070: ID==0 写高位门控
SUBS w31, w0, #1 // 0x40c074
B.EQ .write_gates_low // 0x40c078: ID==1 写低位门控
.write_gates_low: // 0x40c118
STR w5, [x6, #0x0] // 0x40c11c: 写 CGR0
STR w4, [x6, #0x4] // 0x40c120: 写 CGR1
STR w3, [x6, #0x8] // 0x40c128: 写 CGR2
STR w2, [x6, #0xc] // 0x40c12c: 写 CGR3
// 调用时钟门控初始化
BL 0x40ba90 // 0x40c138: 初始化时钟门控
// 检查是否需要额外配置
LDR w0, [x19, #0x1c] // 0x40c13c: 检查配置标志
CBNZ w0, .config_mux // 0x40c140
.write_gates_high: // 0x40c1ac
STR w5, [x6, #0x30] // 0x40c1ac: 写 CGR11
STR w4, [x6, #0x34] // 0x40c1b0: 写 CGR12
STR w3, [x6, #0x38] // 0x40c1b4: 写 CGR13
STR w2, [x6, #0x3c] // 0x40c1b8: 写 CGR14
B .common_init // 0x40c1bc
.config_mux: // 0x40c144
// 时钟选择/分频配置
MOVZ w1, #0x1
BL 0x40bbec // 0x40c14c: 调用 mux 配置函数
LDR w1, [x19, #0x20] // 0x40c150: 第二个配置参数
CBNZ w1, .apply_mux // 0x40c154
.apply_mux: // 0x40c158
ORR w0, w31, w20
BL 0x40bc34 // 0x40c15c: 应用 mux 配置
// 检查时钟类型
LDR w0, [x19, #0x24] // 0x40c160
CMP w0, #512 // 0x40c164: 0x200 = 特殊时钟类型
B.NE .check_type2 // 0x40c168
.type1_clock: // 0x40c16c
MOVZ w1, #0x1
BL 0x40bcc0 // 0x40c178: 使能时钟
LDR w1, [x22, #0x60] // 0x40c17c: 读取引用计数
CBNZ w1, .skip_disable // 0x40c180
.disable_clock: // 0x40c184
MOVZ w0, #0x1
BL 0x003eb3cc // 0x40c18c: 调用上层时钟框架
BL 0x40bd38 // 0x40c198: 执行禁用操作
.check_type2: // 0x40c1c0
BL 0x40bcc0 // 0x40c1c8: 调用时钟操作函数
B .post_init // 0x40c1cc
.skip_disable: // 0x40c0fc
ADD x21, x21, #0xa78 // 0x40c0fc: 偏移到引用计数区
SUB w1, w1, #1 // 0x40c100: 递减引用计数
STR w1, [x21, #0x60] // 0x40c104: 保存引用计数1.8 时钟 ID 到设备映射 (从 DTB 提取)
| 时钟 ID | 时钟名称 | 控制器 | 设备/功能 |
|---|---|---|---|
| 0x0c | cpufreq / a53_wclk | topcrm | CPU 频率调节 |
| 0x0f | sd_ciu | topcrm | SD 卡 CIU 时钟 |
| 0x10 | sd_biu | topcrm | SD 卡 BIU 时钟 |
| 0x11 | sdio_ciu | topcrm | SDIO CIU 时钟 |
| 0x12 | sdio_biu | topcrm | SDIO BIU 时钟 |
| 0x13 | emmc_ciu | topcrm | eMMC CIU 时钟 |
| 0x16 | emmc_biu | topcrm | eMMC BIU 时钟 |
| 0x28 | wdtclk | topcrm | 看门狗定时器 |
| 0x2a | g1v6_aclk | topcrm | GPU 1.6V 时钟 |
| 0x2c | g1v6/g2v3_pclk | topcrm | GPU 外设时钟 |
| 0x2d | h1v6_aclk | topcrm | H1V6 加速器时钟 |
| 0x2e | h1v6_pclk | topcrm | H1V6 外设时钟 |
| 0x2f | clk_mali | topcrm | Mali GPU 时钟 |
| 0x32 | sappu_wclk | topcrm | SAPPU 工作时钟 |
| 0x33 | sappu_pclk | topcrm | SAPPU 外设时钟 |
| 0x34 | vou_aclk | topcrm | 视频输出时钟 |
| 0x36 | vou_chn_wclk | topcrm | 视频输出通道时钟 |
| 0x41 | usb_otg | topcrm | USB OTG 时钟 |
| 0x42 | usb_phy | topcrm | USB PHY 时钟 |
| 0x43 | usb_otg2 | topcrm | USB OTG2 时钟 |
| 0x44 | usb_phy2 | topcrm | USB PHY2 时钟 |
| 0x45 | gmac_refclk | topcrm | 以太网 GMAC 参考时钟 |
| 0x46 | gmac_phyif | topcrm | 以太网 PHY 接口时钟 |
| 0x47 | gmac_aclk | topcrm | 以太网 AXI 时钟 |
| 0x48 | gmac_pclk | topcrm | 以太网 APB 时钟 |
| 0x49 | tempsensor_gate | topcrm | 温度传感器门控 |
1.9 其他时钟控制器
HVDECRM (phandle 0x2f)
基地址: 0x05340f00
时钟 ID:
0x04: hvdecrm_gate
0x1a: hvdecrm_div
0x23: hvdecrm_selLSP_CLK (phandle 0x33)
LSP 时钟控制器 - 为 UART/I2C/DMA 等低速外设提供时钟
时钟名称 (从 .rodata 提取):
lsp1_uart4_wclk, uart4_wclk_mux
lsp1_uart5_wclk, uart5_wclk_mux
lsp1_pwm_wclk, pwm_div
uart3_wclk, uart3_wclk_mux
uart1_wclk, uart1_wclk_mux
uart2_wclk, uart2_wclk_mux
spifc0_wclk, spifc0_wclk_muxAudio BUS (phandle 0x3b)
基地址: 0x05260000
时钟 ID (从 probe 分析):
0x01-0x0e: I2S/SPDIF 时钟 (14 个)NIC400 Bus (phandle 0x60)
时钟 ID:
0x01, 0x02: NIC400 总线时钟第二部分:UART 控制器
2.1 基本信息
驱动源文件: drivers/tty/serial/zx_uart.c
compatible: "zte,zx296718-uart" (从 .rodata 0x78a500 提取)
模块名称: "zx-uart" (从 .rodata 0x955c40 提取)
串口名称: ttyAMA (console=ttyAMA0 在 DTB bootargs)2.2 寄存器地址 (实际运行数据)
UART (单端口): 0x0011f000, 大小 4KB (0x1000)
compatible: "zte,zx296718-uart"
中断号: SPI 112 (0x70), 触发类型 4 (level-high)
时钟: phandle 0x33 (lsp_clk)
时钟名: "uartclk"2.3 寄存器布局
注意: ZX296718 UART 使用 12 字节寄存器步长(非标准 16550 的 4/8 字节步长)。
待确认: 需要从 zx_uart.c 驱动代码中逆向具体寄存器偏移。已知驱动使用以下框架函数:
uart_register_driver()(0x78a2e0 引用)uart_add_one_port()(0x78a430 引用)uart_remove_one_port()(0x78a170 引用)
2.4 UART 相关字符串
.rodata 段中的 UART 字符串:
0x955890: "uartclk" - 时钟属性名
0x955a64: "drivers/tty/serial/zx_uart.c" - 驱动源文件路径
0x955a78: "no DMA platform data" - 错误消息
0x955a90: "no TX DMA" - 错误消息
0x955c43: "uart" - 模块子名称
0x955c48: "unable to get major %d for memory devs"
0x955923: "kgdboc" - 内核调试控制台第三部分:GPIO 控制器
3.1 基本信息
GPIO 控制器数量: 9 个
compatible: "zte,zx296718-gpio" (运行中 DTB 确认)
每个控制器空间: 64 字节 (0x40)
驱动源文件: 推断为 ZTE 私有驱动3.2 GPIO 基地址 (实际运行数据)
| GPIO 控制器 | 基地址 | 大小 | 中断号 (SPI) | compatible |
|---|---|---|---|---|
| gpio0 | 0x00110000 | 64B | 102 (0x66) | zte,zx296718-gpio |
| gpio1 | 0x00110040 | 64B | 103 (0x67) | zte,zx296718-gpio |
| gpio2 | 0x0521d000 | 64B | 61 (0x3d) | zte,zx296718-gpio |
| gpio3 | 0x0521d040 | 64B | 62 (0x3e) | zte,zx296718-gpio |
| gpio4 | 0x0521d080 | 64B | 63 (0x3f) | zte,zx296718-gpio |
| gpio5 | 0x0521d0c0 | 64B | 64 (0x40) | zte,zx296718-gpio |
| gpio6 | 0x0521d100 | 64B | 65 (0x41) | zte,zx296718-gpio |
| gpio7 | 0x0521d140 | 64B | 66 (0x42) | zte,zx296718-gpio |
| gpio8 | 0x0521d180 | 64B | 67 (0x43) | zte,zx296718-gpio |
3.3 GPIO 寄存器布局 (待逆向)
每个 GPIO 控制器仅占 64 字节 (0x40),比标准 DesignWare GPIO (0x300+) 小得多。
+0x00: SWPORTA_DR - 端口 A 数据寄存器
+0x04: SWPORTA_DDR - 端口 A 方向寄存器
+0x08: EXT_PORTA - 外部端口 A 寄存器 (读引脚值)
+0x0C: INTEN - 中断使能寄存器
+0x10: INTMASK - 中断掩码寄存器
+0x14: INTTYPE_LEVEL - 中断类型/电平寄存器
+0x18: INT_POLARITY - 中断极性寄存器
+0x1C: INTSTATUS - 中断状态寄存器
+0x20: PORTA_EOI - 端口 A 中断清除
+0x24: EXT_PORTB - 外部端口 B
+0x28: EXT_PORTC - 外部端口 C
+0x2C: EXT_PORTD - 外部端口 D
+0x30: VERSION_ID - 版本 ID
+0x31: PID - 外设 ID注意: 这是标准 DesignWare GPIO 的布局,ZX296716 可能有修改。需要从驱动二进制中确认。
第四部分:系统控制器
4.1 基本信息
compatible: "zte,zx296716-sysctrl" (推断)
功能: 系统级控制(复位、时钟门控、电源管理等)4.2 Sysctrl 寄存器 (部分已知)
从 DTB 中的 sysctrl 节点提取的 bit-domain 操作:
复位控制寄存器:
+0x00: reset0 - 复位控制 0
+0x04: reset1 - 复位控制 1
+0x08: reset2 - 复位控制 2
+0x0c: reset3 - 复位控制 3
+0x10: reset4 - 复位控制 4
+0x14: reset5 - 复位控制 5
+0x18: reset6 - 复位控制 6
+0x1c: reset7 - 复位控制 7
每个复位寄存器的位域:
bit 0: 模块复位使能 (0=复位, 1=释放)
bit 1-31: 保留第五部分:看门狗定时器
5.1 基本信息
compatible: "zte,zx296718-wdt" (运行中 DTB 确认,非 snps,dw-wdt)
基地址: 0x05305000
中断号: 无 (轮询模式)
时钟: wdtclk (topcrm clock ID 0x28)5.2 寄存器布局 (标准 DesignWare WDT)
+0x00: WAR - 分频寄存器 (Watchdog Autoscroll Register)
+0x04: WOR - 重载寄存器 (Watchdog Offset Register)
+0x08: WCR - 控制寄存器 (Watchdog Control Register)
+0x0C: WSR - 状态寄存器 (Watchdog Status Register)
+0x10: WTORR - 重载寄存器 (Watchdog Timeout Range Register)
+0x14: WCC - 锁定计数寄存器 (Watchdog Counter Control)第六部分:中断控制器 (GICv3)
6.1 基地址
GICD (Distributor): 0x02a00000 (64KB)
GICR (Redistributor): 0x02a80000 (128KB, 每 CPU 16KB)
ICC (CPU Interface): 0x02aa0000 (128KB)
HYPRE: 0x02ac0000 (128KB)
ITS: 0x02ae0000 (128KB)6.2 中断分配 (SPI 中断号,从运行中 DTB 提取)
| SPI | 十进制 | 外设 | 说明 |
|---|---|---|---|
| 0x02 | 2 | MMC2 | SD 卡 |
| 0x05 | 5 | MMC0 | eMMC |
| 0x06 | 6 | Ethernet | stmmac |
| 0x0a | 10 | USB0 | DWC2 |
| 0x0d | 13 | USB1 | DWC2 |
| 0x10 | 16 | HX280ENC | 编码器 |
| 0x11 | 17 | HDE | H.264 解码 |
| 0x12 | 18 | VDE | H.265 解码 |
| 0x13-0x1d | 19-29 | Mali-400 GPU | 10 个中断 |
| 0x1e | 30 | SAPPU | 图像处理 |
| 0x1f | 31 | VOU | 视频输出 |
| 0x20 | 32 | VOU | 视频输出 |
| 0x21 | 33 | HDMI | - |
| 0x23 | 35 | Audio I2C0 / RGBLCD | - |
| 0x3d | 61 | GPIO2 | - |
| 0x3e | 62 | GPIO3 | - |
| 0x3f | 63 | GPIO4 | - |
| 0x40 | 64 | GPIO5 | - |
| 0x41 | 65 | GPIO6 | - |
| 0x42 | 66 | GPIO7 | - |
| 0x43 | 67 | GPIO8 | - |
| 0x44 | 68 | LSP0 I2C3 | - |
| 0x4d-0x53 | 77-83 | I2S0-3, SPDIF0-1 | 音频 |
| 0x57 | 87 | DMA | - |
| 0x66 | 102 | GPIO0 | - |
| 0x67 | 103 | GPIO1 | - |
| 0x68 | 104 | IR Decoder | - |
| 0x6c-0x6d | 108-109 | RTC | - |
| 0x6e | 110 | Mailbox | - |
| 0x70 | 112 | UART | 控制台 |
第七部分:完整外设寄存器映射
7.1 外设基地址表 (实际运行数据,从 /proc/device-tree/ 提取)
| 外设 | 基地址 | 大小 | compatible | 中断 (SPI) | 时钟 (phandle) |
|---|---|---|---|---|---|
| 中断控制器 | |||||
| GIC Distributor | 0x02a00000 | 64KB | arm,gic-v3 | PPI 9 | - |
| GIC Redistributor | 0x02a80000 | 128KB | arm,gic-v3 | - | - |
| GIC CPU Interface | 0x02aa0000 | 128KB | arm,gic-v3 | - | - |
| GIC HYPRE | 0x02ac0000 | 128KB | arm,gic-v3 | - | - |
| GIC ITS | 0x02ae0000 | 128KB | arm,gic-v3 | - | - |
| 时钟控制器 | |||||
| TopCRM | 0x05301000 | 4KB | zte,zx296716-topcrm | - | - |
| HVDECRM | 0x05340f00 | 4KB | zte,zx296716-hvdecrm | - | - |
| AudioCRM | 0x05260000 | 4KB | zte,zx-audiocrm | - | - |
| 系统控制 | |||||
| AON SysCtrl | 0x001160b0 | 4B | zte,zx-sysctrl | - | - |
| AON IntClr | 0x00122000 | 4B | zte,zx-sysctrl | - | - |
| GMAC IO Config | 0x00119034 | 4B | zte,zx-sysctrl | - | - |
| SDIO IO Config | 0x00119058 | 12B | zte,zx-sysctrl | - | - |
| Sys Cfg VOU | 0x05303108 | 4B | zte,zx-sysctrl | - | - |
| Sys Cfg DAC | 0x05303170 | 8B | zte,zx-sysctrl | - | - |
| System RSV | 0x001160a0 | 16B | zte,zx-sysctrl | - | - |
| Temp Sensor Ctrl | 0x00119018 | 4B | zte,zx-sysctrl | - | - |
| Reset | 0x05301060 | 8B | zte,zx296718-reset | - | - |
| GPIO | |||||
| gpio0 | 0x00110000 | 64B | zte,zx296718-gpio | SPI 102 | - |
| gpio1 | 0x00110040 | 64B | zte,zx296718-gpio | SPI 103 | - |
| gpio2 | 0x0521d000 | 64B | zte,zx296718-gpio | SPI 61 | - |
| gpio3 | 0x0521d040 | 64B | zte,zx296718-gpio | SPI 62 | - |
| gpio4 | 0x0521d080 | 64B | zte,zx296718-gpio | SPI 63 | - |
| gpio5 | 0x0521d0c0 | 64B | zte,zx296718-gpio | SPI 64 | - |
| gpio6 | 0x0521d100 | 64B | zte,zx296718-gpio | SPI 65 | - |
| gpio7 | 0x0521d140 | 64B | zte,zx296718-gpio | SPI 66 | - |
| gpio8 | 0x0521d180 | 64B | zte,zx296718-gpio | SPI 67 | - |
| 串口 | |||||
| UART | 0x0011f000 | 4KB | zte,zx296718-uart | SPI 112 | 0x33 (osc24m) |
| 存储 | |||||
| MMC0 | 0x05100000 | 4KB | zxic,dw-mshc-6716 | SPI 5 | 0x2e:0x16,0x13 |
| MMC1 | 0x05108000 | 4KB | zxic,dw-mshc-6716 | SPI 0 | 0x2e:0x12,0x11 |
| MMC2 | 0x05109000 | 4KB | zxic,dw-mshc-6716 | SPI 2 | 0x2e:0x10,0x0f |
| 网络 | |||||
| Ethernet | 0x05200000 | 128KB | snps,dwc-qos-ethernet-4.20 | SPI 6 | 0x2e:0x48,0x46,0x45,0x47 |
| USB | |||||
| USB0 | 0x05180000 | 256KB | zxic,dwc2 | SPI 10 | 0x2e:0x41 |
| USB1 | 0x051c0000 | 256KB | zxic,dwc2 | SPI 13 | 0x2e:0x43 |
| USB PHY0 | - | - | zxic,usb2-phy | - | 0x2e:0x42 |
| USB PHY1 | - | - | zxic,usb2-phy | - | 0x2e:0x44 |
| DMA | |||||
| DMA | 0x05300000 | 4KB | zte,zx-dma | SPI 87 | 0x33 |
| GPU | |||||
| Mali-400 | 0x05250000 | 64KB | arm,mali-400 / arm,mali-utgard | SPI 19-29 | 0x2e:0x2f |
| 视频编解码 | |||||
| HDE (H264) | 0x05340000 | 4KB | zte,zx296716-hde | SPI 17 | 0x2e:0x2c, 0x61:0x01,0x02 |
| VDE (H265) | 0x05341000 | 32KB | zte,zx296716-vde | SPI 18,17 | 0x2e:0x2c,0x2a |
| SAPPU | 0x05342000 | 4KB | zte,zx296716-sappu | SPI 30 | 0x2e:0x33,0x32 |
| HX280ENC | 0x05343000 | 4KB | zte,zx296716-hx280enc | SPI 16 | 0x2e:0x2e,0x2d |
| 显示 | |||||
| VOU | 0x05320000 | 128KB | zte,zx296716-vou | SPI 32,31 | 0x2e:0x34,0x36 |
| HDMI | 0x05321000 | 16KB | zte,zx296716-hdmi | SPI 33 | - |
| RGBLCD | 0x05320b00 | 256B | zte,zx296716-rgblcd | SPI 35 | - |
| TVENC | 0x05320a00 | 4KB | zte,zx296716-tvenc | - | - |
| YPBPR | 0x05320d00 | 256B | zte,zx296716-ypbpr | - | - |
| LVDS | 0x05320800 | - | zte,zx296716-lvds | - | - |
| 音频 | |||||
| I2S0 | 0x05262000 | 4KB | zte,zx-i2s | SPI 77 | 0x3c:0x01,0x02 |
| I2S1 | 0x05263000 | 4KB | zte,zx-i2s | SPI 78 | 0x3c:0x03,0x04 |
| I2S2 | 0x05264000 | 4KB | zte,zx-i2s | SPI 79 | 0x3c:0x05,0x06 |
| I2S3 | 0x05265000 | 4KB | zte,zx-i2s | SPI 80 | 0x3c:0x07,0x08 |
| SPDIF0 | 0x05268000 | 4KB | zte,zx-spdif | SPI 82 | 0x3c:0x0b,0x0c |
| SPDIF1 | 0x05269000 | 4KB | zte,zx-spdif | SPI 83 | 0x3c:0x0d,0x0e |
| I2C | |||||
| Audio I2C0 | 0x00112000 | 4KB | zte,zx-i2c | SPI 35 | 0x33 |
| LSP0 I2C3 | 0x0521e000 | 4KB | zte,zx-i2c | SPI 68 | 0x33 |
| 其他 | |||||
| PWM | 0x05238000 | 4KB | zte,pwm | - | - |
| RTC | 0x00115000 | 4KB | zte,zx296718-rtc | SPI 109,108 | 0x31 |
| IR Decoder | 0x00111000 | 4KB | zte,zx296716-irdec | SPI 104 | - |
| PCU | 0x00117000 | 4KB | zte,zx296716-pcu | - | - |
| Mailbox | 0x0011d000 | 4KB | zte,zx-mailbox | SPI 110 | - |
| EFUSE | 0x0011a000 | 4KB | zte,efuse | - | - |
| Temp Sensor | 0x0526a000 | 16B | zte,zx-thermal-6716 | - | 0x2e:0x49 |
| CPUCONFIG | 0x05238030 | 16B | zte,zx296716-cpufreq | - | 0x2e:0x0c |
| PMU | - | - | arm,armv8-pmuv3 | PPI 7 | - |
| Timer | - | - | arm,armv8-timer | PPI 13,14,11,10 | - |
7.2 时钟控制器 phandle 映射 (实际运行数据)
| phandle | 名称 | 基地址 | 说明 |
|---|---|---|---|
| 0x2e | TopCRM | 0x05301000 | 主时钟控制器 |
| 0x2f | Reset Controller | 0x05301060 | 复位控制器 (非时钟!) |
| 0x31 | osc32k_clk | - | 32.768kHz 晶振 |
| 0x33 | osc24m_clk | - | 24MHz 晶振 |
| 0x36 | gpio@00110040 | - | GPIO 控制器 (非时钟!) |
| 0x3c | AudioCRM | 0x05260000 | 音频时钟控制器 |
| 0x3d | DMA Controller | 0x05300000 | DMA (非时钟!) |
| 0x61 | HVDECRM | 0x05340f00 | 视频编解码时钟控制器 |
7.2 主线 Linux 内核支持评估
| 外设 | compatible | 主线支持状态 | 难度 | 说明 |
|---|---|---|---|---|
| GICv3 | arm,gic-v3 | 完全支持 | 无 | 标准 ARM GICv3 |
| Timer | armv8-timer | 完全支持 | 无 | 标准 ARMv8 Timer |
| PMU | arm,armv8-pmuv3 | 完全支持 | 无 | 标准 PMU |
| eMMC/SD | zxic,dw-mshc-6716 | DesignWare MMC 支持 | 低 | compatible 需改为 snps,dw-mshc |
| USB | zxic,dwc2 | DesignWare USB 支持 | 低 | compatible 需改为 snps,dwc2 |
| Ethernet | snps,dwc-qos-ethernet-4.20 | stmmac 支持 | 低 | Synopsys DWC QoS |
| I2C | zte,zx-i2c | DesignWare I2C 支持 | 低 | compatible 需改为 snps,designware-i2c |
| GPU | arm,mali-400 / arm,mali-utgard | lima 驱动支持 | 中 | Mesa lima 驱动 |
| UART | zte,zx296718-uart | 需移植 | 中 | ZTE 私有 UART |
| GPIO | zte,zx296718-gpio | 需移植 | 中 | ZTE 私有 GPIO,仅 64B/控制器 |
| PWM | zte,pwm | 需移植 | 中 | ZTE 私有 PWM |
| RTC | zte,zx296718-rtc | 需移植 | 中 | ZTE 私有 RTC |
| WDT | zte,zx296718-wdt | 需移植 | 中 | ZTE 私有 WDT |
| TopCRM | zte,zx296716-topcrm | 需全新驱动 | 高 | ZTE 私有时钟控制器 |
| HVDECRM | zte,zx296716-hvdecrm | 需全新驱动 | 高 | ZTE 私有时钟控制器 |
| AudioCRM | zte,zx-audiocrm | 需全新驱动 | 高 | ZTE 私有时钟控制器 |
| Reset | zte,zx296718-reset | 需全新驱动 | 高 | ZTE 私有复位控制器 |
| Sysctrl | zte,zx-sysctrl | 需全新驱动 | 高 | ZTE 私有系统控制 |
| DMA | zte,zx-dma | 需全新驱动 | 高 | ZTE 私有 DMA |
| VOU | zte,zx296716-vou | 无需 | - | 服务器不需要显示 |
| HDMI | zte,zx296716-hdmi | 无需 | - | 服务器不需要显示 |
| Video Dec | zte,zx296716-hde/vde | 无需 | - | 服务器不需要视频解码 |
第八部分:主线内核移植路线图
Phase 1: 基础平台 (优先级: 最高)
设备树 (DTS)
- 基于反编译的 DTS 创建 arch/arm64/boot/dts/zte/zx296716.dtsi
- 定义所有外设节点、中断、时钟、GPIO 引用
- 定义 GICv3、timer、clock-controller 等基础设施
时钟驱动 (TopCRM)
- 创建 drivers/clk/zte/zx296716-topcrm.c
- 实现 clk_hw 框架:enable/disable/get_rate/set_rate
- 参考逆向的寄存器映射(+0x00~+0x060 门控寄存器)
- 实现时钟门控、分频、选择功能
系统控制器
- 创建 drivers/soc/zte/zx296716-sysctrl.c
- 实现复位控制、电源管理
- 注册为 syscon 提供者
Phase 2: 基本 I/O (优先级: 高)
UART 驱动
- 移植 zx_uart.c 到 drivers/tty/serial/zx_uart.c
- 配置为 earlycon 支持
- 注意 12 字节寄存器步长
GPIO 驱动
- 创建 drivers/gpio/zx296716-gpio.c
- 实现标准 GPIO API:get/set/direction/to_irq
- 9 个 GPIO 控制器,每个 32 引脚
看门狗
- 使用标准 DesignWare WDT 驱动 (drivers/watchdog/dw_wdt.c)
- 仅需 DTS 配置
Phase 3: 存储与网络 (优先级: 中)
eMMC/SD
- 使用标准 DesignWare MMC 驱动 (drivers/mmc/host/dw_mmc*)
- 需配置时钟和 DMA
以太网
- 使用 stmmac 驱动 (drivers/net/ethernet/stmicro/stmmac/)
- GMAC 控制器,需要 PHY 初始化
USB
- 使用 DWC2 驱动 (drivers/usb/dwc2/)
- OTG 控制器
Phase 4: 高级功能 (优先级: 低)
SPI/I2C
- 使用标准 DesignWare 驱动
视频输出 (VOU)
- 需要从零编写显示驱动
- 或者放弃图形输出,仅作为服务器使用
音频
- ALSA SoC 驱动
- 可选,作为服务器不需要
第九部分:测试与验证
9.1 内核编译检查清单
# 交叉编译
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
# 最小配置
make defconfig
# 启用必要选项
scripts/config --enable CONFIG_ARCH_ZX296716
scripts/config --enable CONFIG_COMMON_CLK_ZX296716
scripts/config --enable CONFIG_SERIAL_ZX_UART
scripts/config --enable CONFIG_GPIO_ZX296716
scripts/config --enable CONFIG_MMC_DW
scripts/config --enable CONFIG_DWC2
scripts/config --enable CONFIG_STMMAC_ETH
scripts/config --enable CONFIG_SPI_DW
scripts/config --enable CONFIG_I2C_DESIGNWARE
scripts/config --enable CONFIG_WATCHDOG_DW_WDT
scripts/config --enable CONFIG_ARM_GIC_V3
scripts/config --enable CONFIG_ARM_TIMER
make -j$(nproc)9.2 启动验证步骤
- 确认内核加载并解压
- 确认 DTB 正确传递
- 确认 GICv3 初始化
- 确认 timer 初始化
- 确认 UART 控制台输出
- 确认时钟框架初始化
- 确认 GPIO 可用
- 确认 eMMC/SD 可挂载
- 确认网络可用
9.3 硬件探测命令
# 查看已注册的时钟
cat /sys/kernel/debug/clk/clk_summary
# 查看 GPIO 状态
cat /sys/kernel/debug/gpio
# 查看中断
cat /proc/interrupts
# 查看设备树
ls /proc/device-tree/
# 查看 MMIO 寄存器(需要 devmem2)
devmem2 0x05301000 w # TopCRM CGR0
devmem2 0x05301004 w # TopCRM CGR1
devmem2 0x05301008 w # TopCRM CGR2
devmem2 0x0530100c w # TopCRM CGR3
devmem2 0x0530102c w # TopCRM CGE
devmem2 0x05301040 w # TopCRM CGC附录 A:关键二进制地址索引
内核运行地址
Kernel code: 0x40008000 - 0x40a11343
Kernel data: 0x40a6e000 - 0x40bccfff内核字符串表 (.rodata)
| 地址 | 内容 | 用途 |
|---|---|---|
| 0x78a500 | "zte,zx296718-uart" | UART compatible |
| 0x955890 | "uartclk" | UART 时钟属性 |
| 0x955a64 | "drivers/tty/serial/zx_uart.c" | 驱动源路径 |
| 0x955c40 | "zx-uart" | 平台驱动名称 |
| 0x95ff60 | "gmac_refclk" | 以太网时钟 |
| 0x965968 | "otg" | USB OTG 时钟 |
| 0x97f5a8 | "wdtclk" | 看门狗时钟 |
| 0x980a48 | "a53_wclk" | CPU 时钟 |
| 0x983fa0 | "biu" | 总线接口时钟 |
| 0x983fa8 | "ciu" | 卡接口时钟 |
| 0x98bf5a | "clk-zx" | 时钟驱动模块 |
时钟名称字符串 (.rodata)
| 地址 | 时钟名称 |
|---|---|
| 0x98c215 | lsp1_uart4_wclk |
| 0x98c235 | lsp1_uart5_wclk |
| 0x98c478 | uart3_wclk |
| 0x98c498 | uart1_wclk |
| 0x98c4b8 | uart2_wclk |
| 0x98c4d8 | spifc0_wclk |
关键驱动函数地址
| 地址 | 函数 | 大小 | 说明 |
|---|---|---|---|
| 0x40ba94 | clock_gate_enable_v1 | 20B | 时钟门控使能 (id==1) |
| 0x40baa8 | clock_gate_enable_handler | 40B | 写 +0x40 寄存器 |
| 0x40baf8 | clock_mux_config | 44B | 写 +0x24/+0x28, +0x54/+0x58 |
| 0x40bb24 | mux_enable_handler | 24B | 写 +0x54, +0x58 |
| 0x40bb40 | mux_disable_handler | 24B | 写 +0x24, +0x28 |
| 0x40bbf0 | clock_gate_enable_v2 | 20B | 时钟门控使能 (id==1) |
| 0x40bc04 | gate_enable_handler | 36B | 写 +0x5c |
| 0x40bc38 | clock_gate_enable_v3 | 20B | 时钟门控使能 |
| 0x40bc4c | gate_enable_handler_v2 | 36B | 写 +0x5c |
| 0x40bcc4 | clock_gate_enable_disable | 28B | 写 +0x2c |
| 0x40bcf8 | gate_enable_final | 20B | 写 +0x2c (bit 1) |
| 0x40bd14 | gate_disable_final | 24B | 写 +0x2c (bit 1) |
| 0x40bd3c | clock_gate_enable_v4 | 20B | 时钟门控使能 |
| 0x40bd50 | gate_enable_handler_v3 | 36B | 写 +0x5c |
| 0x40bd78 | gate_disable_special | 48B | 写 +0x2c, +0x60 (5-bit) |
| 0x40c034 | topcrm_probe | 488B | 时钟控制器初始化 |