Writing an OS in 1000 linesやる
5. ブート
進めていると、下のようにOpenSBIのロゴが出ない問題が発生した
code: shell
$ ./run.sh
+ QEMU=qemu-system-riscv32
+ qemu-system-riscv32 -machine virt -bios opensbi-riscv32-generic-fw_dynamic.bin -nographic -serial mon:stdio --no-reboot
qemuのバージョンを見てみると、
code: sh
$ qemu-system-riscv32 --version
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.27)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
環境構築の章でDLしたのはv8.0.4
code:sh
そりゃ動かんわ
現行最新のqemu-8.1.2をDLすることにした
↑を参考にしました、ありがとうございますmmm
僕は~/tools/qemu-riscv32-8.1.2にDLした
code: sh
$ cd ~/tools/qemu-riscv32-8.1.2
$ tar xvJf qemu-8.1.2.tar.xz
$ cd qemu-8.1.2
$ mkdir build
$ cd build
$ ../configure --target-list=riscv32-softmmu --prefix=$HOME/tools/qemu-riscv32-8.1.2
$ make
$ make install
configureしたときに、python関係で怒られたため、python3-venvを入れた
8.1.2のopensbiもDLしておく
うまくいった!
kernelがコンパイル(リンク)できない
できなかった
結果↓ ながいので省略している
code:sh
clang version 10.0.0-4ubuntu1
Target: riscv32
Thread model: posix
InstalledDir: /usr/bin
~~~~~~~~~~~~~~~~~~~
clang -cc1 version 10.0.0 based upon LLVM 10.0.0 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "include"
/usr/lib/llvm-10/lib/clang/10.0.0/include
End of search list.
"/usr/bin/ld" -m elf32lriscv -L/lib -Tkernel.ld -Map=kernel.map /tmp/kernel-66d2f0.o -o kernel.elf
/usr/bin/ld: 認識できないエミュレーションモードです: elf32lriscv
サポートされているエミュレーションモード: elf_x86_64 elf32_x86_64 elf_i386 elf_iamcu elf_l1om elf_k1om i386pep i386pe
clang: error: ld command failed with exit code 1 (use -v to see invocation)
/usr/bin/ldが呼ばれているが、ここはld.lldを呼んだほうがよさそう
デフォルトがld linkerを呼んでいるみたい????
ここにあるとおりに、linkerを別で呼んだほうがよさそう たしかにみかん本でもそうしてたしね
lldに渡すオプションは、上にあるとおり-m elf32lriscv -L/lib -Tkernel.ld -Map=kernel.map /tmp/kernel-66d2f0.o -o kernel.elfにする
-m : エミュレーションターゲットを指定
-L/lib : ライブラリの探し先
-o : 出力場所、名前を指定。デフォルトはa.out
オブジェクトファイルのとこはいじる
CFLAGSに追加したcオプションは、リンク前までやるようにできる
これだと、ld.lld: error: kernel.c:(.text+0x0): relocation R_RISCV_ALIGN requires unimplemented linker relaxation; recompile with -mno-relax と言われる
CFLAGSに-mno-relaxつければよさそう
6. hello world
printfで出てきたva_***は何者だ...?? みかん本で出てきたかもしれないけど、忘れてしまった
va_listは、引数の列
va_startで、引数列に今回使いたい列を設定(?)
va_argで、中身を取り出しつつ、ポインタを進める
va_endで、おしまい
なるほどわかりやすい。
builtinのやつはどこにあるか分からないが、stdarg.hに同じもの?があるみたいなので、こんどちゃんと調べる
7. c stdlib
Cって難しいな、と改めて思った
8. kernel panic
11. process
カーネルスタックがちゃんと理解できていない
13,14
下のように、scauseが期待した値になってない(桁数もたりないし....)
PANIC: kernel.c:48: unexpected trap scause=0000000, stval=80200000, sepc=01000026
info registersで確認したところ、scause 0000000fになってたので、動作は正しい。
ただ、パニック時の出力がなんか変だ...]