ゼロ除算のカーネルソースコード(2.6.35)を調べています。
ユーザースペースプログラムにゼロ除算を挿入すると、すべてのスレッドが停止しました。
だから私はArmCortexA-9のカーネルで「ゼロディバイド」がどこで行われているのか知りたいですか?
このためのトラップを見つけることができません...。
ありがとう
ゼロ除算のカーネルソースコード(2.6.35)を調べています。
ユーザースペースプログラムにゼロ除算を挿入すると、すべてのスレッドが停止しました。
だから私はArmCortexA-9のカーネルで「ゼロディバイド」がどこで行われているのか知りたいですか?
このためのトラップを見つけることができません...。
ありがとう
アーキテクチャによって異なります。x86システムで次のユーザースペースコードがあるとします。
main() {
int x = 42 / 0;
}
コンパイラはidivl
コマンドをオブジェクトコードに挿入します。このコマンドが除数0で実行されると、CPUはゼロ除算トラップを生成します(割り込みと同様)。これによりdivide_error
、カーネル内のトラップハンドラーが呼び出されます。x86の場合は、次の場所にありarch/x86/kernel/entry_32.S
ます。
ENTRY(divide_error)
RING0_INT_FRAME
pushl_cfi $0 # no error code
pushl_cfi $do_divide_error
jmp error_code
CFI_ENDPROC
END(divide_error)
次に、error_code
ターゲットはエラーを処理するために必要なすべてのアクションを処理し、最終的にトラップから戻ります。
ARMでは、状況が異なります。いくつかの例外を除いて、ARM CPUにはハードウェア除算命令がありません(たとえば、Arm Cortex A-9にはハードウェア除算命令がありません)。分割はライブラリ関数として実装する必要があります。カーネルの場合、これはarch/arm/lib/lib1funcs.S
ゼロ除算もある場所に実装されています。ユーザースペースアプリケーションの場合、これはlibgccライブラリのライブラリ関数として実装されていると思います。