1

ゼロ除算のカーネルソースコード(2.6.35)を調べています。

ユーザースペースプログラムにゼロ除算を挿入すると、すべてのスレッドが停止しました。

だから私はArmCortexA-9のカーネルで「ゼロディバイド」がどこで行われているのか知りたいですか?

このためのトラップを見つけることができません...。

ありがとう

4

1 に答える 1

10

アーキテクチャによって異なります。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ライブラリのライブラリ関数として実装されていると思います。

于 2012-09-21T08:38:24.167 に答える