这一节主要讲linux的数据类型,主要是为了方便理解接下来将大端、小段字节序定义的源码。
首先,来看看 include/linux/types.h 源码:
------------------------------------------------------------------
#ifndef _LINUX_TYPES_H
#define _LINUX_TYPES_H
#include <asm/types.h>
#ifndef __ASSEMBLY__
#include <linux/posix_types.h>
/*
* Below are truly Linux-specific types that should never collide with
* any application/library that wants linux/types.h.
*/
#ifdef __CHECKER__
#define __bitwise__ __attribute__((bitwise))
#else
#define __bitwise__
#endif
#ifdef __CHECK_ENDIAN__
#define __bitwise __bitwise__
#else
#define __bitwise
#endif
//_be32只是一个带有bitwise属性的整型类型,
//而这个属性对gcc本身没有任何作用,
//所以如果不利用sparse,__be32和__u32没有任何差别,
//但是如果利用sparse,它就能提供一种超强制的类型匹配检查。
typedef __u16 __bitwise __le16;
typedef __u16 __bitwise __be16;
typedef __u32 __bitwise __le32;
typedef __u32 __bitwise __be32;
typedef __u64 __bitwise __le64;
typedef __u64 __bitwise __be64;
typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;
/*
* aligned_u64 should be used in defining kernel<->userspace ABIs to avoid
* common 32/64-bit compat problems.
* 64-bit values align to 4-byte boundaries on x86_32 (and possibly other
* architectures) and to 8-byte boundaries on 64-bit architetures. The new
* aligned_64 type enforces 8-byte alignment so that structs containing
* aligned_64 values have the same alignment on 32-bit and 64-bit architectures.
* No conversions are necessary between 32-bit user-space and a 64-bit kernel.
*/
#define __aligned_u64 __u64 __attribute__((aligned(8)))
#define __aligned_be64 __be64 __attribute__((aligned(8)))
#define __aligned_le64 __le64 __attribute__((aligned(8)))
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */
-----------------------------------------------------------------------------------
注意到 include/linux/types.h 源码中包含有 #include <asm/types.h>,那我们就来看看 asm/types.h(以x86为例子)
---------------------------------------
#ifndef _ASM_X86_TYPES_H
#define _ASM_X86_TYPES_H
#include <asm-generic/types.h>
#endif /* _ASM_X86_TYPES_H */
----------------------------------------------
同样,查看 asm-generic/types.h
-----------------------------------------------------------------
#ifndef _ASM_GENERIC_TYPES_H
#define _ASM_GENERIC_TYPES_H
/*
* int-ll64 is used practically everywhere now,
* so use it as a reasonable default.
*/
#include <asm-generic/int-ll64.h>
#ifndef __ASSEMBLY__
typedef unsigned short umode_t;
#endif /* __ASSEMBLY__ */
#endif /* _ASM_GENERIC_TYPES_H */
-------------------------------------------------------------------
查看 asm-generic/int-ll64.h (为使用“long long”64位类型的架构做出整数声明)
-----------------------------------------------------------------------------------
/*
* asm-generic/int-ll64.h
*
* Integer declarations for architectures which use "long long"
* for 64-bit types.
*/
#ifndef _ASM_GENERIC_INT_LL64_H
#define _ASM_GENERIC_INT_LL64_H
#include <asm/bitsperlong.h>
#ifndef __ASSEMBLY__
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
* header files exported to user space
*/
typedef __signed__ char __s8;
typedef unsigned char __u8;
typedef __signed__ short __s16;
typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
#ifdef __GNUC__
__extension__ typedef __signed__ long long __s64;
__extension__ typedef unsigned long long __u64;
#else
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
#endif /* _ASM_GENERIC_INT_LL64_H */
-----------------------------------------------------------------------
关于 asm/bitsperlong.h ,可以查看另一篇博文:linux源码分析之字节序
小结:
本文主要介绍了linux中对于一些数据类型的宏定义,其中像 _le16 代表的是 小端字节序的2字节无符号类型,而 _be16 代表的是 大端字节序的2字节无符号类型,依次类推。