UCBが開発しているRISC-VのシミュレータSpikeや、Rocket-ChipのRTLデザインは通常はシステムコールを持っていない。
つまり、当然ながらC言語でprintf("Hello World\n");
などと書いても動作しないのだが、そこはコンパイラとフロントエンドサーバfesvr、pk(Proxy Kernel)によって肩代わりすることでこれらのシステムコールを実現している。
RISC-VのシミュレータであるSpikeでは、これらのシステムコールとUARTによるコンソールを実現しており、これを移植して自作RISC-Vシミュレータで動作させると、Linuxのブートができるはずだ。 やってみよう。
RISC-Vの外にあるホストインタフェースに、システムコールのポートと、コンソールのポートを追加した。
どちらのポートを使うかは、THOSTインタフェースに入力されるデバイス番号で識別するようにする。
以下のような感じでデバイスを追加できる
class RiscvDeviceList_t { private: std::vector<RiscvDevice_t*> m_devices; ... void RegisterDevice (RiscvDevice_t* dev) { m_devices.push_back(dev); } void HandleCommand (UDWord_t cmd) { m_devices[device(cmd)]->HandleCommand(cmd); }
システムコールを処理するインタフェースと、BCD(コンソールインタフェース)を追加した。
RiscvPeThread::RiscvPeThread (FILE *dbgfp, RiscvBitMode_t bit_mode, PrivMode maxpriv, bool en_stop_host, ... m_device_list = new RiscvDeviceList_t(); RiscvSyscall_t *riscv_syscall = new RiscvSyscall_t(this); m_device_list->RegisterDevice(riscv_syscall); // Device List = 0 RiscvTerm_t *riscv_term = new RiscvTerm_t (); m_device_list->RegisterDevice(riscv_term); // Device List = 1 ...
RISC-VのBBLとvmlinuxを作成し、シミュレータで実行した。 ここまでで、どうにか最初のスプラッシュ画面と、vmlinuxの最初の方までは動作するようになってきた。
ただし、途中で止まってしまうので解析しなければ...