V853开发板开发进阶——在Linux下加载E907核心固件
-
以下内容均来自V853在线文档:https://v853.docs.aw-ol.com/soft/dev_e907_firm/
E907 核心固件加载
在调试阶段,需要经常修改 E907 的代码。而为了调试代码多次刷写系统非常麻烦。其实 E907 核心的固件可以在 Linux 系统内加载,本文将描述如何在 Linux 系统内启动 E907 核心、加载 E907 固件、关闭 E907 核心。
如何加载
从上一篇文章可以知道,这里使用
remoteproc
管理小核的生命周期。
上一篇文章:详解全志V853上的ARM A7和RISC-V E907之间的通信方式
remoteproc
框架抽象出硬件差异,允许不同的平台/架构来控制(开机、加载固件、关机)这些远程处理器,此外,还为支持这种通信的远程处理器添加了rpmsg
virtio
设备。这样,特定平台的remoteproc
驱动程序只需要提供一些低级处理程序,然后所有rpmsg
驱动程序就可以正常工作。作用:
- 从文件系统加载固件
- 准备远程处理器所需资源
- 注册一个
rpmsg virtio
设备 - 提供对要提供对远程处理器的生命周期进行管理
所以固件的加载流程大致如下:
1. 加载固件 1. 调用 firmware 接口获取文件系统中的固件 2. 解析固件的 resource_table 段,该段有如下内容 1. 声明需要的内存(Linux 为其分配) 2. 声明使用的 vdev(固定为一个) 3. 声明使用的 vring(固定为两个) 3. 将固件加载到指定地址 2. 注册 rpmsg virtio 设备 1. 提供 vdev->ops(基于 virtio 接口实现的) 2. 与 rpmsg_bus 驱动匹配,完成 rpmsg 初始化 3. 启动小核 1. 调用 rproc->ops->start
Kernel 的配置
首先需要配置设备树,预留 E907 核心内存,
buffer
内存,vring
内存等。并正确配置rproc
与rpbuf
,也不要忘记配置firmware-name
,下面的配置示例为测试固件所使用的地址。不同的固件地址可能不同。reserved-memory { e907_dram: riscv_memserve { reg = <0x0 0x48000000 0x0 0x00400000>; no-map; }; vdev0buffer: vdev0buffer@47000000 { /* 256k reserved for shared mem pool */ compatible = "shared-dma-pool"; reg = <0x0 0x47000000 0x0 0x40000>; no-map; }; vdev0vring0: vdev0vring0@47040000 { reg = <0x0 0x47040000 0x0 0x20000>; no-map; }; vdev0vring1: vdev0vring1@47060000 { reg = <0x0 0x47060000 0x0 0x20000>; no-map; }; }; e907_rproc: e907_rproc@0 { compatible = "allwinner,sun8iw21p1-e907-rproc"; clock-frequency = <600000000>; memory-region = <&e907_dram>, <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>; mboxes = <&msgbox 0>; mbox-names = "mbox-chan"; iommus = <&mmu_aw 5 1>; memory-mappings = /* DA len PA */ /* DDR for e907 */ < 0x48000000 0x00400000 0x48000000 >; core-name = "sun8iw21p1-e907"; firmware-name = "melis-elf"; status = "okay"; }; rpbuf_controller0: rpbuf_controller@0 { compatible = "allwinner,rpbuf-controller"; remoteproc = <&e907_rproc>; ctrl_id = <0>; /* index of /dev/rpbuf_ctrl */ iommus = <&mmu_aw 5 1>; status = "okay"; }; rpbuf_sample: rpbuf_sample@0 { compatible = "allwinner,rpbuf-sample"; rpbuf = <&rpbuf_controller0>; status = "okay"; };
接下来需要配置
kernel
选项,配置驱动。make kernel_menuconfig
并勾选以下驱动:
Device Drivers ---> Remoteproc drivers ---> <*> SUNXI remote processor support Rpmsg drivers ---> <*> allwinnertech rpmsg driver for v853-e907 <*> allwinnertech rpmsg hearbeat driver <*> Virtio RPMSG bus driver <*> sunxi rpmsg ctrl driver [*] Mailbox Hardware Support ---> <*> sunxi Mailbox <*> sunxi rv32 standby driver
加载小核固件
测试固件下载地址:https://www.aw-ol.com/downloads?cat=16
烧录启动系统后,可以在
/sys/kernel/debug/remoteproc/
节点找到remoteproc0
我们可以使用
cat
命令检查小核目前的状况cat /sys/kernel/debug/remoteproc/remoteproc0/state
可以看到目前是
offline
的。可以尝试使用echo
启动小核echo start > /sys/kernel/debug/remoteproc/remoteproc0/state
可以看到,由于我们没有加载固件,小核启动失败。此时我们需要把准备好的固件放置到开发板的
lib/firmware
文件夹内。这里我们使用adb
上传小核固件。!
然后我们将固件名称置于
firmware
节点内,并启动固件。echo e907_test.elf > /sys/kernel/debug/remoteproc/remoteproc0/firmware echo start > /sys/kernel/debug/remoteproc/remoteproc0/state
此时可以看到
remote processor e907_rproc is now up
,同时查看状态也显示了running
此时也可以用
stop
命令停止小核运行echo stop > /sys/kernel/debug/remoteproc/remoteproc0/state
测试小核
在测试之前我们先把
kernel
侧的设备树中uart3
禁用,使小核可以使用uart3
外设打印日志。&uart3 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart3_pins_active>; pinctrl-1 = <&uart3_pins_sleep>; uart-supply = <®_dcdc1>; status = "disabled"; };
如果不禁用
uart3
会出现错误提示:uart: create mailbox fail uart: irq for uart3 already enabled uart: create mailbox fail
然后将调试串口连接到
UART3
排针,加载固件。echo e907_test.elf > /sys/kernel/debug/remoteproc/remoteproc0/firmware echo start > /sys/kernel/debug/remoteproc/remoteproc0/state
便可以启动小核的固件
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号