在 Zephyr 上移植 LiteX VexRiscv 软核 SoC:从 FPGA 比特流生成到 Zephyr 串口启动的完整实践
【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr
LiteX VexRiscv 是 Zephyr 官方支持的一块面向 FPGA 的软核 SoC 板卡配置,它把开源 RISC-V 处理器 VexRiscv 与 LiteX SoC 构建框架生成的外设组合成完整系统,可运行在 Digilent Arty A7 与 SDI-MIPI Video Converter 等 FPGA 开发板上。本文以 LiteX VexRiscv 板卡文档 为核心脉络,结合仓库中的设备树、Kconfig 与构建脚本,完整讲解比特流生成、Zephyr 应用构建、烧写与串口启动的端到端流程,读者可以据此在真实 FPGA 硬件上把 Zephyr 跑起来。
LiteX VexRiscv 板卡概览
litex_vexriscv是一个"片上系统(SoC)示例":它由 32 位 RISC-V 软核处理器VexRiscv加上 LiteX 提供的各类外设 IP 组成。这套组合的独特之处在于,整个 SoC 不是固定的硅片,而是可以用工具现场生成的门级网表——这正是它被归类为 FPGA 平台的原因。
从 board.yml 可以看到板卡的基本身份信息:
board: name: litex_vexriscv full_name: LiteX VexRiscv vendor: enjoydigital socs: - name: litex_vexriscv配套的 litex_vexriscv.yaml 则声明了架构类型与默认资源配置:
identifier: litex_vexriscv name: LiteX SoC with VexRiscV softcore CPU type: mcu arch: riscv toolchain: - zephyr ram: 262144 vendor: litex其中ram: 262144(256 KB)对应设备树中 0x40000000 起始的主 RAM 区域大小;toolchain: zephyr表示直接使用 Zephyr SDK 自带的 RISC-V 工具链,无需额外安装厂商编译器。
技术底座:LiteX 与 VexRiscv
- LiteX是一个基于 Migen/MiSoC 的开源 SoC 构建框架。它提供现成的总线、流、互连、通用核与 CPU 封装组件,可以快速拼装 SoC,并内置集成、仿真与构建机制,支持不同厂商的多款 FPGA 芯片。Zephyr 侧与 LiteX 外设对应的设备树绑定(binding)也可以在仓库中直接找到,例如 dts/bindings/serial/litex,uart.yaml、dts/bindings/timer/litex,timer0.yaml 等。
- VexRiscv是用 SpinalHDL 编写的一款 32 位 RISC-V CPU 实现,支持 M、C、A 指令集扩展,内置多级流水线与数据缓存等大量优化,并提供 JTAG、MMU、MUL/DIV 等可选扩展以定制设计,整体面向 FPGA 芯片优化。
目标硬件
Zephyr 中的litex_vexriscv板卡配置面向以下两类由 LiteX 生成的 SoC 实现:
- Digilent Arty A7-35T / A7-100T开发板——最常用的验证目标,对应 F4PGA(SymbiFlow)开源工具链;
- SDI-MIPI Video Converter(Antmicro 的 SDI 转 MIPI 视频转换板)——对应 oxide(yosys+nextpnr)工具链。
支持的硬件功能
litex_vexriscv.yaml中通过supported:字段声明了板卡已支持的设备类别:
supported: - gpio - uart - spi - sdhc - i2s - i2c - netif:eth - watchdog而在 litex_vexriscv.dts 中可以看到这套 SoC 实际例化的外设比声明更丰富。顶层chosen与aliases节点把系统关键角色绑定到具体外设:
chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,sram = &ram0; zephyr,entropy = &prbs0; }; aliases { sdhc0 = &sdhc0; watchdog0 = &wdt0; };内存布局上,ram0位于 0x40000000,大小为 0x10000000(256 MB 主 RAM,实际物理大小由 FPGA 上的内存颗粒决定);所有外设都挂在 0xe0000000 起的 MMIO 地址空间。主要外设及其在设备树中的地址如下:
| 外设 | 设备树节点 | 基地址 | compatible |
|---|---|---|---|
| SoC 控制器(复位/scratch/总线错误) | ctrl0 | 0xe0000000 | litex,soc-controller |
| UART 控制台 | uart0 | 0xe0001800 | litex,uart |
| 定时器(含 uptime) | timer0 | 0xe0002800 | litex,timer0 |
| 硬件唯一 ID(DNA) | dna0 | 0xe0003800 | litex,dna0 |
| 时钟控制器(MMCM DRP) | clock0 | 0xe0004800 | litex,clk |
| I2C | i2c0/i2c1 | 0xe0005000 / 0xe000d800 | litex,i2c/litex,litei2c |
| GPIO 输出 / 输入 | gpio_out/gpio_in | 0xe0005800 / 0xe0006000 | litex,gpio |
| 伪随机熵源(PRBS) | prbs0 | 0xe0006800 | litex,prbs |
| PWM | pwm0 | 0xe0007000 | litex,pwm |
| MDIO(以太网 PHY 管理) | mdio0 | 0xe0008000 | litex,liteeth-mdio |
| SPI | spi0 | 0xe0002000 | litex,spi |
| SPI Flash(LiteSPI,内存映射) | spi1+spiflash0 | 0xe000c000 | litex,spi-litespi/jedec,spi-nor |
| 看门狗 | wdt0 | 0xe000d000 | litex,watchdog |
| SD 卡(SDHC/MMC) | sdhc0 | 0xe000e800 | litex,mmc |
| 以太网 | eth0 | 0xe0009800 | litex,liteeth |
| I2S 接收 / 发送 | i2s_rx/i2s_tx | 0xe000a800 / 0xe000b000 | litex,i2s |
几个值得注意的实现细节:
- 串口:
uart0在 litex_vexriscv.dts 中被声明为 8 个独立 32 位寄存器(rxtx、txfull、rxempty、ev_status 等),波特率固定为 115200,同时承担 Zephyr 控制台与 shell 的角色。 - SPI NOR Flash:
spi1(LiteSPI)带flash_mmap内存映射窗口(0x60000000,16 MB),挂载的spiflash0是标准jedec,spi-nor器件,spi-max-frequency为 10 MHz,可用于文件系统或固件存储。 - 以太网:
eth0通过phy-handle关联mdio0下的 PHY,并预设了local-mac-address;Kconfig.defconfig 中通过configdefault ETH_DRIVER default y默认启用以太网驱动。 - 熵源:
prbs0(LiteX PRBS 伪随机序列生成器)被选为zephyr,entropy,满足 Zephyr 熵 API 的需求,对应的绑定为 dts/bindings/rng/litex,prbs.yaml。 - SD 卡:
sdhc0下声明了zephyr,sdmmc-disk节点(磁盘名为 "SD"),使 Zephyr 可以通过标准磁盘/文件系统 API 访问 SD 卡。
比特流生成:把 SoC"烧"进 FPGA
要在 FPGA 上运行 Zephyr,第一步是生成比特流(bitstream,即 FPGA 配置文件)。官方文档提供了两条路径,推荐优先使用参考平台以保证寄存器地址与 Zephyr 设备树严格一致。
方式一:Zephyr on LiteX VexRiscv 参考平台
参考平台是官方验证过的构建入口,它保证所有寄存器地址都处于正确位置,并且所有 Zephyr 驱动都基于该平台测试通过。生成步骤如下:
1. 克隆仓库并初始化全部子模块:
git clone https://github.com/litex-hub/zephyr-on-litex-vexriscv.git cd zephyr-on-litex-vexriscv git submodule update --init --recursive生成 Digilent Arty A7-35 的比特流需要先安装 F4PGA 工具链;生成 SDI-MIPI Video Converter 的比特流则需要安装 oxide(yosys+nextpnr)工具链。
2. 安装依赖并运行安装脚本:
apt-get install build-essential bzip2 python3 python3-dev python3-pip ./install.sh3. 将 LiteX 加入 PATH:
source ./init4. 配置 F4PGA 环境(仅 Digilent Arty A7-35 需要):
export F4PGA_INSTALL_DIR=~/opt/f4pga export FPGA_FAM="xc7" export PATH="$F4PGA_INSTALL_DIR/$FPGA_FAM/install/bin:$PATH"; source "$F4PGA_INSTALL_DIR/$FPGA_FAM/conda/etc/profile.d/conda.sh" conda activate $FPGA_FAM5. 按目标硬件生成比特流:
# Arty A7-35T ./make.py --board=arty --variant=a7-35 --build --toolchain=symbiflow # Arty A7-100T ./make.py --board=arty --variant=a7-100 --build --toolchain=symbiflow # SDI-MIPI Video Converter ./make.py --board=sdi_mipi_bridge --build --toolchain=oxide生成的比特流(如digilent_arty.bit、antmicro_sdi_mipi_video_converter.bit)就是后续烧写到 FPGA 的配置文件。
方式二:官方 LiteX SoC Builder
也可以直接使用官方 LiteX 仓库生成比特流,但此时必须额外生成一份 dts overlay,因为自行配置的 SoC 外设地址可能与 Zephyr 内置设备树不一致。
1. 安装 Migen/LiteX 及其核:
wget https://raw.githubusercontent.com/enjoy-digital/litex/master/litex_setup.py chmod +x litex_setup.py ./litex_setup.py --init --install --user (--user to install to user directory) --config=(minimal, standard, full)--config可选minimal、standard、full,决定安装的 LiteX 生态组件范围。
2. 安装 RISC-V 工具链:
pip3 install meson ninja ./litex_setup.py --gcc=riscv3. 构建目标 SoC(以 Arty 为例),并导出 CSR 布局:
./litex-boards/litex_boards/targets/digilent_arty.py --build --timer-uptime --csr-json csr.json--timer-uptime会例化带 uptime 功能的定时器(对应设备树中timer0的uptime_latch/uptime_cycles寄存器);--csr-json csr.json导出每个外设寄存器的最终地址。
4. 生成 dts 与配置 overlay:
./litex/litex/tools/litex_json2zephyr.py --dts overlay.dts --config overlay.config csr.json(原文档中的命令为litex_json2dts_zephyr.py,请以实际安装的 LiteX 版本提供的脚本名为准。)这一步产生的overlay.dts会在下一步编译 Zephyr 应用时通过-DDTC_OVERLAY_FILE传给设备树编译流程,从而让 Zephyr 的设备树与实际生成的 SoC 地址完全对应。
构建 Zephyr 应用
应用构建方式与 Zephyr 其他板卡一致(参考构建应用文档),只需把BOARD设为litex_vexriscv:
west build -b litex_vexriscv path/to/app如果比特流是用官方 LiteX SoC Builder 生成的,还需要额外传入 overlay:
west build -b litex_vexriscv path/to/app -DDTC_OVERLAY_FILE=path/to/overlay.dts构建产物中的zephyr.bin即用于串口引导的内核镜像。
板级默认配置解读
litex_vexriscv_defconfig 定义了板卡默认开启的 Kconfig 选项:
CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y CONFIG_GPIO=y CONFIG_CLOCK_CONTROL=y CONFIG_HEAP_MEM_POOL_SIZE=4096CONFIG_UART_CONSOLE=y:把uart0(115200 波特)作为默认控制台,与设备树chosen中的zephyr,console呼应;CONFIG_GPIO/CONFIG_CLOCK_CONTROL:启用 GPIO 与时钟控制子系统;CONFIG_HEAP_MEM_POOL_SIZE=4096:预分配 4 KB 系统堆,供网络栈、文件系统等需要动态内存的组件使用。
板卡 Kconfig 入口 Kconfig.litex_vexriscv 通过select SOC_LITEX_VEXRISCV关联到 soc/litex/litex_vexriscv/Kconfig.soc 定义的 SoC 系列;SoC 层的 Kconfig.defconfig 则把NUM_IRQS默认设为 12,与设备树 SoC 节点intc0的中断向量数量对应。
烧写比特流与串口启动
上传比特流到 FPGA
Digilent Arty A7可以使用xc3sprog或openFPGALoader:
xc3sprog -c nexys4 digilent_arty.bitopenFPGALoader -b arty_a7_100t digilent_arty.bitSDI-MIPI Video Converter使用ecpprog:
ecpprog -S antmicro_sdi_mipi_video_converter.bit从串口引导 Zephyr
烧写好比特流后,SoC 的 BIOS 会进入串口引导流程。使用litex_term从串口加载内核(将ttyUSBX替换为实际设备节点):
litex_term /dev/ttyUSBX --speed 115200 --kernel zephyr.binlitex_term会把zephyr.bin通过串口下载到内存并跳转执行。启动后即可在 115200 波特率的串口终端上看到 Zephyr 的输出与 shell 提示符——这也是 litex_vexriscv.jpg 右侧控制台窗口所展示的典型画面:LiteX BIOS 打印 SoC 配置(VexRiscv CPU、ROM/SRAM/MAIN-RAM 大小)后等待从串口引导。
源码层面的深入支撑
要理解这套流程为何"开箱即用",可以沿着仓库源码追一遍:
- SoC 定义:soc/litex/litex_vexriscv/Kconfig.soc 将
SOC定义为"litex_vexriscv",CMakeLists.txt 引入soc/common/riscv-privileged的中断向量与启动汇编,并把链接脚本指向 include/zephyr/arch/riscv/common/linker.ld,说明 VexRiscv 以 RISC-V privileged 模式运行 Zephyr。 - SoC 级设备树:dts/riscv/riscv32-litex-vexriscv.dtsi 声明 CPU 节点(
litex,vexriscv-standard)、中断控制器(litex,vexriscv-intc0)等基础结构,板级 litex_vexriscv.dts 通过#include <riscv32-litex-vexriscv.dtsi>继承并补充具体外设。 - 设备树绑定:仓库在 dts/bindings 下为 LiteX 全套外设提供了 binding(
litex,uart、litex,timer0、litex,liteeth、litex,mmc、litex,spi-litespi、litex,i2s、litex,prbs、litex,gpio、litex,clk等),这是设备树节点能被 Zephyr 驱动识别的前提。 - 测试约束:litex_vexriscv.yaml 的
testing.ignore_tags排除了bluetooth与xip——软核 SoC 没有蓝牙硬件,且当前不支持 XIP(从 Flash 就地执行),运行 Zephyr 测试套件时这两类用例会被自动跳过。
小结
LiteX VexRiscv 是理解"软件(Zephyr RTOS)如何与可定制硬件(LiteX SoC)协同"的极佳平台:先用zephyr-on-litex-vexriscv或官方 LiteX SoC Builder 生成比特流,再用west build -b litex_vexriscv编译应用,最后通过litex_term从串口加载zephyr.bin启动。整个链路——SoC 定义、设备树、绑定、板级配置——都可以在本仓库的boards/enjoydigital/litex_vexriscv/、soc/litex/与dts/bindings/目录中逐一对证,为在自研 FPGA SoC 上移植 Zephyr 提供了完整的参考范本。
【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考