ページ 11

質問板

Posted: 2011年6月15日(水) 08:04
by TororoShinku
OS作成時の質問板です。
どんな事でもかまわないけれども、
回答者様に分かりやすいような質問を心がけましょう♪

Re: 質問板

Posted: 2011年6月15日(水) 19:40
by aquashooting
>TororoShinkuさん
トピックを立ててくださいまして、申し訳ないです。
実はこちらからトピックを立てようとすると出来ないので、他のトピックも立ててもらえませんか?よろしくおねがいします

Re: 質問板

Posted: 2011年6月15日(水) 19:47
by TororoShinku
aquashooting さんが書きました:>TororoShinkuさん
トピックを立ててくださいまして、申し訳ないです。
実はこちらからトピックを立てようとすると出来ないので、他のトピックも立ててもらえませんか?よろしくおねがいします
了解です。 質問版、OS更新履歴板を立てていいでしょうか?

Re: 質問板

Posted: 2011年6月15日(水) 20:01
by aquashooting
どうぞおかまいなく

Re: 質問板

Posted: 2011年6月23日(木) 21:44
by aquashooting
TIMEコマンドを応用した時計を作ろうかと実装しているのですが
こちらが問題の自作の時計のソースコードです。

コード:

#include "apilib.h"
#include "bootpack.h"
#include <stdio.h>
void HariMain(void)
{
	int win;
	char buf[150 * 50];
	unsigned char s[24],t[7];
	win = api_openwin(buf, 150, 50, -1, "What date is it today?");
	api_boxfilwin(win,  8, 36, 141, 43, 3 /* 黄 */);
	readrtc(t);//RTCの読み込み
	sprintf(s,"%02X%02X.%02X.%02X %02X:%02X:%02x\n",t[6],t[5],t[4],t[3],t[2],t[1],t[0]);//year.month.day hour:minitues:seconds
	for (;;) {
		if (api_getkey(1) == 0x0a) {
			break; /* Enterならbreak; */
		}
	}
	api_close();
	api_end();
}
これははりぼてOSにある「NOODLE」アプリをちょっとまねしてみたものですが
RTCの読み込みがこれでうまくいっているはずなのに、OSで例外がおきてしまいます。

これはなぜでしょうか、教えてください。

Re: 質問板

Posted: 2011年6月24日(金) 06:48
by TororoShinku
aquashooting さんが書きました:

コード:

#include "apilib.h"
#include "bootpack.h"
#include <stdio.h>
void HariMain(void)
{
	int win;
	char buf[150 * 50];
	unsigned char s[24],t[7];
	win = api_openwin(buf, 150, 50, -1, "What date is it today?");
	api_boxfilwin(win,  8, 36, 141, 43, 3 /* 黄 */);
	readrtc(t);//RTCの読み込み
	sprintf(s,"%02X%02X.%02X.%02X %02X:%02X:%02x\n",t[6],t[5],t[4],t[3],t[2],t[1],t[0]);//year.month.day hour:minitues:seconds
	for (;;) {
		if (api_getkey(1) == 0x0a) {
			break; /* Enterならbreak; */
		}
	}
	api_close();
	api_end();
}
全く関係ないかもしれませんが、readrtcはアプリから呼び出すためには、
hrb_api内に定義しないとダメなのかもしれません。

Re: 質問板

Posted: 2011年6月24日(金) 15:23
by aquashooting
>TororoShinkuさん
分かりました、やってみます。
もしだめだったらまた質問しますのでよろしく

Re: 質問板

Posted: 2011年8月20日(土) 21:53
by aquashooting
ずいぶんと遅くなりましたが、まだ前に質問した問題は解決していません。

それで、今度はもう一つ、ちょっとした興味で質問したいと思います。
QEMUには音を出すためのものがありませんが、それが出せるようにするには具体的にどうすればよいのでしょうか?
いくつかのサイトを参考にしてみましたが、どれも検討違いのものなので
よろしくおねがいします

Re: 質問板

Posted: 2011年8月21日(日) 09:20
by TororoShinku
自分はvitual boxを使ってます。
30日本の最後に書いてあった、isoイメージ作るソフトで、
作ったisoを起動して試してます。

Re: 質問板

Posted: 2011年8月22日(月) 18:54
by aquashooting
>TororoShinkuさん
情報提供ありがとうございます

Re: 質問板

Posted: 2011年9月04日(日) 19:17
by aquashooting
お久しぶりです。
早速ですが、質問をさせていただきます。

今度はタイトルコマンドを実装しようと思っているのですが、なかなか思うようなものができません。
タイトルコマンドは左上にあるアプリ名などを、ユーザーが入力した文字列に変えてしまうというものです。
例として「title cmdline」とうつと、左上にcmdlineと表示できます。

一応分かっているのはmake_window8()の括弧の中にあるchar *titleの中身をうまいこと変えればできることだけです。

今言ったことをプログラムにするとこのような感じです。

コード:

/*疑問1:cmd_title関数の中にある引数は果たしてこれだけでいいのだろうか?*/
void cmd_title(struct CONSOLE *cons,char *cmdline){
     /*ここに何らかの処理を書きたい*/
     make_window8(buf, 256, 165, "console", 0); //"console"の部分を入力した文字列に変換したい
     return;
}
私からは以上です。

Re: 質問板

Posted: 2011年10月15日(土) 16:18
by ぬっち
どうしても割り込み処理がうまくいかないので質問させていただきます。
OSの自作を始めてから、ブートセクタの読み込み、GDTの初期化、画面へのデバッグ表示まで行えるようになりました。
次はOSには欠かせない、マルチタスクを実現しようと思ったのですが割り込み処理で躓いてしまいました。
バイナリを駆使しても解決しそうになかったので皆様の知恵をお貸しいただければと思い、書き込みをしました。

私が作ろうと思っているOSは、30日OS自作本のようなGUI主体ではなく、UNIXライクなCUI主体のものです。
使用ツールは
[アセンブラ] gas
[コンパイラ] gcc
[リンカ] ld
[エミュレータ] qemu
[etc] make
です。

マルチタスクの実装ですが、私は以下の順番で行えば良いと思っています。
1. IDTの初期化
2. 割り込みハンドラの作成  ←現在ここ
3. タイマ割り込みの実装
4. マルチタスクの実装(TSS関連)

最初にキーボードの割り込みハンドラの実装に取りかかりました。
割り込みハンドラの作成は30日のOS自作入門を参考(ほとんど同じ)にしています。
違いは、asmhead.nasのwaitkbdoutの処理を行っていないことくらいです。
また、ブートセクタでOSのサイズ分をディスクから読み込むようになっています。
qemuのモニタリング機能を使用し、GDTとIDTが適切に設定されていることは確認しました。
症状としては、キーボードの割り込みの時にIDTに設定されたアドレスにジャンプせず、まったく違う部分のアドレスにジャンプしてしまうということです。
しかも割り込みが起こる度に、まったく異なるアドレスにジャンプします。
割り込みが起きているのはわかるのですが。。。

waitkbdoutがもしかしたら怪しいのかなと思っていますが、自作本見た感じだとあまり必要のない処理のような気がしますし。
現在は、はじめて読む486を見ながらさらに原因究明をしている状態ですが、時間がありましたら教えてください。
私も解決したらここに書き込みをします。
よろしくお願いします。

[追記]
あと1つ30日自作本と異なることがあります。io_out8でPICの初期化を行う部分で、
asm_out8( PIC0_IMR, 0xfb );
とありますが、
asm_out8( PIC1_IMR, 0xf9 );
として、PICの初期化直後にキーボードの割り込みを許可しています。

Re: 質問板

Posted: 2011年10月15日(土) 17:45
by TororoShinku
自分のOSデータの入ったパソコンじゃないんで、
調べれないため原因かわかりませんが、

コード:

	asm_out8(PIC0_IMR,  0xfb  ); /* 11111011 PIC1以外は全て禁止 */
	asm_out8(PIC1_IMR,  0xff  ); /* 11111111 全ての割り込みを受け付けない */
としその後↓の処理を行っています。

コード:

	asm_out8(PIC0_IMR, 0xf8); /* PITとPIC1とキーボードを許可(11111000) */
	asm_out8(PIC1_IMR, 0xef); /* マウスを許可(11101111) */
もしかしたら関係あるかもしれません。

Re: 質問板

Posted: 2011年10月16日(日) 16:24
by ぬっち
返信ありがとうございます。
うーん、やはりだめそうですねぇ。。。
PITの割り込みを許可したためか、割り込みが起こる度に、IDTとGDTが奇妙な値に変化し、手がつけられない状態となってしまいました。
多分、これはPITの割り込みハンドラを作成していないのが原因と思い、PITの割り込みは今のところ止めておきました。
やはり、IDTの初期化で0x21への割り込みハンドラの設定がおかしい気がしました。

抽象的な話になってしまいそうなのでソースコードを用いることにします。
IDTの初期化です。

コード:

GateDesc* pDesc = ( GateDesc* ) IDT_ADDR;
int i = 0;

for( i = 0; i < NUM_IDT; ++i ){
	SetGateDesc( pDesc + i, 0, 0, 0 );
}
SetGateDesc( pDesc + 0x21, (int)IntHook21, 2 * 8, AR_INTGATE32 );
LoadIDT( 0x7ff, IDT_ADDR );
メモリマップは自作本と同様です。IntHook21というのが割り込みハンドラです。
この設定により、IDTにはIntHook21のアドレスが設定されます。
そこで、バイナリでIntHook21のアドレス値を見てみると、0x1449となっており、0x280000+0x1449となっていません。
しかし、セレクタでGDTの2番目を指定しているため、0x1449->0x280000+0x1449の変換が行われているはずです。
その後、色々調べてみると、0x281449には別のコードが入っていることがわかりました。
これは自作本と異なり、ブートセクタ+その他諸々を0x280000にコピーしていないためです。

現在まだ完全に原因がわかっていませんが、どうやら私がリンカスクリプトをきちんと理解していないことと、割り込みハンドラの設定がきちんと行えていないことが原因なのかもしれません。
もう少し原因がつかめましたら再度ご報告します。

自作本のソースコードを見れない環境にいるので、自作本で説明されていないソースコードが見れないのが残念なところです。

TororoShinkuさん、返信ありがとうございます。
長文失礼しました。

Re: 質問板

Posted: 2015年2月21日(土) 14:13
by taka
はじめまして。takaと申します。
私もはりぼてOSから派生させてOSを作っています。
いきなりアレですが返信を。
>>aquashootingさん
一応分かっているのはmake_window8()の括弧の中にあるchar *titleの中身をうまいこと変えればできることだけです。
そこはmake_wtitle8 じゃないですか?
make_window8 だと背景の黒がなくなる気がします。
以下適当即興コード

コード:

void cmd_title(struct CONSOLE *cons,char *cmdline){
	struct TASK *task = task_now();
	int i, j;
	char title[256];
	
	for(i = strlen("title ") + 1, j = 0; cmdline[i] != ' '; i++, j++) {
		title[j] = cmdline[i];
	} /* cmdlineは入力そのままなので 引数前を飛ばしてコピー */
	
	make_wtitle8(task->cons->sht->buf, 256, title, 0);
	return;
}

Re: 質問板

Posted: 2015年2月21日(土) 14:25
by taka
連投すみません。
また返信です。
>>ぬっちさん
違いは、asmhead.nasのwaitkbdoutの処理を行っていないことくらいです。
waitkbdoutの部分はここでしょうか。

コード:

		CALL	waitkbdout
		MOV		AL,0xd1
		OUT		0x64,AL
		CALL	waitkbdout
		MOV		AL,0xdf			; enable A20
		OUT		0x60,AL
		CALL	waitkbdout
ここだったらA20GATEが解放されていない可能性が高いです。(キーボードコントローラーがデータをきちんと受け取れていないかも)
もし解放されていなければ
0x281149 & 0xFFFFF(20bit) = 0x81449
なので全く違うアドレスになっているはずです。
ここでwaitkbdoutをきちんと呼び出してみたらどうですか?