4. 开发环境搭建
玄铁C906/C910属于RISC-V 64位高性能处理器核,其软件开发环境与ARM生态有明显差异。搭建一套可复现、可调试、可仿真的开发环境,是后续裸机程序、RTOS移植和Linux内核适配的前提。本章围绕工具链、交叉编译、QEMU仿真、FPGA选型与OpenOCD调试五个环节展开,形成从代码到硬件的完整闭环。
一、核心原理:为什么需要交叉工具链
C906/C910运行在目标板上,而开发主机通常是x86_64 PC。编译器在主机上运行,生成的是RISC-V指令集的目标代码,这种“在A架构上编译B架构程序”的方式称为交叉编译。玄铁官方推荐使用平头哥T-Head GCC工具链,其前缀为riscv64-unknown-linux-gnu-或riscv64-unknown-elf-,分别面向Linux应用和裸机/RTOS场景。
工具链的核心组件包括:gcc编译器、binutils汇编链接器、gdb调试器、newlib/glibc运行库。C906支持RV64GC指令集,C910在此基础上扩展了向量与AI加速指令,因此编译参数必须与核配置匹配,否则会出现非法指令异常。
二、工具链安装与交叉编译实操
推荐在Ubuntu 20.04/22.04上安装。方式一:使用平头哥官方预编译包;方式二:从源码构建。预编译包安装最快,适合快速验证。
# 下载并解压T-Head工具链
wget https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1695027452343/XuanTie-gcc-10.4.0-linux-x86_64.tar.gz
tar -xzf XuanTie-gcc-10.4.0-linux-x86_64.tar.gz -C /opt/
export PATH=/opt/XuanTie-gcc-10.4.0/bin:$PATH
# 验证
riscv64-unknown-linux-gnu-gcc -v
# 应显示 gcc version 10.4.0 (XuanTie)
# 交叉编译裸机程序
riscv64-unknown-elf-gcc -march=rv64gc -mabi=lp64d \
-mcmodel=medany -nostartfiles -T link.ld \
-o hello.elf hello.c
# 生成反汇编与二进制
riscv64-unknown-elf-objdump -d hello.elf > hello.dis
riscv64-unknown-elf-objcopy -O binary hello.elf hello.bin
-march中加入_xtheadvector等扩展,并确认工具链版本支持。参数不匹配是“非法指令”故障的首要原因。三、QEMU仿真:无板卡快速验证
QEMU可模拟C906/C910的指令行为,适合在拿到FPGA板卡前验证启动流程、中断控制器和串口输出。玄铁提供了定制QEMU,支持CLINT、PLIC、UART等外设模型。
# 启动QEMU仿真C906
qemu-system-riscv64 -M virt -cpu c906 -m 512M \
-nographic -bios default -kernel hello.elf
# 若需调试,加-s -S参数
qemu-system-riscv64 -M virt -cpu c906 -m 512M \
-nographic -kernel hello.elf -s -S
# 另开终端连接GDB
riscv64-unknown-elf-gdb hello.elf \
-ex "target remote :1234" \
-ex "b main" -ex "c"
QEMU的局限在于时序不精确、外设模型简化,不能替代真实硬件验证。建议将QEMU作为“第一道过滤”,通过后再上板。
四、FPGA开发板选型要点
C906/C910可综合到FPGA上运行,选型需关注逻辑资源、DDR带宽、外设接口和调试接口。下表给出常见选型对比。
| 开发板 | FPGA型号 | 逻辑资源 | DDR | 调试接口 | 适用场景 |
|---|---|---|---|---|---|
| Xilinx KC705 | Kintex-7 XC7K325T | 326K LC | DDR3 1GB | JTAG/FTDI | C906单核验证 |
| Xilinx ZCU102 | Zynq UltraScale+ | 600K LC | DDR4 4GB | JTAG/USB | C910多核+Linux |
| Alinx AXU9EG | Zynq UltraScale+ | 600K LC | DDR4 4GB | JTAG/UART | 性价比方案 |
| 平头哥曳影1520 | 专用SoC | — | DDR4 | JTAG/UART | 官方参考板 |
五、OpenOCD调试连接与常见排障
OpenOCD负责将GDB的调试请求转换为JTAG时序,驱动FPGA上的调试模块。典型配置文件需指定适配器、目标芯片和传输速率。
# openocd.cfg 示例
adapter driver ftdi
ftdi_vid_pid 0x0403 0x6010
ftdi_layout_init 0x0008 0x000b
adapter speed 1000
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d
target create $_CHIPNAME.cpu riscv -chain-position $_CHIPNAME.cpu
riscv set_reset_timeout_sec 120
riscv set_command_timeout_sec 120
# 启动
openocd -f openocd.cfg
连接成功后,GDB通过target remote :3333接入,即可进行单步、断点、寄存器查看。常见故障包括:JTAG链ID不匹配、适配器速率过高导致握手失败、FPGA未加载含调试模块的比特流、GDB与OpenOCD版本不兼容。
scan_chain检查JTAG链,最后降低adapter speed至500kHz重试。多数“无法连接”问题源于速率或ID配置错误。完成以上五步后,开发者即拥有“编译—仿真—上板—调试”的完整链路。建议先用QEMU跑通启动代码,再切换到FPGA验证真实时序与外设,最后用OpenOCD定位硬件相关问题,从而显著缩短调试周期。