7

これは答えるのがかなり難しい質問だと思います。主な理由は、間違っている可能性のあるものが非常に多く、特定するのが難しいためです。しかし、私はできるだけ多くの情報を提供します。うまくいけば、それが役立つでしょう。

私はD言語とDigitalMarsDコンパイラを使用して独自のカーネルを書き始め、再配置可能なフラットバイナリを生成する方法を見つけるのに多くの問題を抱えた後、最終的に通常のPEファイルを生成するというアイデアを思いつきました。アドレス、およびそのすべてのヘッダーをバイト(NOPオペコード)0xC0000000に置き換えます。0x90これは完全にうまく機能し、16ビットアセンブリベースのブートローダーの助けを借りて、画面に物事を書き込んだり、ページングを設定したり、プロテクトモードに入るなどを完全にうまく行うことができました。

すべてが順調でした。つまり、カーネルで使用するためにDランタイムライブラリを移植することにしました。ライブラリのサブセットを抽出し、それを変更してアプリにコンパイルできるようにしました。次に、プログラムを実行しました。(注:ライブラリをまったく使用しませんでし た。私のコードは、起動後に実行される最初のコードでした。最初に発生したのは画面への印刷であり、その前にランタイムコードは呼び出されませんでした。)"Kernel"

AD配列(したがって、文字列は単なるaであるため、文字列char[])は、ポインタとサイズメンバーを持つ構造体にすぎないため、32ビットシステムでは8バイトの大きさになります。面白いことに、プログラムを実行すると、構造体のメンバーがゼロであることがわかりました。つまり、ポインターとサイズの両方がゼロでした。(ポインターの値と長さのメンバーを画面に出力することでこれを確認しました。どちらもゼロでした。)ランタイムのソースコードを削除するとすぐに(とにかく実行されませんでした)、正常に機能しました。 。

これを2つの可能性に絞り込みました。

  1. スタックが正しく設定されていませんでした。ランタイムライブラリがなくてもすべてが正常に機能するため、これを除外し、ファイルを逆アセンブルして、コードの前に他のコードが実行されていないことを確認しました。

  2. PEファイルセクションに何かおかしいことがあります。実行時のバージョンに2つのTLS(スレッドローカル)変数があることを確認しました。案の定、(スレッドローカルではなく)共有させたところ、コードは機能しました!ただし、別のファイルで記述したコードを呼び出したときに、コードで同じ問題が発生しましたkernel.d。スタートアップファイルである、のみが文字列で正しく動作しました。他のファイルでは、配列は再びゼロになりました。

さて、なぜこれが起こっているのかについて誰かが推測していますか?

さらに情報が必要な場合は、喜んで投稿します。

ありがとうございました!

4

2 に答える 2

6

まず、免責事項:私はDについて最初のことを知りません。

次に、別の免責事項:「PEファイル」という用語の使用に基づいて、Windowsを使用していると推測します。GNUツールチェーンの提案をしようとしています...

しかし...Dコンパイラが他のコンパイラと同じようにオブジェクトファイルを生成すると仮定すると...次のことをしないのはなぜですか(これは、Cで趣味のOSに取り組んだとき、そのようなことをする時間があったときに行ったことです):

  • カーネルのELFバイナリを生成します...これを行うには、通常どおりすべてのオブジェクトファイルをビルドします。リンクステップで、ld開始アドレス、バイナリのセクション(テキスト、データ、rodataなど)の順序などを定義するリンカースクリプトをフィードします...
  • GRUBで起動します(かなり簡単です。..バイナリの先頭近くに魔法の言葉を入れる必要があります。対応するobjが先頭近くでリンクされている場合は、.asmファイルでステートメントを入力するdbか、ステートメントを入力できます。カーネルの。このリンクdwをチェックしてください)

このようにして、PEヘッダーをハックしたり、ブートローダーを作成したりするよりも、もっと面白いことに集中できます。

もちろん...リンク方法ではなく、コード自体に問題がある可能性は十分にあります。アセンブリ出力をステップスルーできるようなもので実行すると有益な場合があります。x86 PCエミュレーターqemuには、アセンブリを出力して状態をログに登録するデバッグオプションがいくつかあります。私はそれを使用していました。

于 2010-12-22T05:25:36.627 に答える
1

一年後...

解決しました!:D

(>'。')>(^'。'^)<('。')>(v'。'v)<('。' <)

ブートローダーの問題でした。メモリに読み取るセクターが少なすぎました。(つまり、128 125ではなく64セクターです。)

于 2011-06-21T03:40:41.387 に答える