Writing an OS in 1000 linesやる
#OS
https://operating-system-in-1000-lines.vercel.app/ja/welcome
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
curl -LO https://github.com/qemu/qemu/raw/v8.0.4/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
そりゃ動かんわ
現行最新のqemu-8.1.2をDLすることにした
https://zenn.dev/sphendami/scraps/e3b9bdb82d0b7e
↑を参考にしました、ありがとうございますmmm
僕は~/tools/qemu-riscv32-8.1.2にDLした
code: sh
$ cd ~/tools/qemu-riscv32-8.1.2
$ wget https://download.qemu.org/qemu-8.1.2.tar.xz
$ 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しておく
https://github.com/qemu/qemu/blob/v8.1.2/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
うまくいった!
https://github.com/yttnn/os-1000/commit/dd73b64cf75871e52abf5b4c24548c0885afa72e
kernelがコンパイル(リンク)できない
できなかった
https://github.com/yttnn/os-1000/commit/d4602fdd3ef6cc626bb28051c74d97e163cf8226 clang -vで見やすくしている
結果↓ ながいので省略している
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"
#include "..." search starts here:
#include <...> search starts here:
/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
オブジェクトファイルのとこはいじる
https://github.com/yttnn/os-1000/commit/6a78ed261ffeee7a3a57dfd1fb30f6c4966ddd2c
CFLAGSに追加したcオプションは、リンク前までやるようにできる
これだと、ld.lld: error: kernel.c:(.text+0x0): relocation R_RISCV_ALIGN requires unimplemented linker relaxation; recompile with -mno-relax と言われる
CFLAGSに-mno-relaxつければよさそう
https://en.wikipedia.org/wiki/Linker_(computing)#Relocation リンカのリラックスは、メモリ最適化の手段で、OS開発ではOFFにしとくのがよさそう
https://github.com/yttnn/os-1000/commit/6cac361d850c5f97f7307c801e7baa2306a1b1c0 5.boot 完了!!
6. hello world
インラインアセンブラの書き方がわからなくなったので https://wocota.hatenadiary.org/entry/20090628/1246188338
printfで出てきたva_***は何者だ...?? みかん本で出てきたかもしれないけど、忘れてしまった
http://kwski.net/cplusplus/209/
va_listは、引数の列
va_startで、引数列に今回使いたい列を設定(?)
va_argで、中身を取り出しつつ、ポインタを進める
va_endで、おしまい
なるほどわかりやすい。
builtinのやつはどこにあるか分からないが、stdarg.hに同じもの?があるみたいなので、こんどちゃんと調べる
https://github.com/yttnn/os-1000/compare/main%40{3day}...main
7. c stdlib
Cって難しいな、と改めて思った
https://github.com/yttnn/os-1000/pull/1
8. kernel panic
https://github.com/yttnn/os-1000/pull/2
知らなかった、勉強になる https://www.jpcert.or.jp/sc-rules/c-pre10-c.html
11. process
https://github.com/yttnn/os-1000/pull/4
カーネルスタックがちゃんと理解できていない
13,14
https://github.com/yttnn/os-1000/pull/6
下のように、scauseが期待した値になってない(桁数もたりないし....)
PANIC: kernel.c:48: unexpected trap scause=0000000, stval=80200000, sepc=01000026
info registersで確認したところ、scause 0000000fになってたので、動作は正しい。
ただ、パニック時の出力がなんか変だ...]