このページはWritingPortableDriversセクションの一部です。
カーネル内で使用されるデータ型
移植性の高いコードを書くときに覚えておきたいもっとも基本的なルールは、 変数の大きさをどのくらいにする必要があるかに気を付けるというものです。 データ型intとlongの変数のサイズは、プロセッサごとに異なります。 さらに変数には、符号付き、符号なしといった違いもあります。このため、変数の サイズを一定のビット数にする必要があり、符号付きか符号なしのどちらかに しなければならない場合、組み込みのデータ型を使用する必要があります。 次に示すtypedefされたデータ型はヘッダファイルlinux/types.hで定義されていて、 カーネルコードのどこででも使用することができます。
u8 unsigned byte (8 bits) u16 unsigned word (16 bits) u32 unsigned 32-bit value u64 unsigned 64-bit value s8 signed byte (8 bits) s16 signed word (16 bits) s32 signed 32-bit value s64 signed 64-bit value
たとえば、i2cドライバサブシステムには次のような関数があり、i2cバス上の データ送受信に使用されています。
これらの関数はすべて符号付き32ビット値を返し、パラメータのvalueとcommandは どちらも符号なし8ビット値を取ります。このコードはこれらのデータ型を使用して いるおかげで、どのような種類のプロセッサへも移植することができます。
ユーザ空間のプログラムで参照される可能性のあるコードの中で変数を使用する 場合は、次のような外部から利用可能なデータ型を使用する必要があります。 このデータ型の使用例は、ioctl()呼び出しを介して受け渡されるデータ構造に 見られます。これらのデータ型もヘッダファイルlinux/types.hで定義されています。
__u8 unsigned byte (8 bits) __u16 unsigned word (16 bits) __u32 unsigned 32-bit value __u64 unsigned 64-bit value __s8 signed byte (8 bits) __s16 signed word (16 bits) __s32 signed 32-bit value __s64 signed 64-bit value
FIXME __le16とその仲間たちを追加すること
たとえば、ヘッダファイルusbdevice_fs.hには、ユーザ空間のプログラムがUSBデバイス と直接話すときに使用される、さまざまな構造体が定義されています。次に示すのは デバイスにUSBコントロールメッセージを送信するために使用されるioctlの定義です。
64ビットマシンがさらに普及してきたことで、ポインタのサイズが符号なし整数の サイズと同じではないために数多くの問題が発生しました。ポインタのサイズは unsigned longのサイズと等しくなります。これはget_zeroed_page()のプロトタイプ 宣言に見ることができます。
extern unsigned long FASTCALL (get_zeroed_page(unsigned int gfp_mask))
get_zeroed_page()はゼロで初期化された割り当て可能なメモリページを 返します。この関数はunsigned longを返し、その値はおそらく特定のデータ型に キャストされるはずです。その方法は、次に示すdrivers/char/serial.cで 定義されているrs_open()関数のコードの断片に見ることができます。
FIXME この例は2.4の頃の古い例である。
unsigned longの代わりに使用すべきネイティブなカーネルデータ型がいくつかあります。 以下に示すのはその一部です。
pid_t, key_t, gid_t, size_t, ssize_t, ptrdiff_t, time_t, clock_t, and caddr_t.
あなたのコードの中でこれらの型のどれかを使用する必要があるときは、そのデータ 型を使用してください。そうすることで多くの問題を避けることができるでしょう。