MochiOS@仮想ファイルシステムの作成part6
前提知識無しで作るなんちゃって仮想ファイルシステムpart6。
開発日記です。独り言です。
これまでのあらすじ
part | 内容 |
---|---|
0 | 仮想ファイルシステムを作りたい宣言をする。 |
1 | ざっくり仮想ファイルシステムの機能を決める。 が、機能呼出し先の仮想ファイルシステムのタスクIDをどう取得するかという問題に気付く。 |
2 | カーネルにタスク名登録機能を実装した。 これでタスク名からタスクIDを取得する事が出来る様になるハズ、なので試したいが試す方法が無い事に気付き、ログ出力タスクの開発を宣言する。 |
3 | ログ出力の為に使うvsnprintf()の仕様を調べる。 |
4 | ログ出力タスクを開発してタスク名からタスクIDの取得機能が正しく動いている事が確認できた。 |
5 | mount()機能を実装した。たぶんできてる。 |
openの仕様を考える
とりあえず、必要なのはパスよね。
あと、読書きフラグ。。。あるけど、今は忘れよ、うん。後ね後。
で、openしたらファイルディスクリプタ(FD)を払い出す。大体、FDはプロセス毎に1からなので、プロセス毎にFDを払い出す事にする。
あー、MochiKernelのメッセージパッシングはメッセージ送信元タスクIDしか取れないので、プロセスIDを取れるようにしないとだ。。
(どこかでMochiKernelの概要を書かねばと思っているのだけど、ここでさらっとご紹介。MochiKernelではカーネル上の1つのコンテキストをタスクという名前で扱う。つまるところ、タスクはスレッドと同じ意味。プロセスは複数のスレッド(タスク)から構成されるのは普通と一緒。スレッドIDはプロセス内ローカル値だがタスクIDはグローバル値という違いがある)
mountされたファイルをopenした時、そのファイルをmountしたドライバはopenされたタイミングで何か初期化をしたいかもしれない。
なので、openメッセージを横流しする。横流しといってもメッセージはそのままでなくて、新しい識別子を切ることとしよう。
パラメータはopenしてきたPIDと払い出されたFDを組み合わせた値とパスとしとく。
以下、メッセージ仕様。
■ open要求メッセージ
offset | size | 内容 | 値 | 意味 |
---|---|---|---|---|
0x00 | 4 | 機能ID | 0x0000_0001 | open |
0x04 | 4 | タイプ(要求/応答) | 0x0000_0000 | 要求 |
0x08 | 4 | ローカルFD※ | 任意 | - |
0x08 | 1024 | 絶対パス(\0含む) | 任意 | - |
■ open応答メッセージ
offset | size | 内容 | 値 | 意味 |
---|---|---|---|---|
0x00 | 4 | 機能ID | 0x0000_0001 | open |
0x04 | 4 | タイプ(要求/応答) | 0x0000_0001 | 応答 |
0x08 | 4 | 処理結果 | 0x0000_0000 0x0000_0001 |
成功 失敗 |
0x0C | 4 | グローバルFD※ | 任意 | - |
■ vfsOpen要求メッセージ
offset | size | 内容 | 値 | 意味 |
---|---|---|---|---|
0x00 | 4 | 機能ID | 0x0000_0002 | vfsOpen |
0x04 | 4 | タイプ(要求/応答) | 0x0000_0000 | 要求 |
0x08 | 4 | PID | 任意 | - |
0x0c | 4 | グローバルFD※ | 任意 | - |
0x10 | 1024 | 絶対パス(\0含む) | 任意 | - |
■ vfsOpen応答メッセージ
offset | size | 内容 | 値 | 意味 |
---|---|---|---|---|
0x00 | 4 | 機能ID | 0x0000_0002 | vfsOpen |
0x04 | 4 | タイプ(要求/応答) | 0x0000_0001 | 応答 |
0x08 | 4 | 処理結果 | 0x0000_0000 0x0000_0001 |
成功 失敗 |
※ 詳細は下記の「FD(ファイルディスクリプタ)の実装方法を考える」を参照
制御方法を考える
なんだかちょっとしたシーケンスが出来てしまったので、状態遷移表を用いた制御を行う。
その為に、MLib(自作の便利ライブラリ)に状態遷移管理機能を実装してそれを使うことにする。
詳細は割愛。ライブラリはここ(https://github.com/MasterMochi/MLib/commit/4135b1b0a1cd7d0617405e38e9b997b3bc3bf7fb)でコミットした。
状態遷移はこんな感じ。上のシーケンスから状態遷移記述に落としただけ。
状態 | 初期状態 | vfsOpen待ち | |
---|---|---|---|
イベント | # | 01 | 02 |
open要求 | 01 | Task0101 →2 |
- |
vfsOpen応答 | 02 | - | Task0202 →1 |
タスク概要はこんな感じ。エラー処理やその時の遷移はここでは割愛。
タスク名 | 処理概要 |
---|---|
Task0101 | 1. FD払い出し 2. mountタスクへvfsOpen要求を送信 |
Task0202 | 1. oepn要求元タスクへopen応答を送信 |
FD(ファイルディスクリプタ)の実装方法を考える
ファイルディスクリプタって、各プロセス毎に一意の値じゃない?単純に考えると、仮想ファイルサーバは「プロセス(PID)」毎にFDテーブルを持たなきゃならない。PIDをキーにFDテーブルを持たなきゃならないわけだ。
PIDをインデックスとしたテーブルにすれば簡単にできそうだけど、PID分を全部用意しとかなきゃならないってのはなかなかメモリ容量を使いそう。
なので、各プロセス用のFDテーブルと仮想ファイルサーバ用のFDテーブルを持つこととする。
仮想ファイルサーバはプロセス毎にFDを管理するんじゃなくて、単純に一個のFDテーブルを持つ様にする。そうすればFDの払い出しは、0から順に空いているFD使えばいいので難しい事を考える必要がなくなる。
各プロセスは自分用のFDテーブルを管理しておいて、その用途は仮想ファイルサーバのFDを変換するだけにしておく。そうすれば、0からの各プロセス毎に一意なFDを使用できる。
ローカルFDテーブルの操作は、仮想ファイルサーバが提供するライブラリでやってしまえば、こんな仕組みはユーザに隠蔽することができる。
便宜上、各プロセス毎のFDをローカルFD、仮想ファイルサーバのFDをグローバルFDなんて名前にしておく。
ユーザタスクがローカルFD=0のreadをしたければ、自身のFDテーブルを用いてローカルFDからグローバルFDに変換して、仮想ファイルサーバにグローバルFD=190のreadを出せばいい。
実装してみた
かなりやっつけだけど実装した。
ttyサーバ君を作って、シリアルポートドライバ君がMountする「/serial」を二回連続でOpenさせています。詳細な説明は割愛!
コメント
コメントを投稿