7

起動時間の要件が厳しいプロジェクトに取り組んでいます。対象となるアーキテクチャは、32ビットプロテクトモードで動作するIA-32ベースのプロセッサです。改善できると特定された領域の1つは、現在のシステムがプロセッサのIDT(割り込み記述子テーブル)を動的に初期化することです。プラグアンドプレイデバイスがなく、システムが比較的静的であるため、静的に構築されたIDTを使用できるようにしたいと思います。

ただし、8バイトの割り込みゲート記述子がISRアドレスを分割するため、これはIA-32アーチにとって厄介であることがわかります。ISRの下位16ビットは記述子の最初の2バイトに表示され、他のいくつかのビットは次の4バイトを埋め、最後にISRの最後の16ビットが最後の2バイトに表示されます。

const配列を使用してIDTを定義し、IDTレジスタを次のようにポイントするだけです。

typedef struct s_myIdt {
    unsigned short isrLobits;
    unsigned short segSelector;
    unsigned short otherBits;
    unsigned short isrHibits;
} myIdtStruct;

myIdtStruct myIdt[256] = {
    { (unsigned short)myIsr0, 1, 2, (unsigned short)(myIsr0 >> 16)},
    { (unsigned short)myIsr1, 1, 2, (unsigned short)(myIsr1 >> 16)},

myIsrは一定ではないため、Cでこれを行うことは違法であるため、明らかにこれは機能しません。その値は、コンパイラではなく、リンカ(限られた量の計算しか実行できない)によって解決されます。

これを行う方法に関する推奨事項やその他のアイデアはありますか?

ありがとう、

4

1 に答える 1

3

よく知られた x86 いぼに遭遇しました。リンカが、IDT エントリが期待するスウィズル形式で isr ルーチンのアドレスを詰め込むことができるとは思えません。

野心がある場合は、このような (Linux ベースの) アプローチを行う IDT ビルダー スクリプトを作成できます。私はこのスキームをテストしていませんが、とにかく厄介なハックと見なされる可能性があるため、慎重に行ってください.

ステップ 1: 「nm」を実行して stdout をキャプチャするスクリプトを作成します。

ステップ 2: スクリプトで、nm 出力を解析して、すべての割り込みサービス ルーチンのメモリ アドレスを取得します。

ステップ 3: IDT バイトがすべてセットアップされ、LIDT 命令の準備が整ったバイナリ ファイル 'idt.bin' を出力します。スクリプトは、isr アドレスを正しいスウィズル形式で出力することは明らかです。

ステップ 4: objcopy を使用して生のバイナリを elf セクションに変換します。

objcopy -I binary -O elf32-i386 idt.bin idt.elf

ステップ 5: idt.elf ファイルには、次のようなシンボルを含む IDT バイナリが含まれています。

> nm idt.elf
000000000000000a D _binary_idt_bin_end
000000000000000a A _binary_idt_bin_size
0000000000000000 D _binary_idt_bin_start

ステップ 6: idt.elf を含むバイナリを再リンクします。アセンブリ スタブとリンカー スクリプトでは、シンボル _binary_idt_bin_start を IDT のベースとして参照できます。たとえば、リンカー スクリプトは、任意のアドレスにシンボル _binary_idt_bin_start を配置できます。

IDT セクションと再リンクしても、バイナリ内の他のもの (たとえば、isr ルーチン) が移動しないことに注意してください。IDT を独自の専用セクションに配置して、リンカー スクリプト (.ld ファイル) でこれを管理します。

---編集--- コメントから、問題について混乱があるようです。32 ビット x86 IDT は、割り込みサービス ルーチンのアドレスが次のように 2 つの異なる 16 ビット ワードに分割されることを想定しています。

31 16 15 0
+--------------+---------------+
| | 住所 31-16 | | |
+--------------+---------------+
| | | | 住所 15-0 |
+--------------+---------------+

したがって、リンカは ISR アドレスを通常の再配置としてプラグインすることができません。そのため、起動時にソフトウェアはこの分割形式を構築する必要があり、起動時間が遅くなります。

于 2012-10-13T00:47:12.567 に答える