之所以要关注数据类型,主要是要解决程序可移植性的问题。Linux是可以用在多个平台上的,因此要保证驱动程序具有可移植性。
内核中使用的数据类型主要包括以下三类:
- 标准C语言类型(例如:int)
- 确定大小的类型(例如:u32)
- 特定内核对象类型(例如:pid_t)
1. 标准C语言类型
在我们需要使用确定长度的数据时,我们不应该使用标准C语言类型,因为在不同架构上,标准类型所占的空间大小是不一样的。常见平台的标准类型所占空间的见下表:
arch | char | short | int | long | ptr | long-long | u8 | u16 | u32 | u64 |
---|---|---|---|---|---|---|---|---|---|---|
i386 | 1 | 2 | 4 | 4 | 4 | 8 | 1 | 2 | 4 | 8 |
alpha | 1 | 2 | 4 | 8 | 8 | 8 | 1 | 2 | 4 | 8 |
armv41 | 1 | 2 | 4 | 4 | 4 | 8 | 1 | 2 | 4 | 8 |
ia64 | 1 | 2 | 4 | 8 | 8 | 8 | 1 | 2 | 4 | 8 |
m68k | 1 | 2 | 4 | 4 | 4 | 8 | 1 | 2 | 4 | 8 |
mips | 1 | 2 | 4 | 4 | 4 | 8 | 1 | 2 | 4 | 8 |
ppc | 1 | 2 | 4 | 4 | 4 | 8 | 1 | 2 | 4 | 8 |
sparc | 1 | 2 | 4 | 4 | 4 | 8 | 1 | 2 | 4 | 8 |
sparc64 | 1 | 2 | 4 | 4 | 4 | 8 | 1 | 2 | 4 | 8 |
x86_64 | 1 | 2 | 4 | 8 | 8 | 8 | 1 | 2 | 4 | 8 |
通常来说,地址是指针类型的(ptr),但我们经常在使用过程中使用unsigned long
来表示一个地址,这是基于:目前平台上,指针类型的数据长度和long类型的数据长度是相同的。
2. 确定大小类型
对于需要特定长度大小的数据,内核提供了以下数据类型:
#include <asm/types.h> // 该头文件包含在 <linux/types.h>中
u8; /** 无符号8位 */
u16; /** 无符号16位 */
u32; /** 无符号32位 */
u64 /** 无符号64位 */
s8; /** 有符号8位 */
s16; /** 有符号16位 */
s32; /** 有符号32位 */
s64 /** 有符号64位 */
以上类型是Linux中所特有的,其他Unix变种并不包含,因此会影响驱动程序往其他Unix程序移植。
使用新编译器的系统支持C99标准类型,例如uint8_t和uint32_t;如果考虑可移植性,可以使用这些类型。