设为首页 加入收藏

TOP

Linux内核--内核数据类型
2014-11-24 02:01:49 来源: 作者: 【 】 浏览:0
Tags:Linux 内核 数据 类型

将Linux 移植到新的体系结构时,开发者遇到的若干问题都与不正确的数据类型有关。坚持使用严格的数据类型和使用 -Wall -Wstrict-prototypes 进行编译可能避免大部分的 bug。


内核数据使用的数据类型主要分为3个类型: 标准C语言类型确定大小的类型特定内核对象的类型


当需要“一个2字节填充符”或“用一个4字节字串来代表某个东西”,就不能使用标准C语言类型,因为在不同的体系结构,C 语言的数据类型所占的空间大小不同。而且有的构架,内核空间和用户空间的C数据类型所占空间大小也可能不同。


内核:当需要知道你定义的数据的大小时,可以使用内核提供的下列数据类型:


内核中最常用的数据类型由它们自己的 typedef 声明,阻止了任何移植性问题。
“接口特定(interface-specific)”由某个库定义的一种数据类型, 以便为了某个特定的数据结构提供接口。
注意


当处理时间间隔时,不要假定每秒的jiffies个数,不是每个 Linux 平台都以固定的速度运行。当计算时间间隔时,要使用 HZ ( 每秒的定时器中断数 ) 来标定你的时间。


当使用内存时,记住一个内存页是 PAGE_SIZE 字节, 不是 4KB。相关的宏定义是 PAGE_SIZE 和 PAGE_SHIFT(包含将一个地址移位来获得它的页号的位数)。如果用户空间程序需要这些信息,可以使用 getpagesize 库函数。
若一个驱动需要 16 KB 来暂存数据,一个可移植得解决方法是 get_order:


不要假设字节序。 代码应该编写成不依赖所操作数据的字节序的方式。
头文件定义:


但是还有一个更好的方法:Linux 内核有一套宏定义来处理处理器字节序和特定字节序之间的转换。例如:
u32 cpu_to_le32 (u32);
u32 le32_to_cpu (u32);

/*这些宏定义将一个CPU使用的值转换成一个无符号的32位小头数值,无论 CPU 是大端还是小端,也不管是不是32 位处理器。在没有转换工作需要做时,返回未修改的值。*/


编写可移植代码而值得考虑的最后一个问题是如何访问未对齐的数据。存取不对齐的数据应当使用下列宏:
#include
get_unaligned(ptr);
put_unaligned(val, ptr);

这些宏是无类型的,并对各总数据项,不管是 1、2、4或 8 个字节,他们都有效,并且在所有内核版本中都有定义。

关于对齐的另一个问题是数据结构的跨平台移植性。同样的数据结构在不同的平台上可能被不同地编译。为了编写可以跨体系移植的数据结构,应当始终 制数据项的自然对齐。
自然对齐(natural alignment)指的是:数据项大小的整数倍的地址上存储数据项。 应当使用填充符避免强制自然对齐时编译器移动数据结构的字段,在数据结构中留下空洞。

为了目标处理器的良好性能,编译器可能悄悄地插入填充符到结构中,来保证每个成员是对齐的。若定义一个和设备要求的结构体相匹配结构,自动填充符会破坏这个意图。解决这个问题的方法是告诉编译器这个结构必须是"紧凑的", 不能增加填充符。例如下列的定义:


相关阅读


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Tiny6410声卡驱动——录音与回放 下一篇C语言中如何将字符串转换成float..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: