22

ある種のアセンブラを使用せずに (できれば __asm を使用せずに)、C または C++ でブートローダーを作成することは可能ですか? オペレーティング システムを作成していますが、完全に C および C++ で作成したいと考えています。

4

4 に答える 4

24

それはかなりシステムに依存しています。ほとんどの場合、答えは「いいえ」です。C コードの実行を開始する前に、カスタム アセンブリを記述して C ランタイムをセットアップする必要があります。ただし、いくつかの例外があります。たとえば、ARM Cortex-M0は、C コードをリセットから直接実行できます。

ただし、おそらく M0 を使用していないため、アセンブリを作成する必要があります。繰り返しますが、システム/チップに依存しますが、次のような簡単なことでうまくいくかもしれません:

reset_vector:
    mov  sp, SOME_KNOWN_GOOD_STACK_ADDRESS
    call c_entry_point

これは単にスタック ポインタを初期化し、C プログラムのエントリ ポイントを呼び出します。もちろん、この単純なセットアップは、それをサポートするリセットベクター/ベクターテーブルを持つチップ、リセットベクターが呼び出される前に初期化される RAM (または RAM のようなもの) などに依存します。初期のシステム初期化では、多くの「問題」が発生する傾向があります。

コンパイラ、アセンブラ、リンカのドキュメントに慣れる準備をしてください。最初の段階のブートローダーとしてフラッシュできるフラット バイナリを生成することは、多くの場合、それ自体が大きな苦痛です。

幸運を!

于 2011-07-24T17:48:28.773 に答える
6

これが x86 用であると仮定すると、適切なコンパイラ オプションがあり、適切なリンカ マジックを使用してブートセクタのレイアウトを正しく取得できれば、16 ビット モードで何かを実行できる可能性があります。

しかし、プレーンC(または C++) では遠くまで行きません。割り込みを非常に高速にマスクする必要があり、Cそのための関数はありません。組み立てが必要です。

これはおそらく、他のほとんどのアーキテクチャでも同じです。C と C++ には、これらの機能が組み込まれていないだけです (一部のコンパイラ拡張機能が役立つ場合があります)。

あなたがやろうとしていることの素晴らしいリソース: OSDev

于 2011-07-24T17:50:13.043 に答える
3

x86 保護モードの場合:

保護モードに切り替えるには、次のようなことを行う必要があるため、答えはノーだと思います。

    lgdt[GDTR]
    jmp CODESEL:FLUSH
FLUSH:
    ...

jmp間違っているかもしれませんが、純粋な C/C++ で命令を実行する方法はないと思います。(私はここでは決して専門家ではありません。少し前に作成したブートローダーを参照しているだけです。)

于 2011-07-24T17:40:28.457 に答える
3

いいえ、「純粋な」C では、少なくとも x86 では不可能です ... x86 マシンが 16 ビット リアル モードで起動するという事実に加えて (コンパイラが 32 ビットではなく 16 ビットを生成する必要があります)コード)、x86 および他のプラットフォームでは、CPU のレジスタや特定のアセンブリ コマンドにアクセスする必要があります。

第二に、C++ の場合、クラスを定義することにした場合、最初のクラスが実際にメモリ内のどこかに存在できるようにメモリをセットアップするために、何らかのタイプの手動で構成して「コンストラクタ」を実行する必要があります...あなたも勝った例外をスローすることはできません。これらの高レベルのデータ抽象化には、OS ランタイム自体からの適切なサポートが必要であり、アセンブリと C コードの組み合わせを使用してセットアップする必要があるため、基本的に、使用しようとする C++ 固有の機能は役に立ちません。

于 2011-07-24T18:50:13.967 に答える