<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[V853开发板开发进阶——在Linux下加载E907核心固件]]></title><description><![CDATA[<p dir="auto"><strong>以下内容均来自V853在线文档：<a href="https://v853.docs.aw-ol.com/soft/dev_e907_firm/" target="_blank" rel="noopener noreferrer nofollow ugc">https://v853.docs.aw-ol.com/soft/dev_e907_firm/</a></strong></p>
<h1>E907 核心固件加载</h1>
<p dir="auto">在调试阶段，需要经常修改 E907 的代码。而为了调试代码多次刷写系统非常麻烦。其实 E907 核心的固件可以在 Linux 系统内加载，本文将描述如何在 Linux 系统内启动 E907 核心、加载 E907 固件、关闭 E907 核心。</p>
<h2>如何加载</h2>
<p dir="auto">从上一篇文章可以知道，这里使用 <code>remoteproc</code> 管理小核的生命周期。<br />
上一篇文章：<a href="https://bbs.aw-ol.com/topic/1725/">详解全志V853上的ARM A7和RISC-V E907之间的通信方式</a><br />
<code>remoteproc</code> 框架抽象出硬件差异，允许不同的平台/架构来控制（开机、加载固件、关机）这些远程处理器，此外，还为支持这种通信的远程处理器添加了 <code>rpmsg</code> <code>virtio</code> 设备。这样，特定平台的 <code>remoteproc</code> 驱动程序只需要提供一些低级处理程序，然后所有 <code>rpmsg</code> 驱动程序就可以正常工作。</p>
<p dir="auto">作用：</p>
<ul>
<li>从文件系统加载固件</li>
<li>准备远程处理器所需资源</li>
<li>注册一个 <code>rpmsg virtio</code> 设备</li>
<li>提供对要提供对远程处理器的生命周期进行管理</li>
</ul>
<p dir="auto"><img src="/assets/uploads/files/1658730508499-2022-07-19-15-33-28-image.png" alt="2022-07-19-15-33-28-image.png" class=" img-responsive img-markdown" width="817" height="500" /></p>
<p dir="auto">所以固件的加载流程大致如下：</p>
<pre><code>1. 加载固件
   1. 调用 firmware 接口获取文件系统中的固件
   2. 解析固件的 resource_table 段，该段有如下内容
      1. 声明需要的内存（Linux 为其分配）
      2. 声明使用的 vdev（固定为一个）
      3. 声明使用的 vring（固定为两个）
   3. 将固件加载到指定地址
2. 注册 rpmsg virtio 设备
   1. 提供 vdev-&gt;ops（基于 virtio 接口实现的）
   2. 与 rpmsg_bus 驱动匹配，完成 rpmsg 初始化
3. 启动小核
   1. 调用 rproc-&gt;ops-&gt;start
</code></pre>
<h2>Kernel 的配置</h2>
<p dir="auto">首先需要配置设备树，预留 E907 核心内存，<code>buffer</code> 内存，<code>vring</code> 内存等。并正确配置 <code>rproc</code> 与 <code>rpbuf</code>，也不要忘记配置 <code>firmware-name</code>，下面的配置示例为测试固件所使用的地址。不同的固件地址可能不同。</p>
<pre><code class="language-c">reserved-memory {
    e907_dram: riscv_memserve {
        reg = &lt;0x0 0x48000000 0x0 0x00400000&gt;;
        no-map;
    };

    vdev0buffer: vdev0buffer@47000000 {
        /* 256k reserved for shared mem pool */
        compatible = "shared-dma-pool";
        reg = &lt;0x0 0x47000000 0x0 0x40000&gt;;
        no-map;
    };

    vdev0vring0: vdev0vring0@47040000 {
        reg = &lt;0x0 0x47040000 0x0 0x20000&gt;;
        no-map;
    };

    vdev0vring1: vdev0vring1@47060000 {
        reg = &lt;0x0 0x47060000 0x0 0x20000&gt;;
        no-map;
    };
};

e907_rproc: e907_rproc@0 {
    compatible = "allwinner,sun8iw21p1-e907-rproc";
    clock-frequency = &lt;600000000&gt;;
    memory-region = &lt;&amp;e907_dram&gt;, &lt;&amp;vdev0buffer&gt;,
                    &lt;&amp;vdev0vring0&gt;, &lt;&amp;vdev0vring1&gt;;
    mboxes = &lt;&amp;msgbox 0&gt;;
    mbox-names = "mbox-chan";
    iommus = &lt;&amp;mmu_aw 5 1&gt;;

    memory-mappings =
        /* DA              len         PA */
        /* DDR for e907  */
        &lt; 0x48000000 0x00400000 0x48000000 &gt;;
    core-name = "sun8iw21p1-e907";
    firmware-name = "melis-elf";
    status = "okay";
};

rpbuf_controller0: rpbuf_controller@0 {
    compatible = "allwinner,rpbuf-controller";
    remoteproc = &lt;&amp;e907_rproc&gt;;
    ctrl_id = &lt;0&gt;;    /* index of /dev/rpbuf_ctrl */
    iommus = &lt;&amp;mmu_aw 5 1&gt;;
    status = "okay";
};

rpbuf_sample: rpbuf_sample@0 {
    compatible = "allwinner,rpbuf-sample";
    rpbuf = &lt;&amp;rpbuf_controller0&gt;;
    status = "okay";
};
</code></pre>
<p dir="auto">接下来需要配置 <code>kernel</code> 选项，配置驱动。</p>
<pre><code class="language-c">make kernel_menuconfig
</code></pre>
<p dir="auto">并勾选以下驱动：</p>
<pre><code class="language-c">Device Drivers  ---&gt;
  Remoteproc drivers  ---&gt;
    &lt;*&gt; SUNXI remote processor support
  Rpmsg drivers  ---&gt;
    &lt;*&gt; allwinnertech rpmsg driver for v853-e907
    &lt;*&gt; allwinnertech rpmsg hearbeat driver
    &lt;*&gt; Virtio RPMSG bus driver 
    &lt;*&gt; sunxi rpmsg ctrl driver
  [*] Mailbox Hardware Support  ---&gt;
    &lt;*&gt;   sunxi Mailbox
    &lt;*&gt;   sunxi rv32 standby driver
</code></pre>
<h2>加载小核固件</h2>
<p dir="auto">测试固件下载地址：<a href="https://www.aw-ol.com/downloads?cat=16" target="_blank" rel="noopener noreferrer nofollow ugc">https://www.aw-ol.com/downloads?cat=16</a></p>
<p dir="auto">烧录启动系统后，可以在 <code>/sys/kernel/debug/remoteproc/</code> 节点找到 <code>remoteproc0</code></p>
<p dir="auto"><img src="/assets/uploads/files/1658730744937-2022-07-19-15-58-51-image.png" alt="2022-07-19-15-58-51-image.png" class=" img-responsive img-markdown" width="627" height="55" /></p>
<p dir="auto">我们可以使用 <code>cat</code> 命令检查小核目前的状况</p>
<pre><code class="language-c">cat /sys/kernel/debug/remoteproc/remoteproc0/state
</code></pre>
<p dir="auto"><img src="/assets/uploads/files/1658730765726-2022-07-19-16-04-59-image.png" alt="2022-07-19-16-04-59-image.png" class=" img-responsive img-markdown" width="622" height="53" /></p>
<p dir="auto">可以看到目前是 <code>offline</code> 的。可以尝试使用 <code>echo</code> 启动小核</p>
<pre><code class="language-c">echo start &gt; /sys/kernel/debug/remoteproc/remoteproc0/state
</code></pre>
<p dir="auto"><img src="/assets/uploads/files/1658730777495-2022-07-19-16-07-40-image.png" alt="2022-07-19-16-07-40-image.png" class=" img-responsive img-markdown" width="697" height="162" /></p>
<p dir="auto">可以看到，由于我们没有加载固件，小核启动失败。此时我们需要把准备好的固件放置到开发板的 <code>lib/firmware</code> 文件夹内。这里我们使用 <code>adb</code> 上传小核固件。</p>
<p dir="auto">!<img src="/assets/uploads/files/1658730792802-2022-07-19-16-17-14-image.png" alt="2022-07-19-16-17-14-image.png" class=" img-responsive img-markdown" width="481" height="45" /></p>
<p dir="auto">然后我们将固件名称置于 <code>firmware</code> 节点内，并启动固件。</p>
<pre><code class="language-c">echo e907_test.elf &gt; /sys/kernel/debug/remoteproc/remoteproc0/firmware

echo start &gt; /sys/kernel/debug/remoteproc/remoteproc0/state
</code></pre>
<p dir="auto">此时可以看到 <code>remote processor e907_rproc is now up</code>，同时查看状态也显示了 <code>running</code></p>
<p dir="auto"><img src="/assets/uploads/files/1658730805179-2022-07-19-16-46-33-image.png" alt="2022-07-19-16-46-33-image.png" class=" img-responsive img-markdown" width="662" height="212" /></p>
<p dir="auto">此时也可以用 <code>stop</code> 命令停止小核运行</p>
<pre><code class="language-c">echo stop &gt; /sys/kernel/debug/remoteproc/remoteproc0/state
</code></pre>
<p dir="auto"><img src="/assets/uploads/files/1658730819513-2022-07-19-16-49-24-image.png" alt="2022-07-19-16-49-24-image.png" class=" img-responsive img-markdown" width="633" height="62" /></p>
<h2>测试小核</h2>
<p dir="auto">在测试之前我们先把 <code>kernel</code> 侧的设备树中 <code>uart3</code> 禁用，使小核可以使用 <code>uart3</code> 外设打印日志。</p>
<pre><code class="language-c">&amp;uart3 {
        pinctrl-names = "default", "sleep";
        pinctrl-0 = &lt;&amp;uart3_pins_active&gt;;
        pinctrl-1 = &lt;&amp;uart3_pins_sleep&gt;;
        uart-supply = &lt;&amp;reg_dcdc1&gt;;
        status = "disabled";
};
</code></pre>
<p dir="auto">如果不禁用 <code>uart3</code> 会出现错误提示：</p>
<pre><code class="language-c">uart: create mailbox fail
uart: irq for uart3 already enabled
uart: create mailbox fail
</code></pre>
<p dir="auto">然后将调试串口连接到 <code>UART3</code> 排针，加载固件。</p>
<pre><code class="language-c">echo e907_test.elf &gt; /sys/kernel/debug/remoteproc/remoteproc0/firmware

echo start &gt; /sys/kernel/debug/remoteproc/remoteproc0/state
</code></pre>
<p dir="auto">便可以启动小核的固件</p>
<p dir="auto"><img src="/assets/uploads/files/1658730829162-2022-07-19-18-26-16-image.png" alt="2022-07-19-18-26-16-image.png" class=" img-responsive img-markdown" width="899" height="551" /></p>
]]></description><link>https://bbs.aw-ol.com/topic/1810/v853开发板开发进阶-在linux下加载e907核心固件</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 09:09:08 GMT</lastBuildDate><atom:link href="https://bbs.aw-ol.com/topic/1810.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 25 Jul 2022 07:40:59 GMT</pubDate><ttl>60</ttl></channel></rss>