我们知道,在Linux内核中,不同CPU里面,不同CPU的字节序定义不同。
本节年内容主要是讲的是:不同CPU里面,各自的位长定义也是不同。
本次用于分析的 Linux 内核版本为: linux--3.0.0-12。
arch/XXX/include/asm/bitsperlong.h:不同CPU(XXX)的位长定义
1)ARM(XXX=arm):
#include <asm-generic/bitsperlong.h>
(2)PowerPC(XXX=powerpc)
#ifndef __ASM_POWERPC_BITSPERLONG_H
#define __ASM_POWERPC_BITSPERLONG_H
#if defined(__powerpc64__)
# define __BITS_PER_LONG 64
#else
# define __BITS_PER_LONG 32
#endif
#include <asm-generic/bitsperlong.h>
#endif /* __ASM_POWERPC_BITSPERLONG_H */
(3)X86(XXX=x86)
#ifndef __ASM_X86_BITSPERLONG_H
#define __ASM_X86_BITSPERLONG_H
#ifdef __x86_64__
# define __BITS_PER_LONG 64
#else
# define __BITS_PER_LONG 32
#endif
#include <asm-generic/bitsperlong.h>
#endif /* __ASM_X86_BITSPERLONG_H */
由上面举的3个例子,可以看出三种不同的CPU对于各自的位长定义有所不同。
接下来我们来看看 asm-generic/bitsperlong.h, 源码如下
#ifndef __ASM_GENERIC_BITS_PER_LONG
#define __ASM_GENERIC_BITS_PER_LONG
/*
* There seems to be no way of detecting this automatically from user
* space, so 64 bit architectures should override this in their
* bitsperlong.h. In particular, an architecture that supports
* both 32 and 64 bit user space must not rely on CONFIG_64BIT
* to decide it, but rather check a compiler provided macro.
*/
#ifndef __BITS_PER_LONG
#define __BITS_PER_LONG 32
#endif
#endif /* __ASM_GENERIC_BITS_PER_LONG */
该头文件说明:一个支持32和64位用户空间的架构,不能像依靠 CONFIG_64BIT 来决定位长,而是检查编译器提供的宏。
小结:即是先检查 arch/XXX/include/asm/bitsperlong.h, 看CPU是否定义了位长,若没有定义,则按照 asm-generic/bitsperlong.h 来决定。
(该例子是只要 arch/XXX/include/asm/bitsperlong.h 中没定义,asm-generic/bitsperlong.h 都定义位长为32)