Hello Worldのプログラムを動かしながら、RISC-V Spikeシミュレータのログを追っていき、RISC-Vのブートシーケンスを追っていく、その3。
Spikeシミュレータはファイルの呼び出しもできる。これを実現しているのは、Spikeとは外部に接続されているpk(Proxy Kernel)だ。
試しにこんなプログラムを書いてRISC-VのGCCでコンパイルしてみる。
- file_access.c
#include <stdio.h> #include <stdlib.h> int main () { printf("Hello World\n"); FILE *fp; if ((fp = fopen("sample_hello.txt", "w")) == NULL) { perror ("sample_hello.txt"); exit(EXIT_FAILURE); } fprintf (fp, "Hello World\n"); fclose (fp); if ((fp = fopen("sample_hello.txt", "r")) == NULL) { perror ("sample_hello.txt"); exit(EXIT_FAILURE); } char cin[100]; fscanf (fp, "%s", cin); printf ("%s\n", cin); char c[100]; scanf("%s", c); printf("%s\n", c); return 0; }
run: file_access_riscv file_access_x86 spike pk $< file_access_riscv: file_access.c riscv64-unknown-elf-gcc $^ -o $@ file_access_x86: file_access.c gcc $^ -o $@
これで実行してみると、通常のprintf/scanf
はProxy Kernelの力で問題なく読み取りができる。一方で、ファイルシステムのほうは少し工夫が必要だった。
上記のプログラムでsample_hello.txt
が存在しない場合、エラーとなって終了してしまう。
$ make run spike pk file_access_riscv Hello World sample_hello.txt: No such file or directory Makefile:2: recipe for target 'run' failed make: *** [run] Error 1
ファイルをあらかじめ作っておくと、問題なく動作する。これはpkのバグか?仕様か?
$ make run spike pk file_access_riscv Hello World Hello hello hello $ cat sample_hello.txt Hello World
というわけで、動作の様子を観測したいので自作ISSで関数トレースを出してみたのだが、良くわからなくなった... もう少し解析だな。
... <Return: plic_prop> <FunctionCall 46805 plic_done(0x800035d4)> <Return: plic_done> <Return: fdt_scan_helper> <Return: fdt_scan_helper> <Return: fdt_scan> <Return: query_plic> <FunctionCall 46988 hart_plic_init(0x80002918)> <Return: hart_plic_init> <FunctionCall 47025 file_init(0x80000696)> <FunctionCall 47032 file_get_free(0x800005b0)> <Return: file_get_free> <FunctionCall 47053 file_dup(0x8000064a)> <FunctionCall 47068 file_incref(0x800005f0)> <Return: file_incref> <Return: file_dup> <FunctionCall 47082 file_get_free(0x800005b0)> <Return: file_get_free> <FunctionCall 47108 file_dup(0x8000064a)> <FunctionCall 47130 file_incref(0x800005f0)> <Return: file_incref> <Return: file_dup> <FunctionCall 47144 file_get_free(0x800005b0)> <Return: file_get_free> <FunctionCall 47175 file_dup(0x8000064a)> <FunctionCall 47204 file_incref(0x800005f0)> <Return: file_incref> <Return: file_dup> <Return: file_init> <FunctionCall 47223 pk_vm_init(0x80001732)> <FunctionCall 47257 __page_alloc(0x80000e34)> <FunctionCall 47278 memset(0x80007912)> <Return: memset> <Return: __page_alloc> <FunctionCall 48841 __map_kernel_range(0x8000163c)> <FunctionCall 48877 __walk_internal(0x80000e86)> <FunctionCall 48897 __page_alloc(0x80000e34)> <FunctionCall 48918 memset(0x80007912)> <Return: memset> <Return: __page_alloc>