Skip to content

Latest commit

 

History

History
42 lines (33 loc) · 5.58 KB

diary.md

File metadata and controls

42 lines (33 loc) · 5.58 KB

V言語にMikanOSを移植した話

はじめに

皆さんV言語をご存じですか。V言語とは2019年よりAlex Medvednicov氏が中心となり開発がなされている新進気鋭のプログラミング言語です。文法としてはGo言語に近く、より安全性やメモリ管理がスマートになるよう志向されています。新しい言語のため安定性はそれほど高くないため会社のプロダクト等にはまだ早いと思いますが、趣味の範囲としては面白い言語だと思います。
さて、2021年3月に発売されたuchan氏による「ゼロからのOS自作入門」という本を進めるにあたって、この本で作っていくOSはオープンソースになっている氏によるMikanOSというOSです。このOSはC++で開発されており、確かに現代的な言語ではあるんです。あるんですが、V言語に慣れてしまった以上、冗長性に耐えられなくなってしまいました。
OSに使える言語とは何でしょう?氏がDiscordサーバーのもくもく会で仰っていたことをまとめると、(C言語を基底としてほかの言語が上に立つ、などではなく)システム部分に直接触れることができる言語がよく、かつ(Go言語のように)GCなどのメモリ管理を切ることのできない言語は向かない、ということでした。現代としてはC言語、C++、Rustが例に挙がるでしょうか。しかし、C言語はもはや古く言語機能も小さく、またRustにはシステムやメモリ周りの複雑性、天才性が求められます。
そこで私としては、V言語はOS開発に向くのではないか?と思っているわけです。V言語はGo言語と違いGCを基本的には採用しておらず、またC言語へのトランスパイラということもあり、OS開発への親和性はC言語並みにあると考えられます。故に私はMikanOSをV言語に移植してみたく思ったわけです。
とんでもない罠を踏んだり、飽きたときはその時です。しかし、V言語のゴミ加減すばらしさを何としても世の中に広めたい。この移植でV言語に興味を持ってくださる方がいらっしゃったとしたら、感極まります。

day03

まず初めにお断りしておきたいのが、ブートローダはC言語に任せた方がよいと判断したため、V言語での開発はカーネルに限ります。これは、V言語を生でコンパイルしてしまうとバイナリサイズが(ブートローダとしては)大きくなってしまうのと、C言語の方が素直にUEFIのAPIを定義し操作できるからです。これに関しては本家MikanOSでもC言語となっているため、これに倣います。

さて、まずどうやってV言語のコードをコンパイルし動かすかを考えます。第一に考えたのは、V言語に備わっている-freestandingオプションです。これはlibcから独立したプログラムを組むときに用いるオプションで、もちろんこれで動かしてみようと思っていました。
しかし、V言語はまだ不安定です。先月までコンパイルできたコードが通らないことは日常茶飯事です。なんと、このオプションは現在死んでいて使い物になりませんでした!

そこで次に考えたのは、素でC言語にコンパイルして、足りないsyscallはプレースホルダに置き換えてしまおうという作戦です。幸いにも元のMikanOSのビルド機構にはプレースホルダさえ置いてしまえばリンクして実用できるlibc互換なブツが用意されていました。試しにV言語で書いてコンパイルして生成したC言語のコードをそこにリンクしてコンパイルすると、以下の関数がリンクできないとエラーが出ました。

_exit
sbrk
close
lseek
read
write
fstat
isatty

このプレースホルダは既に本家で実装されていたので、ありがたく使わせていただきました。そして、そのオブジェクトファイルと一緒にリンクしてやると、kernel.elfが無事生成できました。

最後に、V言語からはKernelMainという名前のエントリーポイント関数は直接作れないので、C言語でV言語のエントリー関数を呼ぶ関数を作成してやります。これでちゃんとV言語のソースコードで動くカーネルの完成です。

day04

C言語のstructとV言語のstructには互換性があります。WIP

day05

順当に行って次はフォントの読み込みと文字の表示です。 WIP

day08

WIP ここで、V言語にはC言語のようなビットフィールド(bit fieldとかbit packingって言われている機能)は存在しませんでした。というのも、これを作り始めた当初は、V言語にbitfieldというモジュールが入っているし、Joe氏(V言語開発者の一人)がそれらしい機能を実装したという情報をもとに見切り発車してしまいました。しかしながらその実態はC言語の機能とは違い、ビットDPとかで使うような(よく知りませんが)ビット操作中心のモジュールだったのです。これは失敗。
そこで、V言語にbitfieldモジュールをC言語のビットフィールド操作ができるようにする簡単なメソッド追加のPRを送りつけました(#9612)。