組み込みTiki/の過去その2
SuzTiki:組み込みTiki
不定期にっき
PDAのコンテンツ 関係で、私的には、PDA の中で Tiki を動かしたい。
そうすると Ruby がないとダメということになる。Tiki を動かす前提で
Ruby が必要とする リソースというのは何?
こういう構造 で、作る... というより 組みあげる。
tiki httpd
------------------------
ruby [Thread]
-----------------------
ライブラリ(Minix)
------------------------ <<<<< VOS API
Virtual OS [FileSystem]
------------------------ <<<<< Host OS API
Host OS
という目的から
という発想になって、
- thread は ruby の中にあるから それを使う。
- ruby が使うライブラリは、MINIX-2.0.3 のものをベースにして、自前でもつ
( 以下 minlib )
- ruby および minlib が使う OS API (関数/変数)には、__vos_ プレフィックス
を付ける。( #define で namespace を強引に 変える)
- __vos_ の API をサポートする、Virtual OS を 考える。
- ファイルシステムは、V7 のものを使い 内蔵する。(以下 v7fs )
ここまでが いままでの あらすじ。→ ./の過去その1
現在は、
- minlib の 組み込み
- __vos_ プレフィックスを付けた API セット を呼び出すことの確認
- v7fs の組み込み。
まで作業が進んでいる。
- 組み込んでみての感想。
- minix のライブラリを選んだのは正解 かもしれない。なぜなら、
MINIX は、V7 との整合性というものを考慮してくれている。
しかも、ANSI/POSIX API との整合性も かなりあって、この目的には
これ以上のものはないようにさえ思えてきた。
- ちなみに、その他のものを否定しているわけではない、
無数のトレードオフ を考慮してソフトウェアは設計されるわけだから、
条件が変われば、ソフトウェアのあるべき姿も変わる。で、
実際に V7 の FS を組み込むわけだから、MINIX で考慮されている要素が、
非常にありがたい。
- キーワードならべると ruby MINIXのライブラリ UNIX_V7のファイル
システム そしてジャーナリング ... なんか すげえ組合せだなぁ。
- ファイルシステムで v7fs と ジャーナリング って最も離れている組合せ
の1つに思えるし
- MINIX に ruby ってのも 移植されたこともなさそう。
- そして、MINIX と v7fs を実際組み合わせるのも..はじめてかも。
- で、これはいったい何だろう
- ライセンス的には、3 つのライセンス
が混在しているけど、全体としては GPL で問題ない...
- 機能からいえばruby 専用の 仮想マシン ruby VM とか ruby box
とか 言えばいい。
- でも、これそのものを 端的には表していない、ruby-minix-v7jfs ?
スナップショット
- 注意!) 006b-007 で Tiki いれちゃってますが、ライセンスに関する情報を
いれるの忘れてました。配布条件みたしていないはずなので、取扱注意!。
- すいません 次からいれるんでご容赦。-> ksr さん。
- 何が満たされてないんですか?v7ファイルシステムにいれて配布する
場合でも, v7ファイルシステムから取り出せる方法が用意されていればok(ってもしかしてこのコマンドがないのかな?)
- それ以前に ライセンスを 示す ファイルをいれてなかったかと。
- v7ファイルシステムから取り出せる方法自体は、意識していて、
httpd 経由で読めるようにはしています。
- 別の手段も作る予定。
( もし古いバージョンに興味がある人がいれば... 逆にパッチを当ててください。)
@
002 の変更内容
次の課題は、ストリーミング に関する もの
isatty / select / ioctl
をどうするかということであった。
char 型デバイスを作り
/dev/stdin c 7 0
/dev/stdout c 7 1
/dev/stderr c 7 2
/dev/fd/[0..31] c 7 [0..31]
というファイルを作る。
- major は .. なんとなく 7 を使うことに決めた。
- 同時に open できるファイルの最大数は、32 に決めた。(fd_set で制限)
これらは、HOST OS の プロセスとして動かしたとき
fd と 一致するようにする。
そして、ちゃんとファイルシステムを通すようにする。
- cdevsw に関数を登録するということ。登録した関数から HOST OS の
read/write につなげていけば良い。
- stdin/out は 最初から open されているから、oepn/close の メソッドは不要。
- それ以外でサポートするものは、TCP/IP のみだから、open/close の
メソッドは別に用意する。
そうすると、ioctl / select は fd の変換なしで 行える。
- fdset は、32bit しかないから、ちょっと 工夫が必要かも。
isatty については、0 から 2 まで は、tty それ以外は、not tty と
規定する。
このシステム 0 から 2 までは、stdin/stdout/stderr だが、
このシステムにおいては、それは console という位置付け。
- console 以外に セッション という概念は、下位層には存在しないから
問題ない。
@
003の変更内容
ということで 上記について改造した。
- cdevsw から、デバイスドライバとして登録された emread/emwrite が呼ばれると
minor(dev) を引数に stream_read/write を呼び出す。
- stream_read/write では、HOST OS の read/write を minir(dev)
のファイルディスクリプタに対して行う。
- v7fs へデータ移動は、v7_iomove() を呼び出すことで行う。
なんでこんなに面倒なことやっているかというと、name space の問題が
あって、HOST OS の read/write のシンボル使うには、
違う .c の 関数に一回飛ばさないといけない。で、stread_read とか
では、逆に u.u_base とかが見えないから、v7fs の関数のお世話になる。
read/write はとりあえず、iomove ってのがあったから これをちょっと改造して
使っている。
ioctl の方はエントリだけ追加。ioctl の場合は、cmd みないと read/write かも
わからないから頭がいたい。
このベースができたので、fcntl/select/isatty を いれてみる。
- select は、かなりいんちき。fd_set のフォーマットが同じで
サイズだけが違うことを 想定してごまかしている。
- isatty は、上記の通りのもの 0,1 は、tty と決めうち。
- fcntl をまじめに作るつもりはないから、ruby の config.h で
HAVE_FCNTL を undef しておいて、スタブを作る。MINIX 側で ちょっと
使っているところがあったので、それ前提で ごまかす。
次の課題は、どうやって socket を open/close するか。
send/recv は、read/write として、HOST OS にスルーする。
ここで、ext/socket のライブラリを見る。
accept, bind listen send sendto shutdown socket socketpair
getaddrinfo, gethostbyaddr, gethostname, getnameinfo,getperrname
getservbyname, getsockname, getsockopt
setsockopt
結構たくさんあるじゃないか ... そして どこからどこまでがライブラリで
どこからどこまで、システムコールだろう?
全部サポートすべきかどうか とか いろいろ調べないと。
---
Omicron:RubyVM をみると、Ruby にバイトコードを実装しようという
動きがあるらしい。
- そういうのを RubyVM というのなら、これは ruby VM と呼んではダメか。
---
残問題
- Process の扱い
- fork/vork/exec なんて作りようがないから、機能を全部外す。
- でも ひょっとしたら、Ruby Thread で Process を実装できるかも。
- signal
- とりあえず、singal 番号の変換だけをいれる。サポートしない
signal もちゃんと決めないと。
- setjmp/longjmp
- Tiki:cont ベースで考える。将来 VOS レベルで Process をサポート
したら、使いたいし。
- cont は、setjmp のかわりにはならないみたいなんで、別途作成。
だいぶ減った。
@
004の変更内容
とにかくなんか 動いたといえる 最初のバージョンになった。
整理しきれていないが
- setjmp の実装(minlib/ansi/setjmp.c) 。NetBSD/i386 を参考に。
- network 一応 ひとそろえ いれてみた。動作未確認
- README.ja の添付
- stdio/stdout の動作 確認 /dev の自動生成
- インストールディレクトリの変更
- ruby しかないんだから 大胆に /lib に もっていく。
ToDO:
- errno の扱いについて 再考。ミスマッチを起こす可能性あり。
- ちゃんと変換することを考えないといけないかも。
- ちゃんと入っていないものもある。要チェック
- network 動作確認
- network 系の define シンボルの チェック。
- どうも sockopt とか、Linux と BSD は違うみたい。
- ioctl のチェック。何に使っているのか調べる。
- スタートアップをちゃんといれる。/etc/rc.rb か?
- netdb 系ライブラリの 内蔵化
- テストを通す。
- v7fs に入っている ところのインターフェイスを見直す。
- グローバルなシンボルがあるので美しくない。
- あと mmap 使っているところも read/write のみで使えるようにする。
- MIPS への移植 asm 使ってるのは setjmp と netinet/in.h だけのはず。
- JFS 化
- userland
- etc/init.rb を本体にして ... それから スレッドを作ってうごかす
のが良さそう。
- サーバーは、etc/rc.rb から起動される。
- stdin/stdout については、やっぱりスレッドを作っておいて ...
入力を eval ?
うち(RedHat7.2)では動きました。libはパッケージに入ってないのでrubyの方からとってきます。
esehttpd 使うとforkなしでrubyできそうなんですがどうなんだろ。。あ、pollがいるから×か。。
Tiki に限らずおもしろいことに使えそうだけど。。
- お。ユーザが。使ってもらえるのは、嬉しいっす。
- select はいれたんで、poll できるはずなんですが ...
- よくわからないんですが、C でシステム組むよりは、スレッドをサポートした
なんか インタープリタ で 使うのが 吉かなぁ。
- ruby 以外の 言語としては、scheme とか .. 俺言語 ぉ) とか。
- kaffe ? waba ? wabaはインタプリタなかったか。。
- それか Tiki:cont ベースで thread の システム作るか。
- 非同期IOあります?
- ないです。select だけは、ちゃんとサポートする予定なんで
その上で 構築ってことになります。
- ちなみに、シグナルは、送れないし受け取れない。SIGALRM か SIGVTALRM
だけはサポートしたいところですが、ruby はなしでも OK みたい。
- kaffeのスレッドもそうですが、ユーザレベルのスレッドって非同期IO前提なんですよね。 rubyはそのあたりどう取り扱ってるんだろう。。
- えと、eval.c : rb_thread_wait_fd() ってのがあります。
I/O 待ちは、これ登録しておいて ... I/O は、TRAP_BEG ... TRAP_END ではさむ。
(io.c で呼んでいます) ここで、スケジューラが動いて、スケジューラは、登録された wait_fd を集めて
select する。... こういう感じです。
@
005 変更点
- ディストリビューション変更。
- ruby のソース分 は patch にすることにした。
(これで 250K のサイズになった)
- フルパッケージじゃなきゃ面倒。lib.tarも入れてください。
- すいません。ruby の ホームページから 1.6.7 を取って来てください。
ruby の C ソースいれるだけで 250K が 650K になっちゃう。
- make は、ruby-1.6.7 をとなりにおいて make getruby しとけば OK。
- lib は make rootdisk で OK。
- 簡単にできるようにしたので よろしく。
- make rootdisk など 簡単ツールを作成。
- RUBY_BOX.ja (旧 README.ja ) 更新。
@
005a 変更点
- VOS の ファイルディスクリプタと HOST OS の ディスクリプタは
どうしてもずれるので、変換テーブルを作った。
- socket 関係や select も 対処
- v7fs と 上位とのインターフェイスみなおし。
- mmap はオプションにしてread/write を使うようにした。
- v7fs の層で使っている関数もフックできるようにした。
... HOST OS に依存する シンボルを減らすため。
ただし、printf はまだ残っている。
ところで、どうやって スクリプトを動かすのだ ? とか思っていたんだけども。
ファイル名を指定すれば、それに対応した rootfs のファイルシステム
から読んで来て動くのか。...
ようやくruby を動かしてみる。
- sample/cal.rb --- うごくじゃん。
- sample/test.rb --- exec のところまでいくじゃん。
気を良くして
- sample/dualstack-httpd.rb --- だめじゃん。
まず、引っかかったのは、require "socket"
- これは、空の lib/socket.rb を 作っておけば良かった。
で、socket やら select やら signal やらで 引っかかる。
デバッグメッセージやらいれて ようやく accept してくれるところまで来た。
DEBUG_SOCK:select end ret = -1(4)
DEBUG_SOCK: fd_conv (6:3)
DEBUG_SOCK:select start n = (7:4) to = -1
DEBUG_SOCK:select end ret = 1(4)
DEBUG_SOCK:accept => (7:5)(err 0)
accept done 5
socket 0.0.0.0 port 8888 accepted, thread #<Thread:0x2abcca0c>
rb_thread_wait_fd 2147473288
DEBUG_SOCK: fd_conv (6:3)
DEBUG_SOCK:select start n = (7:4) to = -1
DEBUG_SOCK:timer_set => 10
いまの問題は、read しようとしている socket (fd = 5) が
rb_thread_wait_fd にわたったときは、2147473288 という数字に
なってしまっていること。
なにがどうなって、こうrなっちゃうのか .... ひょっとして Floating ?
- 恥ずかしいことに printf に 引数いれてなかった。
@
005b 変更点
- なぁんか バグバグだったので苦労したけども。sample/dualstack-httpd.rb
が動くことを確認。
- gethostbyname とか 組み込んだ。minlib/net
- etc/hosts が読めるのは確認。
- etc/resolv.conf は未確認。
- タイマーを 使えるようにした。現在は off。
- config.h の HAVE_SETITIMER を 1 にすれば、使えますが ...
困らない限り使わない方が良いかも。
@
005c 変更点
- minlib/net でいれたバグの修正 (bcopy -> memcpy でへま)
- CE .. 特に ラジェンダ でこれ動かないかなぁ。
- バックグラウンドにして、localhost で tiki 動けば、
付属のブラウザで 結構 使えないか? と思っているので。
@
006 変更点
- host の dup を使わないようにした。-> vos-conf.h , v7fs/vos_socket.c
- make getruby で lib も取って来ることにした。
- これからは、テスト用に sample 変更する予定。
@
006a 変更点
wwwsrv を動かしてみたが動かないので デバッグ
- md5 がない。=> 組み込むことに。
- inits. に直接いれたら core dump
- ext は、dmyext.c にいれないとマズイということがわかった。
nkf socket も dmyext.c にいれることに。
- md5.c/h 自体は、v7jfs でも使いたいので、minlib へ
- 原因は、socket.c の変更がくさっていたため。
- もういちど ruby のものから 変更したら OK。
- readdir がバグっていたことが判明 -> 修正
@
006b 変更点
- socket.c の config の修正 (gethostname)
- 最低必要なものは、lib/site_ruby にもっていった。
- (その他の)lib と sample を rootdisk から外し、tiki を入れるようにした。
使いかた
- ./ruby-box bin/init.rb で 起動
ToDO
- 漢字ファイル名 の 対応 ( ファイル名の文字数を 60 文字におさえたいので)
@
006c 変更点
- bin/init.rb ( Dehehe server )
のバグ fix 。
@
007 変更点
- NetBSD/i386 でテスト 動かなかった理由は 次の2点
- lseek での off_t が long long だった。(しまった忘れていた)
- struct sockaddr の形式が違うので 変換する必要があった。
- BSD は、sa_len がある。(-> v7fs/vos_socket.c )
- VOS インターフェイスが、sa_len がない。
- このままだと INET6 がサポートできない。( メモ )
- BSD だと 、USE_SETVBUF が ON になっていた。
- ディレクトリ構成変更
- /etc/init.rb がスタートアップ
- tiki.rb は /lib に
- /lib は、必要なものだけ。( 必要になった時点で ruby からもってくる)
- /lib/magic.rb の バグ修正
- tiki の ファイルは、EUC 漢字に変更 ( 60字という制限があるので)
- TODO:
- ファイルシステム が おかしくならないか Tiki で チェック。
- import する方法。ruby-man-*-rd も import したい。
- tar のようなコマンドを ruby で作って オフラインでやる?
- cygwin で動かす?
- mingw で動かす?→ ./Win32APIで動かすには?
- キャッシュサーバの設計 ndbm → ./キャッシュサーバ
- ジャーナリングも進める。
- サーバのマルチスレッド化
- セキュリティの組み込み
@
007a 変更点
(最終更新 Thu Mar 30 19:07:08 2006)