首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

Linux内核在体系结构差异较大的平台之间移植时,会产生与数据类型相关的问题。在编译内核时使用 -Wall -Wstrict-prototypes选项,可以避免很多错误的发生。

内核使用的基本数据类型主要有:

ØØ int          标准C语言整数类型;

ØØ u32         32位整数类型;

ØØ pid_t              特定内核对象pid的类型。

在不同的CPU体系结构上,C语言的数据类型所占空间不一样。下面是在x86下数据类型所占的字节数:

arch

char

short

int

long

ptr

long-long

u8

u16

u32

u64

i686

1

2

4

4

4

8

1

2

4

8

下面是在其他平台上的数据类型所占的字节数:

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

armv4l

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

其中基于sparc64平台的Linux用户空间可以运行32位代码,用户空间指针是32位宽的,但内核空间是64位的。

内核中的地址是unsigned long类型,指针大小和long类型相同。

内核提供下列数据类型。所有类型在头文件<asm/types.h>中声明,这个文件又被头文件<Linux/types.h>所包含。下面是include/asm/types.h文件。

 

#ifndef _I386_TYPES_H

#define _I386_TYPES_H

 

#ifndef __ASSEMBLY__

 

typedef unsigned short umode_t;

 

// 下面__xx类型不会损害POSIX 名字空间,在头文件使用它们,可以输出显露给用户空间

typedef __signed__ char __s8;

typedef unsigned char __u8;

 

typedef __signed__ short __s16;

typedef unsigned short __u16;

 

typedef __signed__ int __s32;

typedef unsigned int __u32;

 

#if defined(__GNUC__) && !defined(__STRICT_ANSI__)

typedef __signed__ long long __s64;

typedef unsigned long long __u64;

#endif

 

#endif /* __ASSEMBLY__ */

 

//下面的类型只用在内核中,否则会产生名字空间崩溃

#ifdef __KERNEL__

 

#define BITS_PER_LONG 32

 

#ifndef __ASSEMBLY__

 

#include <Linux/config.h>

 

typedef signed char s8;

typedef unsigned char u8;

 

typedef signed short s16;

typedef unsigned short u16;

 

typedef signed int s32;

typedef unsigned int u32;

 

typedef signed long long s64;

typedef unsigned long long u64;

 

/* DMA addresses come in generic and 64-bit flavours.  */

#ifdef CONFIG_HIGHMEM64G

typedef u64 dma_addr_t;

#else

typedef u32 dma_addr_t;

#endif

typedef u64 dma64_addr_t;

 

#ifdef CONFIG_LBD

typedef u64 sector_t;

#define HAVE_SECTOR_T

#endif

 

typedef unsigned short kmem_bufctl_t;

 

#endif /* __ASSEMBLY__ */

#endif /* __KERNEL__ */

#endif

 

下面是Linux/types.h的部分定义。

 

 

#ifndef _LINUX_TYPES_H

#define _LINUX_TYPES_H

 

#ifdef   __KERNEL__//这个宏定义必须在#include < asm /types.h>之前

#include <Linux/config.h>

 

#define BITS_TO_LONGS(bits) \

     (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)

#define DECLARE_BITMAP(name,bits) \

     unsigned long name[BITS_TO_LONGS(bits)]

#endif

 

#include <Linux/posix_types.h>

#include <asm/types.h>

 

u8;   /* unsigned byte (8 bits) */

u16;  /* unsigned word (16 bits) */

u32;  /* unsigned 32-bit value */

u64;  /* unsigned 64-bit value */

 

使用有前缀的类型用于将变量显露给用户空间,如_ _u8类型。例如:一个驱动程序通过ioctl函数与运行在用户空间的程序交换数据,应该用_ _u32来声明32位的数据类型。

有时内核使用C语言的类型,如unsigned int,这通常用于大小独立于体系结构的数据项。

内核中许多数据类型由typedef声明,这样方便移植。如使用pid_t类型作为进程标志符(pid)的类型,而不是int类型,pid_t屏蔽了在不同平台上的实际数据类型的差异。

如果不容易选择合适的类型,就将其强制转换成最可能的类型(longunsigned long)。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论