linux源码分析之字节序(2)-- types.h

时间:2022-08-31 17:04:07
这一节主要讲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字节无符号类型,依次类推。