1

私は現在カーネルを開発していますが、システム コールを実装するときに不可解な問題に遭遇します。0x80 番目の割り込みハンドラを次のように記述します。

sys_call_s:
    pushad
    call sys_call
    popad
    iret

「sys_call」は、実際の作業を行う C 関数の名前です。問題は、「int 0x80」の次の命令を実行するときに、トリプル フォルトが発生したことです。たとえば、以下のプログラムの 3 行目を実行するとエラーが発生し、最後に bochs がリセットされます。

abc: mov eax,0              ; 0 means system call get_pid()
     int 0x80
     mov [pid_father],eax   ; this is the instruction caused bochs to triple fault
     mov eax,1              ; 1: fork()
     int 0x80
     jmp $

pid_father:  dd 0

さらに奇妙なことに、「iret」命令を「ret」に置き換えると、プログラムは正常に動作し、「jmp $」でスピンします。

なぜこの問題が発生したのか、誰にも分かりますか?

[編集] この問題は、スタック ポインタのアドレスが間違っていることが原因だと思います。このプロセス用にページをマップしました。このページの物理アドレスは 0x401000、線形アドレスは 0x800000(8M) です。このプロセスのスタック ポインターを 0x800ff0 に設定しましたが、bochs で「print-stack」コマンドを使用するたびに、「リニア 0x00801000 では物理アドレスを使用できません」という出力が表示されます。どうすれば修正できますか?

[編集] このプロセスでデータにアクセスできないことがわかりました。たとえば、「int 0x80」の前に「mov [pid_father],eax」を配置すると、bochs がリセットされます。なぜこれが起こったのですか?

4

1 に答える 1

1

GDT と DS のレジスタとページング テーブルの内容を表示する必要があると思います。コードの残りの部分がなくても、その行にトリプル フォールトが表示されている場合は、[pid_father] へのアクセスに問題があることを意味します。データ セグメントが無効であるか、ページが無効であるか読み取り専用としてマークされているため、GPF またはページ フォールト例外が発生しています。GPF またはページ フォールト例外が失敗し (おそらく同じ理由または別の理由で)、二重フォールト例外が発生し、再び失敗して CPU がトリプル フォールトおよびリセットされます。

Bochs は通常、失敗した理由を (記憶から) かなりうまく出力します。履歴を少し上にスクロールして、発生した最初の例外を探してください。

于 2013-05-05T06:39:14.367 に答える