FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

xv6を移植するときに書き換えるルーチンについて調査(4)

引き続き、RISC-Vにxv6を移植するための情報を調査していこう。

github.com

initcode.Sは一番最初のプロセスとして実行される。 引数を設定し、システムコールを呼び出す。

RISC-Vにて、システムコールを発生させるには以下の命令を使う。

f:id:msyksphinz:20160407232030p:plain

ecallは、システムコールを発生させ、マシンモードに遷移する。どの例外ベクタに飛ぶかについては、どのモードからecall命令を実行したかに依存している。 まず、mtvecレジスタにベクトルベースレジスタを設定し、それから、以下の表に基づいてベクタアドレスにジャンプする。

f:id:msyksphinz:20160408015153p:plain

f:id:msyksphinz:20160408015209p:plain

まずはRISC-Vの例外ベクタを作成しないといけないのだが、この部分はとりあえず例外ベクタのテンプレートだけ用意しておこう。 ちなみに、ecallを実行すると、mcauseレジスタには以下のようなルールで値が書き込まれる(つまり8)、これで、どこから、何の例外が発生したかを確認するわけだ。

f:id:msyksphinz:20160408020102p:plain

さらに、リンカスクリプトを修正する。現在はi386用になっているが、これをRISC-V用に変更した。

OUTPUT_FORMAT("elf32-littleriscv")
OUTPUT_ARCH(riscv)

コンパイルをしていると、_binary_entryother_startや、binary_entryother_sizeがないと怒られる。これは、entryother.Sから来ているものらしいのだが、xv6のマニュアルを読んでも、それらしき説明がない。 いろいろコードを見ていると、スタートアップ時の初期設定をメインのCPUが実行し、それ以外のCPUは待機状態に入る。このためのルーチンらしい。 とりあえずシングルコアで動かす予定なので、この部分は今の時点では実相を省略する。

さらに、usys.Sでは、システムコールを発生させるためのルーチンを定義している。これも、RISC-Vのものに書き換えよう。

#include "syscall.h"
#include "traps.h"

#define SYSCALL(name) \
  .globl name; \
name: \
    li  x16, SYS_ ## name; \
    ecall; \
    eret