<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>OpenSBI on WSLIN</title><link>https://wslin.dev/tags/opensbi/</link><description>Recent content in OpenSBI on WSLIN</description><generator>Hugo</generator><language>zh-tw</language><lastBuildDate>Mon, 20 Apr 2026 13:48:45 +0800</lastBuildDate><atom:link href="https://wslin.dev/tags/opensbi/index.xml" rel="self" type="application/rss+xml"/><item><title>【OS】OpenSBI 開啟Timer Interrupt</title><link>https://wslin.dev/blog/os-opensbi-timer-interrupt/</link><pubDate>Mon, 20 Apr 2026 13:48:45 +0800</pubDate><guid>https://wslin.dev/blog/os-opensbi-timer-interrupt/</guid><description>&lt;p&gt;最近在實作RISC-V OS的Trap時，剛好要做Timer Interrupt，這在QEMU中非常簡單，只要follow xv6的做法就可以實現，但在Milkv開發版上就不太一樣。&lt;/p&gt;&#10;&lt;p&gt;因為我的Milkv開發版上不是裸機執行OS，而是透過OpenSBI來載入並降級到S-Mode，且又因為RISC-V的Timer Interrupt 是只能在M-Mode設置，因此做起來就比較麻煩，需要在S-Mode下透過ecall 委託M-Mode的OpenSBI來完成。&lt;/p&gt;&#10;&lt;h2 id="xv6在qemu上的做法"&gt;&#10; xv6在QEMU上的做法&#10; &lt;a class="heading-link" href="#xv6%e5%9c%a8qemu%e4%b8%8a%e7%9a%84%e5%81%9a%e6%b3%95"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;先來快速go through xv6是怎麼做Timer Interrupt的，首先需要先還在M-Mode時就先設置menvcfg (Machine Environment Configuration) 這個csr暫存器的bit 63來允許 S-mode 使用 stimecmp (Sstc or Supervisor-mode Timer Compare extension)。 (&lt;a href="https://github.com/mit-pdos/xv6-riscv/blob/riscv/kernel/start.c" class="external-link" target="_blank" rel="noopener"&gt;xv6-start.c line:59&lt;/a&gt;)&lt;/p&gt;&#10;&lt;p&gt;然後再設置mcounteren的bit 1，允許 S-mode 讀 time 計數器，沒設的話在執行&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;asm&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;volatile&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;csrr %0, time&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;=r&amp;#34;&lt;/span&gt; (x));&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;時就會觸發 illegal instruction。&lt;/p&gt;&#10;&lt;p&gt;以上兩個都開啟後，就可以在S-Mode中設置stimecmp來開啟timer的計時功能了，時間到就會Trap，然後跳到我們寫好的Trap Handler處理。&lt;/p&gt;&#10;&lt;h2 id="milkv-duo-s-opensbi-上的做法"&gt;&#10; Milkv Duo S (OpenSBI) 上的做法&#10; &lt;a class="heading-link" href="#milkv-duo-s-opensbi-%e4%b8%8a%e7%9a%84%e5%81%9a%e6%b3%95"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;然而因為我目前的Milkv Duo S是跑在OpenSBI下的，所以OS一進來就是S-Mode，沒辦法碰到M-Mode的暫存器，加上他的CPU C906不支援Sstc，不能直接在S-Mode設timer。&lt;/p&gt;&#10;&lt;p&gt;但好在OpenSBI有開啟前面兩點，並提供直接設置Timer計數的功能，因此只要ecall呼叫一下OpenSBI請他開始計數即可。&lt;/p&gt;</description></item></channel></rss>