Hatena::ブログ(Diary)

へにゃぺんて@日々勉強のまとめ

2016-02-08

自作OSにファイルシステム・アプリローダを追加しました

f:id:cupnes:20160211221125g:image


システムコールと特権管理などを追加しました - へにゃぺんて@日々勉強のまとめ

こちらの記事の続きで、自作OS(仮称:OS5)の記事です。


自作OSについては、以下のページにこれまでの記事や成果物のまとめを載せています。

http://funlinux.org/os5/


今回は以下の機能を追加しました。


これらの機能追加により、シェル

シェル組み込みコマンドではない文字列を受け付けた時、

その文字列をファイル名とするファイルを開き(システムコール:open)、

実行する(システムコール:exec)」

という挙動を取らせることができるようになりました。

(上のGIFアニメuptimeを実行することで、右上にシステム起動時間が表示されるようになりました。)


例によって、本日時点のソースコードを以下からダウンロードできます。

https://github.com/cupnes/os5/releases/tag/blog-20160208

(masterブランチにタグをつけてpushしたもの)


また、今回から自作OSを構成する

についてソースコードディレクトリを分けました。


現在、それぞれのソースコード行数(アセンブラとCの行数の総和)は以下のとおりです。

ブートローダ253 行
カーネル1966 行
アプリケーション437 行



前回のブログ記事(2015/11/30)から今回の記事までの間の

コミット数は58件でした。


58件のコミットをざっくりと分けると、以下のとおりです。

なお、時系列の並びをなるべく崩さないようにしたかったので、

「メモリ管理」については「ページングに関する機能設定」と「メモリアロケータ追加」の2つのまとまりがあります。


ソースディレクトリ分離


細かな機能変更、バグfix


メモリ管理: ページングに関する機能設定


タスク管理: タスク初期化処理を汎用化

タスク管理: タスク初期化処理を汎用化」から「ファイルシステム: ファイルシステムシステムコール追加」までが

アプリケーションローダ」機能追加のための一連のコミットです。


ここでは、タスク初期化と実行を行う汎用的な関数task_init()を追加し、

shellとuptime初期化にはこの関数を使用するよう修正しています。


なお、x86の「タスク管理機能」を使用しているので、カーネルに近い場所では「タスク」という表現をしていますが、

現状としては、「アプリ」・「タスク」に違いはありません。


また、task_init()という関数名の割りにはタスクの実行(ランキューへの追加)まで行っているので、

この箇所については、関数名と機能が一致していないですね。。。


メモリ管理: メモリアロケータ追加

  • 5253ab4 2016-01-19 doc: memory_map: ヒープ領域を追加
  • 8dd4cee 2016-01-19 mem: mem_alloc()、mem_free()を追加
  • 7bffee3 2016-01-19 mem: ヒープ領域のPTE追加
  • a716255 2016-01-24 task: task_init()をmem_alloc()に対応
  • 06d0e0c 2016-01-24 doc: アプリPD/PTを動的に確保するようにしたのでドキュメント修正
  • 72079e2 2016-01-24 doc: メモリマップのVAのタスクスタック領域の説明を修正

ここでは、ヒープ領域の作成と、メモリアロケータの追加を行っています。


ヒープ領域は、現状、物理アドレス

0x0009 5000 〜 0x0009 ffff

の(たった)44KBです。

なお、この空間はカーネル空間内であり、物理アドレス=仮想アドレスでマッピングしています。


また、現状のメモリアロケータmem_alloc()は、固定長4KBをヒープ領域から確保し、

確保した領域の先頭のアドレス(物理アドレスであり、仮想アドレスでもある)を返します。


ファイルシステム: ファイルシステムシステムコール追加

ここでは、ファイルシステムと、ファイルを扱うための「open」と「exec」のシステムコールを追加しています。


ファイルシステム」といっても、現状でファイルを定義しているバイナリ的ルールは以下の簡単なものです。

  • ファイルサイズは固定長4KB
  • ファイルの先頭32バイトがヘッダ、それ以降がデータ
    • ヘッダの内容はファイル名のみ
  • ファイルシステムとしては、「コントロールブロック(4KB)、ファイル、ファイル...」というバイナリの並び
    • コントロールブロックに設定する内容は、現状は「ファイル数」のみ

追加したシステムコールについては以下のとおりです。

open引数でファイル名(文字列)を受け取り、struct fileのポインタを返す
exec引数でstruct fileのポインタを受け取り、受け取ったファイルを実行ファイルとして実行する

struct fileは、現状は以下のような簡単な定義です。

struct list {
	struct list *next;
	struct list *prev;
};

struct file {
	struct list lst;
	char *name;
	void *data_base_addr;
};

struct fileはファイルシステム上のファイルについて、

以下の2つのアドレスを管理しています。

  • char *name: ファイル名の先頭アドレス
  • void *data_base_addr: データの先頭アドレス

execでは、task_init()にstruct fileのdata_base_addrを渡すことで、

タスク初期化と実行を行っています。


なお、LinuxではexecはGNU Cライブラリが提供するAPIですね。

「既存のものに合わせる」という気持ちで作っているわけではありませんが、

システムコールの粒度がまちまち」なのはかねてからの問題点なので、

システムコールについては、いずれ設計し直そうかと考えています。


リリース前コード整理

以前はリリース前に作業ブランチ内でコードを整えてからmasterブランチへマージしていたのですが、

最近は面倒さを感じてしまい、あまりツリーを整形せずにmasterへマージしてしまっています。。。


この記事の変更履歴

02/11 23時実行している様子(GIFアニメ)追加、コミット一覧を分類分けし、コメントを追加

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証