トップページ⇒tech
982コメント407KB

OSをつくろうpart4

■ このスレッドは過去ログ倉庫に格納されています
0001ひげぽんNGNG
独自にOSを作っているまたは、作ろうとしている人たちのための
スレッドになればと思います。

前々スレッド
OSをつくろうpart2
http://pc3.2ch.net/test/read.cgi/tech/1024411711/

前スレッド
OSをつくろうpart3
http://pc3.2ch.net/test/read.cgi/tech/1027080631/
0083 ◆sVYyxB.646 NGNG
trの参照先のTSSが32bitならcr3があるよ。
ldtrは使ってないんで覚えてないがあるはず。。。
0084デフォルトの名無しさんNGNG
ぶー何処いった?
0085デフォルトの名無しさんNGNG
>75 じゃないから、違っているかもしれないけど...

>>76
>  一度聞いてみたいアイデアなような気がしますので、
> ここでおっしゃる「メモリハンドラ」というものの詳細や、この方式での
> 具体的なファイルアクセスの手順を聞ければ幸いです。

メモリハンドラは、単なるポインタでいいと思う。C で書けば...

File F = fopen("test.txt", "r");
char *p = fread(F, 100);

とかすれば、OS が 100バイトの領域を確保して、そこにデータを読み込んでから、そのアドレスを返してくれるという感じかと...。
C だと、free(p) とかしないとダメだけど、Java とかならそれも必要ないだろうし。これで、fread() が間違ったアドレスにデータを書き込んでしまうことは防げるでしょ ?

> アプリ側が不法なバッファアドレスを指定した場合、fread() API 内部で、
> スーパーバイザ権限で「身代わりアクセス」してしまうことを指摘されて
> いるのですね。

今時、そんなタコな OS は無いでしょう。当然...

> ご存知かもしれませんが、これを防ぐ手は一応存在していて、API の処理冒頭
> で、メモリが合法かどうかをソフト的にチェックするルーチンをかませば、
> 跳ね返せます。

ぐらいはやってはず。そうではなく、fread() に間違ったアドレス指定して、自分で使う領域を壊したりするのを防ぎたいんだと思う。最近のコンピュータウィルスで使われるバッファーオーバーランとかを避けたいだけじゃないでしょうか。

> CPUの保護機能だけでは無理で、通常のCPU命令を用いてページテーブルや
> セグメントの属性やフラグ類をチェックしなければならないので、確かに
> 煩わしいのですが。

プロセサによっては、保護機能を使えるのもありますよ。(68K の moves とかね。)
0086ひげぽんNGNG
>>82
新たにTSSを追加をする場合
dt分のスペースをお尻に確保しなければならないことに気がつきました。
secondboot.asmで仮に設定しておいて
C++に移行してからもう一度設定しなおしたほうがいいのでしょうか。
うーん勉強が足りません。
0087 ◆sVYyxB.646 NGNG
バッファを固定にしてユーザーモードからバッファを転送すれば何も考えなくても保護機能が動きます。(*゚ー゚)
少し無駄ですが、、、
0088ひげぽんNGNG
今日本屋で久しぶりに詳解Linuxカーネル
を立ち読みしてみました。
初めて読んだときはさっぱり分からなかったですが
難易度的にちょうど良く、自分の知りたいことが
たくさん書いてあるので欲しい。。。でも高い。
http://www.amazon.co.jp/exec/obidos/tg/detail/-/books/4873110483/reviews/ref%3Ded%5Fer%5Fdp%5F1%5F1/249-3833329-4800325

どこかの古本屋に売ってないかな・・・
図書館でも良いな。
0089デフォルトの名無しさんNGNG
>>88
あれってソースがただ印刷されて、コメントが日本語訳されてるだけじゃなかった?
役に立つような解説はなかったような。
カーネルをダウンロードして読むってのじゃだめなのかな?
009089NGNG
>>89
こっちと勘違いしてた。上のは見たことない。
http://www.amazon.co.jp/exec/obidos/ASIN/4797820063/qid=1038350048/sr=1-6/ref=sr_1_2_6/250-3155597-6663410
0091デフォルトの名無しさんNGNG
BSDだけどこれがお勧め
http://www.ascii.co.jp/books/detail/4-7561/4-7561-3313-4.html
0092LightCone ◆sSJBc30S5w NGNG
>>88
詳細Linuxカーネル 5800円:高いですが参考になりそうなので一ヶ月ほど前に購入。
Linux2.4 インターナル 3200円:内容は上記より少なめですが、短いので読みやすいかも。

OS そのものとは関係有りませんが、SHELL プログラミングでお勧めなのが、

SOFT BANK「入門UNIXシェルプログラミング」Bruce Blinn著 山下 哲典 訳
0093LightCone ◆sSJBc30S5w NGNG
>>87
 (恐らく)転送時間が1レベル増えるであろうことを気にしないなら単純でよさそうな方法
ですね。

 セクタの内容をキャッシュするセクタバッファの他に、ファイルごとに
キャッシュするファイルバッファというものがあるそうですが、後者を
うまく使えばバッファの転送時間もかなり減らせるかもしれませんが。
0094LightCone ◆sSJBc30S5w NGNG
>>85

>そうではなく、fread() に間違ったアドレス指定して、自分で使う領域を
>壊したりするのを防ぎたいんだと思う。最近のコンピュータウィルスで使わ
>れるバッファーオーバーランとかを避けたいだけじゃないでしょうか。

fread()の場合は取得サイズをアプリ側が指定するので特に問題は
ないと思うのですが、OS側から可変長のデータを取得する時には
その問題を感じます。

 例えば、何らかの文字列データ(例では他のタスクの名称)をOSから
取得したい時、APIによっては次のような形式を用いますが、ちょっと問題
を感じます。

<<続く>>
0095LightCone ◆sSJBc30S5w NGNG
<#94の続き>

//int GetTaskName(HTASK hTask, char *pFilename);

void PutTaskName(HTASK hTask)
{
int size = GetTaskName(hTask, NULL);
if (size == 0) {
put_err("hTask is wrong?");
}
char *pName = malloc(size + 1);
if (ptr == NULL) {
put_err("Memory shortage!!");
}
else {
GetTaskName(hTask, pName);
printf("The name of task(%08X) is %s\n", hTask, pName);
free(pName);
}
}

一言メモ:
 GetTaskName(hTask,pName)は、pName にNULLを指定すると、
受け取るタスク名の長さを返す。通常、二度呼び出して、pNameのバッファ
をアプリ側が確保する。
0096LightCone ◆sSJBc30S5w NGNG
<#95の続き>

 ここで問題となるのは、hTaskの名前が二度のGetTaskName()呼び出しの
間に変化する可能性です。起動後のタスクではタスク名が絶対変化しないよう
なシステムだと問題なくても、SetTaskName()のようなAPIが用意されている
場合に問題が起きます。
 もし、今の例の様に、GetTaskName()を二度呼ぶような仕様だと、
何らかのロック処理が必要になるはずですが、現実のよく知られたOSでは
私の知る限りそれが出来ないケースがあります。


このような場合には、

const char *GetTaskName2(void);

のようなAPIの方が簡単では有ると思います。ただし、これにも短所が
あります。空システムメモリ空間が圧迫される可能性があることです。
0097ひげぽんNGNG
>>90
>こっちと勘違いしてた。上のは見たことない。
おお、こんなのもあるんですね。
指定されたURLのレビューを見ると詳解の後に
読むことを薦めていますね。

>>92 LightConeさん
>詳細Linuxカーネル 5800円:高いですが参考になりそうなので一ヶ月ほど前に購入。
えっと、だいぶ背中を押されました(笑)
たぶん買います、いやきっと買うでしょう。

>OS そのものとは関係有りませんが、SHELL プログラミングでお勧めなのが、
>SOFT BANK「入門UNIXシェルプログラミング」Bruce Blinn著 山下 哲典 訳
これ会社の同僚が持っていた気がします。仕事でcshを使うので
ちょっと見せてもらってみます。




0098ひげぽんNGNG
>>91
>BSDだけどこれがお勧め
>http://www.ascii.co.jp/books/detail/4-7561/4-7561-3313-4.html
これ安いですねぇ。
内容の難易度的にはどうなんでしょうか。
今度本屋で探してみます。
0099LightCone ◆sSJBc30S5w NGNG
>>97
 OS作りでは、実はコマンドラインSHELLがかなり重要なのではないかと
思えてきた今日この頃です。

 UNIX好きの人でも、CYGWIN環境があれば満足してしまう人も多いようで、
一番大きな理由が、UNIX互換のシェルが使えるからだそうです。

 UNIXは、カーネルも優れた側面を持っていると思いますが、
シェル、特にシェルスクリプトの機能(その一行切り出しとしての
コマンドライン解釈部)が強力なことも見逃せないと思います。


 それにしても UNIX のシェルはいいですね。
0100デフォルトの名無しさんNGNG
割込み、すいません。

C言語でモニタとコルーチンを実装(ライブラリを作成)したいのですが、
WEBで探してもなかなか合った文献がみつかりません。

どなたか、実装方法教えてくれませんか?
WEBや書籍でもいいのでお願いします。


*Modula-2からCへの移植を行うため、モニタとコルーチン機能がCで必要になりまし
た。
0101デフォルトの名無しさんNGNG
>>98
中級ぐらいと思う。
メインはデバドラとブートコード。
「詳解Linuxカーネル」はあまりLinux板では評判よくなかった。
自分ももってるけどLinuxOSの概念の説明で
具体的なコードが書かれてないからすきじゃない
0102LightCone ◆sSJBc30S5w NGNG
>>101
良いことを聞きました。
「詳細Linuxカーネル」は訳本のせいもあるのか文章量が多めで、途中から
斜め読みするには辛いものを感じていたのですが、よく考えるとこの本は、
プログラミング言語で書かれた部分は、構造体定義のみで、他は
ほぼ全て自然言語で書かれています。プログラミング言語も適度に有った
方が分かりやすいのかもしれませんね。今度ご紹介の本を見てみたいです。
0103デフォルトの名無しさんNGNG
Linuxのソースを参考にしながら開発するとmonaはGPLになると思われるがよいか?
0104LightCone ◆sSJBc30S5w NGNG
>>103
ソースをコピーしない限りは、恐らく大丈夫かと。
特許が採られてない限り、技術の内容を真似ること自体は自由では?

そうでないと、知らず知らずにGPLのソースを偶然目に触れてしまって、
いつのまにか真似てしまった場合などにおかしなことになるかと。
0105デフォルトの名無しさんNGNG
>>103
monaはGPLだったと思うけど。
0106デフォルトの名無しさんNGNG
>>104
> ソースをコピーしない限りは、恐らく大丈夫かと。
これはGNUプロジェクトでは"駄目orグレー"だと認識されています。そのため
GNU Coding Standardには"他の実装(Implementation)"を見ないことを推奨し
ていて、見てしまった場合は別の実装を考えるように推奨しています。
日本の法律ではコピーしなければ大丈夫だったと思うけど、海外から訴えられ
たらたまらんですな。
0107ひげぽんNGNG
>中級ぐらいと思う。
>メインはデバドラとブートコード。
ありがとうございます。
なるほど、詳解Linuxカーネルはほとんどソースがないということであれば
立ち読み程度にしておこうかな・・・

ご存知かもしれませんがこんなのを見つけました。
http://lkh.linux.or.jp/24kernel/source/html4/boot.html
0108ひげぽんNGNG
>>103
>>104
>>105
>Linuxのソースを参考にしながら開発するとmonaはGPLになると思われるがよいか?
一応monaはGPLなので問題ないかと。

LightConeさんの仰るとおり
>ソースをコピーしない限りは、恐らく大丈夫かと。

という認識で私もやっています。とおもったら・・・

>これはGNUプロジェクトでは"駄目orグレー"だと認識されています。そのため
>GNU Coding Standardには"他の実装(Implementation)"を見ないことを推奨し
そうなんですか・・・
いろいろなフリーのOSのソースを見て勉強してしまっているんですが・・・

いちおう参考にすることはあっても、コピーはしないようにしています。
自分のためになりませんし・・・
0109LightCone ◆sSJBc30S5w NGNG
>>106
>> ソースをコピーしない限りは、恐らく大丈夫かと。
>これはGNUプロジェクトでは"駄目orグレー"だと認識されています。そのため
>GNU Coding Standardには"他の実装(Implementation)"を見ないことを推奨し
>ていて、見てしまった場合は別の実装を考えるように推奨しています。

こわばら こわばら。

「見てない」って言い張るだけで回避可能とかではない?
0110FreeDOS教徒NGNG
GNU GPLにそこらへんの基準は載ってないのね。

‥‥ていうか、コピペまがいの行為はしないから、大丈夫でしょ?
実装が似通う例なんて腐るほどあるし。
0111LightCone ◆sSJBc30S5w NGNG
>>110
>‥‥ていうか、コピペまがいの行為はしないから、大丈夫でしょ?
してないつもりです。

>実装が似通う例なんて腐るほどあるし。
そうですよね、、、。

 もし、GPLのソースを見て勉強しただけで、自分のプログラムのライセンスまで
制約されると言うのならば、かなり無理が有りませんか。
0112デフォルトの名無しさんNGNG
こわばらage
0113デフォルトの名無しさんNGNG
>>110
> GNU GPLにそこらへんの基準は載ってないのね。
いや、GNUの場合はUNIXの著作権を侵害しないように気を付けろってことだし、
"よりCoolな実装"を目指せば、同じにはならないでしょ。
似たものになっても、より優れていれば大丈夫。
当然、悪くても可 > オレモナー
0114デフォルトの名無しさんNGNG
>>111
そう言ってるともとれるのがGPLです。
0115デフォルトの名無しさんNGNG
一応参考までに
ttp://www.sra.co.jp/wingnut/standards/standards-ja_2.html
0116デフォルトの名無しさんNGNG
>>96
> ここで問題となるのは、hTaskの名前が二度のGetTaskName()呼び出しの
> 間に変化する可能性です。

普通、ユーザーが確保した領域に書き込む API は、サイズを渡すように
なっていて、気の聞いた API/OS なら、入りきらない時は必要なサイズを
返すようになってたりすると思うけど ? (例えば、Win32 の
GetWindowsDirectory() とか。)

悪いけど、もう少し他の OS の勉強した方がいいと思うよ。

> 何らかのロック処理が必要になるはずですが、

そんなことしたら、わざとロックかけて SetTaskName() しようとしている
タスクの実行を邪魔することができちゃうよ。(バッファを別に持つとかし
て、回避できるだろうけど、複雑になるしね。)

> ただし、これにも短所があります。空システムメモリ空間が圧迫される
> 可能性があることです。

どう言うこと ?
0117デフォルトの名無しさんNGNG
おそらく詳解Linuxカーネル。でも部分的にしかないみたい
http://aglaia.c.u-tokyo.ac.jp/~yamamoto/UNIX/kernel/
http://www.graco.c.u-tokyo.ac.jp/~kamina/jugyo/kernel/chap4_half/
0118デフォルトの名無しさんNGNG
>>116
きっとタスク名をシステムメモリ空間に確保したバッファに書き込んでユーザープロセスに返すのでしょう。
どうやって読み出すのかは知りませんが。
0119LightCone ◆sSJBc30S5w NGNG
>>116
>普通、ユーザーが確保した領域に書き込む API は、サイズを渡すように
>なっていて、気の聞いた API/OS なら、入りきらない時は必要なサイズを
>返すようになってたりすると思うけど ? (例えば、Win32 の
>GetWindowsDirectory() とか。)

 そういうAPI仕様は知ってはいましたが、#94-#96では言及できてません
でした。すみません。

UINT GetWindowsDirectory(
LPTSTR lpBuffer, // Windows ディレクトリが格納されるバッファ
UINT uSize // ディレクトリバッファのサイズ
);



その方法では結局、実際に文字列を取得する際のサイズが前回取得した
文字列のサイズ以下になるまで繰り返しが必要になり、単に文字列を
取得したいたびにそのようなループを書く必要があることになる
わけですよね。

結局#96での結論と同じく、

const char *GetTaskName2(HTASK hTask);

というような API 仕様だと便利だと思うんです。
0120LightCone ◆sSJBc30S5w NGNG
>>118
>きっとタスク名をシステムメモリ空間に確保したバッファに書き込んで
>ユーザープロセスに返すのでしょう。
その通りです。 ただし、API呼び出し時に書き込むのではなく、元々存在
している場合の方が多いかもしれませんが。

>どうやって読み出すのかは知りませんが。
共通空間でも、ユーザーが読めるようにすることは可能です(書けるように
することも可能ですが)。
メモリ空間がタスク固有空間か共通空間かと、アクセス禁止属性は独立
して扱えますので。

一応、NWSOS でも、
const char *GetTaskFilename( HTASK hTask );
というAPIにしてみています。

http://homepage2.nifty.com/nowsmart/nwsosapi.htm#NWSOS API
0121デフォルトの名無しさんNGNG
GC完備すれば「バッファサイズ」なんて死語になるのに。。。
0122デフォルトの名無しさんNGNG
『GC』て何?
0123デフォルトの名無しさんNGNG
>>122
…。・・・。・・・。
0124LightCone ◆sSJBc30S5w NGNG
>>122
文脈から、ガーベッジ・コレクションの略だと思います。
0125デフォルトの名無しさんNGNG
>>124
ありがとう。
0126デフォルトの名無しさんNGNG
理解が間違っているかもしれませんが、
LightConeさんはカーネル内部にTASKのデータを持たせておいて、
外部からはHTASKで操作し、
>>116さんはTASKのデータをTASKに持たせておいて、
カーネルではTASKのIDとかで識別できる程度にしておいて、
カーネルからのメッセージでTASKが動作するといったイメージでしょうか?
# 必要なデータはTASK側で確保するってこと。
そうだとすると、マイクロカーネルを目指すmonaとしては後者の方が
有利だと思うのですが、何か間違ってます?
0127ひげぽんNGNG
セグメントディスクリプタテーブルについて
どなたかアドバイスください。
長文になることをご了承くださいm(__)m

Monaではsecondboot.asmにて以下の手順で
ディスクリプタテーブルの設定を行っています。

(1)lgdtにてロード(エントリー数は4)
(2)プロテクトモードに移行
(3)far jump 0x08へ
(4)レジスタの設定
(5)オフセットアドレス決めうちでCで実装したコードへjump

ここまで前提です。

最近タスク管理を実装しようと思い勉強していたのですが
基本的にはタスクひとつにつきTSSが必要っぽいことが分かりました。
エントリー数が足りない・・・
0128ひげぽんNGNG
そこでアドバイスいただきたいです。

(A)セグメントのエントリ数はどのくらいが適当か?

(B)固定or動的にエントリ数を増やせるような仕組み
   どちらが一般的でしょうか?
   
   もし固定であればsecondboot.asmにて
   エントリー数分メモリを確保しようと思っています。

(C)動的な場合
   エントリー数が増えた場合、連続領域にメモリを確保し
   lgdtをしなおさなければならないと考えていますが
   lgdtを複数回行うのはありでしょうか。
   
(D)secondboot.asmにてlgdtを行わず
   プロテクトモード移行後に、Cで実装している部分
   monaKernel.cppでlgdtを行うことは可能か?

   「はじめてよむ486」にはプロテクトモード移行後
    セグメントレジスタにセレクタ値をロードするまでは
    リアルモードのセグメント配置を引きずるとあるのですが・・・

   ※これが可能であれば、エントリ数を増やすときに
     secondboot.binのサイズを固定のままでよいかと考えています。

(C)(D)は実際に自分で、いろいろやってみているのですが
現時点では成功していません。
0129LightCone ◆sSJBc30S5w NGNG
>>126
>TASKのデータをTASKに持たせておいて、
>カーネルではTASKのIDとかで識別できる程度にしておいて、
>カーネルからのメッセージでTASKが動作するといったイメージでしょうか?

「メッセージでTASKが動作する」と言う意味がよく分からないのですが、
TASKならではの情報は、なるべくそのTASK独自のメモリ空間に入れるべ
きだということは同感です。

 しかし、共通空間に入れたほうが簡便になる場合もあるので、事情に
よりけりだと思います。


 他のタスク固有の情報を、「運んでくる」と言うのは結構メンドクさく
感じます。多分、

1. ページングで「窓」をあける。
2. 一旦、ソース側のタスクにいる時に共通空間にコピー、デスト側に来た時に
  共通空間からコピー

みたいな感じになるのでしょうか。
0130LightCone ◆sSJBc30S5w NGNG
>>127
>基本的にはタスクひとつにつきTSSが必要っぽいことが分かりました。
>エントリー数が足りない・・・

基本的にはそうで、最新版のNWSOSでは、タスクごとにTSSを用意して
いるのですが、同一タスクのスレッド(軽量タスク)では同じTSSを指
しています。

しかし、Linux 2.4 では、TSSはひとつだそうです。

ちなみに、タスクゲートは、Linuxでも用いていないそうです(NWSOSでも)。
0131超先生@OS板 ◆leaf/RYZgY NGNG
  ∧_∧
< `ー´>y-~~~
個人的にはTSSを使うのはあまり好きじゃないな・・・。
コンテキスト保存用のブロックが無駄に大きすぎる。
nest-taskができるのは便利なんだが。
0132LightCone ◆sSJBc30S5w NGNG
>>128
 調べて見たところ、NWSOSでは、lgdt は、初期化時に一回だけ、
8192 個のリミットで確保していました(TSS領域自体は、動的に
確保しています。)。

 多分、lgdtは何度でも行えると思うんですが、その際必要となるのが、
「連続した”物理”アドレス」ですので、動的に伸張していく際、
必要なサイズの「連続した物理アドレス」が空いてない場合は、
どこかにページングされているものから集めてくる処理が必要にな
ると思います。
0133ひげぽんNGNG
LightConeさん こんばんは
>基本的にはそうで、最新版のNWSOSでは、タスクごとにTSSを用意して
>いるのですが、同一タスクのスレッド(軽量タスク)では同じTSSを指
>しています。

なるほど、スレッドは、メモリ空間?を共有している特殊なタスクということですね。
ということは、エントリ数は512とか256位必要な気がしますね。

>しかし、Linux 2.4 では、TSSはひとつだそうです。
どういう方法をとっているのでしょうか。なぞです。
でも結局はTSSに相当するものはどこかに持っていないとおかしいですよね。
0134ひげぽんNGNG
>>131 超先生@OS板さん おひさしぶりです。
>個人的にはTSSを使うのはあまり好きじゃないな・・・。
>コンテキスト保存用のブロックが無駄に大きすぎる。
勉強不足なのですがTSSの使用はmustではないのでしょうか?
segment typeはTSSでなくても、結局は使用するセグメントを
ディスクリプタテーブルに登録しなければならない気がするのですが
激しく勘違いしているかもしれません。
0135LightCone ◆sSJBc30S5w NGNG
>>131
超先生、コメント有難うございます。

Linuxの参考書を見るべきかもしれませんが、
TSSを固定するとなると、I/O 許可ビットマップは利用しないという
ことなんでしょうか。in/out 命令は全部例外を起こさせて
エミュレートするか、I/O用システムコールを利用?
0136ひげぽんNGNG
LightConeさん
> 調べて見たところ、NWSOSでは、lgdt は、初期化時に一回だけ、
>8192 個のリミットで確保していました(TSS領域自体は、動的に
>確保しています。)。

わざわざ調べていただいて恐縮です。
なるほどNWSOSでは最初に一回多めにとっているのですね。
結局は、この方法がベストな気がします。

>多分、lgdtは何度でも行えると思うんですが、その際必要となるのが、
>「連続した”物理”アドレス」ですので、動的に伸張していく際、
>必要なサイズの「連続した物理アドレス」が空いてない場合は、
>どこかにページングされているものから集めてくる処理が必要にな
>ると思います。
おっしゃるとおりですね。
動的拡張は、ちょっと面倒であまりメリットがないかもしれません。
結局は初期サイズで余分に取っておくでしょうし・・・

0137LightCone ◆sSJBc30S5w NGNG
 レベル遷移時に、どうしても、TSSの内側レベルのスタックポインタ
(SS0:ESP0, SS1:ESP1, SS2:ESP2) がCPUによって自動参照されて
しまうはずなので、TSSの切り替えをしない場合は、そこをタスク
スイッチ時に書き換える必要がありますよね。違っていたらNWSOS
では無駄なことをしていることになりますが、それをしないと確実に
暴走するので間違いないと思います。

 最新版のNWSOSでは、スレッドを切り替える際は、TSSを変更せずに、
そこだけを書き換えてます。

 他の項目は、タスクゲートなどを使わないなら書かなくていいん
はずですよね。TSSの CR3,LDTR などもどうでもいいんですよね。

 TSSの「レジスタセーブ領域」は、自信を持って書き換える必要がないと
言えます。
 なぜなら、最新版NWSOSでも利用せずに、独自の構造体に入れてますので。
0138超先生@OS板 ◆leaf/RYZgY NGNG
>>134
使わないというか、TSS一つを共有と。

>TSSを固定するとなると、I/O 許可ビットマップは利用しないという
>ことなんでしょうか。in/out 命令は全部例外を起こさせて
>エミュレートするか、I/O用システムコールを利用?

そもそもi386以外ではI/O access mapのようなものはないですからね。
移植性を考慮すると、subsystemプロセスに限定しても、
直接ユーザーランドからI/O命令を発行するような実装は綺麗でないです。
0139LightCone ◆sSJBc30S5w NGNG
>>134
>勉強不足なのですがTSSの使用はmustではないのでしょうか?

恐らくその通りで、Linux でも、TSSは、一つだけは使っています。

超先生がおっしゃっているのは、TSSを複数使うかどうかだと思います。
#135 の私の質問も、その意味で書いたつもりです。
0140LightCone ◆sSJBc30S5w NGNG
>>138
>そもそもi386以外ではI/O access mapのようなものはないですからね。
なるほど。

ご返答有難うございます。
0141LightCone ◆sSJBc30S5w NGNG
やはり、「I/O許可ビットマップ」は使わない、ということなんですね。
 Linuxが、in/out 命令をユーザーレベルで直接使わずに、関数コール
しているのかが今分かった気がします。

やはり、TSSは、一つだけ固定的に持つのが一番賢そうですね。

そして、タスクスイッチ時は、「TSSの内側スタックポインタ」だけを
書き換えればいいわけですよね?
0142ひげぽんNGNG
一人レベルが低くて申し訳ないのですが

>やはり、TSSは、一つだけ固定的に持つのが一番賢そうですね。
となると、TSSをタスクの数だけ用意するのは
何もメリットがないのでしょうか?

0143ひげぽんNGNG
TSSディスクリプタを一つだけ固定で持つということすよね。

そうすればセグメント間ジャンプのときに
セグメントタイプがTSSであることをCPUが検知してくれて
TSSの内容を参照し、セグメントを切り替えてくれる。

OS側では、タスク切り替えの前にTSSディスクリプタが持つ
TSSのアドレスに切り替えたいタスクのTSS構造体のアドレスを設定する。

うーんなんか間違っている気がします・・・
0144LightCone ◆sSJBc30S5w NGNG
>>142
>となると、TSSをタスクの数だけ用意するのは
>何もメリットがないのでしょうか?

複数使うメリット:

1. タスクゲートなどを使ったCPUネイティブなタスクスイッチが行える。
2. 割り込みなどをタスクゲートで行える。その際「ネスト」できるハズ。
3. TSSの「内側レベルのスタックポインタ」を頻繁に書き換えないで済む。
4. I/O 許可ビットマップを(一々コピーすることなく)利用できる。

複数使うデメリット:
1. タスク数に制限がついてしまう
2. I/O ビットマップを使うとなるとメモリが無駄。
3. セグメントレジスタの DWORD align が無駄
 (だけどアクセス高速化のためには結局必要かも)。
0145LightCone ◆sSJBc30S5w NGNG
>>143
>そうすればセグメント間ジャンプのときに
>セグメントタイプがTSSであることをCPUが検知してくれて
>TSSの内容を参照し、セグメントを切り替えてくれる。

CPU定義のタスクジャンプや、タスクコールを使わないで済ますんです。

あと、タスクスイッチを伴うjmpは、「セグメント間ジャンプ」
とは言わない習慣のはずです。
0146みとこ ◆AEqcy/sQU6 NGNG
GDTは連続した物理アドレスではなくリニアアドレスが必要だと思ったんですが。
物理アドレスを使うのはCR3とページディレクトリ・ページテーブルだけですよね?
0147デフォルトの名無しさんNGNG
>>119
> その方法では結局、実際に文字列を取得する際のサイズが前回取得した
> 文字列のサイズ以下になるまで繰り返しが必要になり、単に文字列を
> 取得したいたびにそのようなループを書く必要があることになる
> わけですよね。

ライブラリというものの存在はご存知 ?
個人的には、OS が勝手に領域を確保するという仕様は好みでない。
全ての言語が動的メモリーをサポートしているわけじゃないからね。
文字列領域をユーザーに確保させるか環境が確保するのかは言語/ライブ
ラリ作成者が決めればいい話で OS が決めることではないと思う。

重要なことは、const char *GetTaskName2(HTASK hTask); と言う API
を使って領域を確保しないでタスク名を取得することはできないけど、
GetWindowsDirectory() なら、ライブラリで領域を確保することもでき
るし、ユーザーに領域を確保させることもできると言う自由度があると言
うこと。その自由度を捨てて OS でできる限り安全にすると言うのも一つ
の方向ではあるけどね。
0148デフォルトの名無しさんNGNG
>>126
> >>116さんはTASKのデータをTASKに持たせておいて、
> カーネルではTASKのIDとかで識別できる程度にしておいて、

>>116 では、タスク名称の置き場所とかには言及してません。
まあ、普通は TCB (Task Control Block) 等のタスク管理領域に置くと
思う。

> カーネルからのメッセージでTASKが動作するといったイメージ
> でしょうか?

これは、まずいと思う。ps や taskmgr.exe で、ハングアップしたタス
ク名称が取得できなくなってしまう。
0149126NGNG
>>129 >>148
説明ありがとうございます。できるだけ小さいカーネルと、周りのプログラム
というのが実現できればいいと思ったのですが、ある程度のメモリサイズは
どうしても必要になるのですね。書籍の勉強だけでなく実装の勉強も
してみます。ありがとうございました。
0150LightCone ◆sSJBc30S5w NGNG
>>146
ホントですね。すみません。
lgdtで指定するのは「連続した線形アドレス」でした。
gdtrやidtrは、「セレクタ」が必要ないんでしたか。最近忘れてます。
0151みとこ ◆AEqcy/sQU6 NGNG
GDTRとIDTRは開始アドレスとリミットで構成される擬似デスクリプタという構造体だったと思います。
セレクタが必要なのはLDTRやTRですね。
0152LightCone ◆sSJBc30S5w NGNG
>>151
 そういえば、そうそう。gdtrとidtrのディスクリプタだけは、
「擬似」なんですよね。
0153みとこ ◆AEqcy/sQU6 NGNG
TSSを使わないスタック切り替えは工房の頃に力技で試しましたね。
タスク切り替えが頻繁に起きると大変な事になりそう。。。

めぐではどうしようかな。
0154LightCone ◆sSJBc30S5w NGNG
>>153
>TSSを使わないスタック切り替えは工房の頃に力技で試しましたね。
素晴らしい。


>タスク切り替えが頻繁に起きると大変な事になりそう。。。
 最近のCPUで改良されたかもしれませんが、
速度パフォーマンス的には、CPUが持つタスク切り替え機能も
クロック数はかなりかかるので、気になるほどの差は出ないように思います。
0155LightCone ◆sSJBc30S5w NGNG
>>153
 Linuxでは、バージョンアップ時の改良として、TSSが一本化された
こともありますし、超先生の見解通り、TSSを一本化(使わない)方針が
よいように思います。

 私の個人的見解でもTSSを用いたタスクスイッチはやめたほうが
いいと思います。理由はTR用のセレクタ数にGDTの制限が出てしまう
ことと、実際問題上、コールゲートを呼び出してタスクスイッチする
のは、逆にメンドクサイことになりそうだからです。

 経験上、CR3 等だけ変更して、CS:EIP は連続していた方が何かと楽
です(コードの流れは連続して、メモリマップだけを切り替える方が
楽です。)(CPU定義のタスク切り替えだと、EIPなども変えようと
してしまうわけで)。
0156みとこ ◆AEqcy/sQU6 NGNG
あの頃はカーネル(リング0)スタックをタスク切り替えの際に毎回コピーしなおしてた気が・・・
0157LightCone ◆sSJBc30S5w NGNG
>>156
>あの頃はカーネル(リング0)スタックをタスク切り替えの際に毎回コピーしなおしてた気が・・・
逆に思いつかない(^_^;)
0158みとこ ◆AEqcy/sQU6 NGNG
TSS操作とかページ切り替えをしないように考えてたらスタックコピーという荒業を思いついたのですが、、、

若いって素晴らしい(汗
0159デフォルトの名無しさんNGNG
幾つか質問します
1.OSを作っている言語は何ですか?
2.発表時期は何時?
3.有料?無料?
4.CUI系?GUI系?どちらで操作するようにするのですか?
5.ソースコードは公開するのですか?

私も参加してみたいですねぇ…
0160デフォルトの名無しさんNGNG
過去ログ読めやぁ
0161LightCone ◆sSJBc30S5w NGNG
>>159
 3種のOSの作者が来ていて、一つのOSを共同制作しているわけではない
ことはいいですか?

 ひげぽんさんの OS(higepos, Mona?)は、GPLなので参加者は歓迎されると思い
ます。

 私は NWSOS を作っていて、ソースコードは今のところ非公開。開発言語は
C とアセンブラです。GUIのWindowの中でCUIをサポートしています。
「発表時期(?)」というのは意味がわかりません。今のところ売れそうも
ないので無料です。将来はわかりませんが有料でもただ同然になるはず
です。

 みとこさんは、MEG-OS の作者です。
0162ひげぽんNGNG
どうもIA32におけるタスク切り替えの本質を理解できずに
苦しんでいます。

インテルのマニュアルによると

>プロセッサは次の4 つのどれかが起こった場合に他のタスクへ実行を転送する。
>• 現行プログラム、タスクまたはプロシージャが、GDT 内にあるTSS ディスクリプタに対
>してJMP またはCALL 命令を実行した。
>• 現行プログラム、タスクまたはプロシージャが、GDT または現行LDT 内にあるタスク・
>ゲート・ディスクリプタに対してJMP またはCALL 命令を実行した。
>• 割り込み/ 例外ベクタがIDT 内にあるタスク・ゲート・ディスクリプタを指している。
>• EFLAGS レジスタのNT フラグがセットされているときに現行タスクがIRET を実行した。

そこで私は、TSSディスクリプタ、TSSを用意し
そのTSSディスクリプタに対してjmp(call)すれば
タスクが切り替えられそうだと言うことをなんとなく理解しました。

タスクの切り替えとは大まかに言って
コンテキスト
コードセグメント
データセグメント
スタックセグメント
開始アドレス等
を切り替えることだと思っているのですが
0163ひげぽんNGNG
>LightConeさんの仰る
>超先生の見解通り、TSSを一本化(使わない)方針が
>よいように思います。
>
> 私の個人的見解でもTSSを用いたタスクスイッチはやめたほうが
>いいと思います。

超先生@OS板 さんの仰る
>使わないというか、TSS一つを共有と。

がよく理解できないのです。

Intelは、タスク一つにつき、ディスクリプタとTSSを一組
を用意せよと言っているのに対して
TSSは一つを共有すればよいと仰っていると思うのですが

その場合具体的にはどういう方法でOSが何をすればよいのかが
分かりません。

この辺のことはどのような勉強方法で学習されたのでしょうか。
0164ひげぽんNGNG
>>159
>幾つか質問します

以下、私が中心となって開発しているMons(旧名higepos)について
書かせていただきます。

>1.OSを作っている言語は何ですか?
アセンブラ、C++

>2.発表時期は何時?
すいません、何の発表ですか。
まだ完成していないのでリリースは当然していないです。

>3.有料?無料?
無料です。

>4.CUI系?GUI系?どちらで操作するようにするのですか?
現在はCUIです。
将来はGUIを目指しています。

>5.ソースコードは公開するのですか
sourceforge.jp上で開発していますので公開しています。
http://mona.sourceforge.jp/

>私も参加してみたいですねぇ…
熱意とやる気のある方であれば大歓迎です。
0165ひげぽんNGNG
>>164
訂正です。
>以下、私が中心となって開発しているMons(旧名higepos)について
→以下、私が中心となって開発しているMona(旧名higepos)について
0166LightCone ◆sSJBc30S5w NGNG
>>163
>この辺のことはどのような勉強方法で学習されたのでしょうか。
私の場合、

工学社「80386 プログラミング」
John H,Crawford + Patrick P Gelsinger 著
岩谷 宏 訳

をじっくり読みました。

 この本の中には「命令の論理ソース」がC言語風に掲載されていて、
タスクスイッチが内部的にどのように処理されているのかが厳密に
分かるようになっています。文章量が多くて少々難解ですが、
「論理ソースコード」は参考になります。


 その本を見ると、タスクゲートや、TSSセレクタに対する jmp や call
も、mov cr3,reg や、ldtr, ltr などの組み合わせで書けることが分かる
ようになっています(一目瞭然とまではいかないまでも。)。
0167FreeDOS教徒NGNG
>>ひげぽん
Typoです(Mons->Mona)
0168FreeDOS教徒NGNG
うわ。先に訂正されてしまった。ゴメソ。

何はどもあれプロジェクトに協力できる人募集中です(;
0169LightCone ◆sSJBc30S5w NGNG
>>162
 要するに、それは、IA32のCPUが、
タスクとはこうである、タスクスイッチとはこうである、と定めた
内容を書いているだけで、タスクスイッチとは、所詮、ページテーブル
の変更と、ローカルセレクタの変更、汎用レジスタの復帰、などに
他ならないんです。

ページテーブルの変更--->レジスタ CR3 の変更(mov cr3,reg)
ローカルセレクタの変更--->ldtr の変更(LLDTR)
汎用レジスタの復帰--->通常mov命令

でことたります。


 ただし、一点だけ注意することとして、内部レベルへの遷移時には、
TSSの SS0:ESP0 が自動的に参照されてしまうことです。この動作
だけは、変更することが出来ない(はず)です。
0170ひげぽんNGNG
LightConeさん
>工学社「80386 プログラミング」
http://www.amazon.co.jp/exec/obidos/ASIN/487593128X/qid%3D1014798612/sr%3D1-1/ref%3Dsr%5F1%5F0%5F1/250-3723145-5289069
これですね。在庫切れだ。

>その本を見ると、タスクゲートや、TSSセレクタに対する jmp や call
>も、mov cr3,reg や、ldtr, ltr などの組み合わせで書けることが分かる
>ようになっています(一目瞭然とまではいかないまでも。)。

納得しました。そういうことなんですね。
昨日はこれを知らなくて????となっていました。
やっぱりできる人は勉強してるんですね。

0171ひげぽんNGNG
>>167
>>168
FreeDOS教徒さん
ご指摘ありがとうございます。
>>ひげぽん
>Typoです(Mons->Mona)
OS名だけ見事にtypo、もうバカかと・・・

>何はどもあれプロジェクトに協力できる人募集中です(;
大募集ですm(__)m

0172ひげぽんNGNG
>>169 LightConeさん
>タスクスイッチとは、所詮、ページテーブル
>の変更と、ローカルセレクタの変更、汎用レジスタの復帰、などに
>他ならないんです。

これを知らずに、タスク切り替え部をいびつに
実装してしまったら後悔するところでした。
ありがとうございます。

工学社「80386 プログラミング」 探してみます。
0173LightCone ◆sSJBc30S5w NGNG
ちなみに、この本の初版は、昭和63年です。私のは平成4年版です。
初版は、14年も前なんですね、、、、、、、、。
0174ひげぽんNGNG
>>173
>ちなみに、この本の初版は、昭和63年です。私のは平成4年版です。
>初版は、14年も前なんですね、、、、、、、、。

ここを見ると絶版と書いてあります・・・(T_T)
http://www.skyfree.org/jpn/recommend-1.html


0175159NGNG
はい、分かりました。
凄いです。
0176159NGNG
あ、発表って正式リリースの事です。
0177LightCone ◆sSJBc30S5w NGNG
>>174
絶版本を探すには、古本屋に行くといいのではないでしょうか。

個人的には、中古でも、探していた本が見つかった時は、新しい
本よりも嬉しく感じます。
0178FreeDOS教徒NGNG
何はどもあれ -> 何はともあれ
0179ひげぽんNGNG
>絶版本を探すには、古本屋に行くといいのではないでしょうか。
>個人的には、中古でも、探していた本が見つかった時は、新しい
>本よりも嬉しく感じます。
近くの図書館と、オンライン古本屋では見つかりませんでした。
ますます欲しいーーーー

>>178
typo伝染りましたね。

0180。。。NGNG
前々スレから読み始めてやっと追いつきました。
このスレをたどっていくと、誰でもOSを作れそうですね。
0181デフォルトの名無しさんNGNG
じゃあ俺も
「NanihaDomoare MONS」っていうOS作るよ!
0182LightCone ◆sSJBc30S5w NGNG
>>180
>このスレをたどっていくと、誰でもOSを作れそうですね。

 正直言って、誰でもとは言わないまでも、Cとアセンブラプログラムが
できる方なら基本的なOSは時間さえあればできると思います。
 大事なのは、CPUアーキテクチャの正しい情報を得ることと、
もう一つがデバッグに耐えられる忍耐力があることではない
かと思いますが、どちらも「やる気」の問題が大きいように思います。
スケジューリングやファイルキャッシュの優秀さなどを追求するのは
実験的と勘でやっていけばいいでしょうし、時間が取れなければ先人の
結果を、Linuxの解説本やOSの基礎論の本で見ることで済ませられますし。

 私も含めて不注意な人にはちょっぴりデバッグ回数が増えてしまうのが
大変な所ですが(笑)。
■ このスレッドは過去ログ倉庫に格納されています