Linux 设备驱动 (第三版)第 11 章 内核中的数据类型11.2. 安排一个明确大小给数据项

11.2. 安排一个明确大小给数据项

11.2. 安排一个明确大小给数据项

有时内核代码需要一个特定大小的数据项, 也许要匹配预定义的二进制结构,[39] 来和用户空间通讯, 或者来用插入"填充"字段来对齐结构中的数据( 但是关于对齐问题的信息参考 "数据对齐" 一节 ).

内核提供了下列数据类型来使用, 无论你什么时候需要知道你的数据的大小. 所有的数据声明在 , 它又被 包含.


u8; /* unsigned byte (8 bits) */
u16; /* unsigned word (16 bits) */
u32; /* unsigned 32-bit value */
u64; /* unsigned 64-bit value */

存在对应的有符号类型, 但是很少需要; 如果你需要它们, 只要在名子里用 s 代替 u.

如果一个用户空间程序需要使用这些类型, 可用使用一个双下划线前缀在名子上: u8 和其它独立于 KERNEL 定义的类型. 例如, 如果, 一个驱动需要与用户空间中运行的程序交换二进制结构, 通过 ioctl, 头文件应当在结构中声明 32-位 成员为 u32.

重要的是记住这些类型是 Linux 特定的, 并且使用它们妨碍了移植软件到其他的 Unix 口味上. 使用近期编译器的系统支持 C99-标准 类型, 例如 uint8_t 和 uint32_t; 如果考虑到移植性, 使用这些类型比 Linux-特定的变体要好.

你可能也注意到有时内核使用传统的类型, 例如 unsigned int, 给那些维数与体系无关的项. 这是为后向兼容而做的. 当 u32 和它的类似物在版本 1.1.67 引入时, 开发者不能改变存在的数据结构为新的类型, 因为编译器发出一个警告当在结构成员和安排给它的值之间有一个类型不匹配时.. Linus 不希望他写给自己使用的操作系统称为多平台的; 结果是, 老的结构有时被松散的键入.

事实上, 编译器指示类型不一致, 甚至在 2 个类型只是同一个对象的不同名子, 例如在 PC 上 unsigned long 和 u32.

[39] 这发生在当读取分区表时, 当执行一个二进制文件时, 或者当解码一个网络报文时.