CrystalでOSを作ってみた
この記事は Crystal Advent Calendar 2016 の25日目の記事です。
OSと言っても、ブートして文字を表示してるだけですが・・・こんなんです。
リポジトリはこちら
軽く自己紹介
参考にしたもの
Writing an OS in Rust
そしてRustの部分をCrystalで置き換えればいいやろ、と思っていましたがそんな甘い話があるわけもなく・・・。
ざっくり言うと、blog_osでは、Rust側で rust_main()
という関数を用意します。
. . extern crate rlibc; #[no_mangle] pub extern "C" fn rust_main() { // ATTENTION: we have a very small stack and no guard page let hello = b"Hello World!"; let color_byte = 0x1f; // white foreground, blue background let mut hello_colored = [color_byte; 24]; for (i, char_byte) in hello.into_iter().enumerate() { hello_colored[i*2] = *char_byte; } // write `Hello World!` to the center of the VGA text buffer let buffer_ptr = (0xb8000 + 1988) as *mut _; unsafe { *buffer_ptr = hello_colored }; loop {} } . .
#[no_mangle]
付けて pub extern "C" fn rust_main()
していると。
それをアセンブリ側からこのように呼び出しています。
arch/x86_64/long_mode_init.asm
global long_mode_start extern rust_main section .text bits 64 long_mode_start: ; call rust main call rust_main . .
全く同じことをCrystalでやろうとしましたが、上手く出来なかった・・・。pub extern "C"
みたいなのはどうやるの・・・。name mangling を防ぐのどうするの・・・。
そこで次に参考にしたのはこれです。
crystal_library
Write C static (or shared) libraries in Crystal. This is just a Proof of Concept that exemplifies how to expose a Crystal library to the outside world, eg: C or any language with bindings to C.
ふむ、Crystalで静的(or 共有)ライブラリ作って、それをC言語に食わせればいいんだろうか。
ということはこんな感じ? assembly <- C lang <- Crystal
で、やってみましたが、リンク時に -no-stdlib
オプションをつけているので当然、あれもないこれもないでコケまくります。
blog_osでも結局は、rlibc というcrateを導入することで、この問題を回避しています(しかしその後も色々問題は発生するようですが)
http://os.phil-opp.com/set-up-rust.html#rlibc
つ、詰んだ・・・。と思っていたところへ
os-crystal
そのものズバリなプロジェクトを発見します。
ここでは src/x86/loader.cr にて
@[Naked] fun __entry() asm("mov $0, %esp" : : "Z"(0x00100000 + 0x1000)); asm("push 0"); asm("push 0"); asm("call main") asm("hlt") end
インラインアセンブリからシンプルに call main
しています。で、呼び出される側は
require "./x86/loader" require "./x86/OutputConsole" puts "Kernel booting with Crystal!" puts puts "<3"
こうなっているのですが、不思議なのはmain
という関数ではなく、main.cr
というファイルが呼び出されている?ということです。
いや、ほんとわかんない。でも確かに呼び出されている。
これで助かった・・・。
TODOs
というわけでまだまだこれからですが、最後は自分を叱って終わりにしたいと思います。
- アセンブリ部分はほぼblog_osからのパクリじゃないですか。ちゃんと理解しているんですか? 低レベル言語をしっかりと勉強しなさい
- Crystalの部分はほぼos-crystalからのパクリじゃないですか。なんとかしなさい
- OSと言っても、ブートして文字出してるだけじゃないですか。カッコつけてオーガニゼーションアカウント取得して、よくわからないままリリースもしてしまっているんだから、行けるところまで行きなさい
- そもそももっと早くから取り組んでいればこんなことには・・・。 見積もりの甘さと腰の重さをいい加減直しなさい
- pineさんからgithubでフォローしてもらっているのに、すっかり忘れて放置しているじゃないですか。今すぐフォロバしなさい
- コミニュティにも参加しなさい。「他人の輪の中に入っていく」という発想がごっそり抜け落ちてしまっているのは致命的です。もういい歳なんだからしっかりしなさい
- 仕事が全然進んでいない。このままではクライアントに顔向けできないし、何より安心して年を越せないので仕事しなさい
こちらからは以上です・・・。