I/Oポートを介してハードウェアにデータを出力するための簡単なLinuxキャラクタデバイスドライバをプログラミングしています。私は浮動小数点演算を実行して、ハードウェアの正しい出力を計算する関数を持っています。残念ながら、これは、Linuxカーネルが浮動小数点演算を非常にきれいに処理しないので、私はこの関数をユーザ空間に保持する必要があることを意味します。Linuxカーネルモジュール内からuserspace関数を呼び出す
ここでは、セットアップの擬似的表現(それはちょうど私のコードの相対的なレイアウトを示し、このコードは、特定の何もしないことに注意してください)です。
ユーザ空間の機能:
char calculate_output(char x){
double y = 2.5*x;
double z = sqrt(y);
char output = 0xA3;
if(z > 35.67){
output = 0xC0;
}
return output;
}
Kernelspaceコード:
unsigned i;
for(i = 0; i < 300; i++){
if(inb(INPUT_PORT) & NEED_DATA){
char seed = inb(SEED_PORT);
char output = calculate_output(seed);
outb(output, OUTPUT_PORT);
}
/* do some random stuff here */
}
私は01を使用して考えましたはユーザー空間関数からデータを渡すが、関数呼び出しがループ内にあり、次の呼び出しがcalculate_output
になる前に多くのコードが実行されるという事実をどのように処理するかはわかりません。
私はこの作業を想定方法である:kernelspaceコードの
- メインユーザ空間のプログラムが(おそらく
ioctl
を介して)kernelspaceコードを開始する - ユーザ空間のプログラムブロック待機
- kernelspaceプログラムは、出力データのためにユーザー空間プログラムを要求し、ブロックは、
- ユーザ空間のプログラムをのブロックを解除し、(
ioctl
?)データを算出し、送信し、次いでブロック再び - kernelspaceプログラムはのブロックを解除し、
- kernelspaceプログラム終了を継続し、はユーザ空間
- ユーザ空間に通知しますはブロックをブロック解除し、次のタスクに進みます。
カーネル空間とユーザー空間の間の通信はどのようにしてブロックされるので、ユーザー空間でデバイスファイルをポーリングしてデータを送信する必要があるかどうかを確認する必要はありません。
警告:固定小数点演算は、私のコード例では、非常にうまく機能するだろうが、それは実際のコードではオプションではありません。私は浮動小数点が提供する広い範囲を必要とします。たとえそうでないとしても、固定小数点演算を使用するコードを書き直すことは、将来のメンテナのためのアルゴリズムを難読化することになります。
あなたはほとんどすべてのものをユーザスペースに持つことができますし、カーネルのインターフェースイネーブラーを薄くできますか? –
@ChrisStrattonそれは私が達成しようとしているものです。 forループ内で発生するものは、その他のハードウェア出力(単純なoutb呼び出しとそれ以外のもの)です。 –
@ChrisStrattonああ、あなたはカーネルの外で 'for'ループを動かすことを意味しますか? –