在内核源码中,看到了typedef __u16 __bitwise __le16;那么,__le16是什么类型呢?

本文主要记录内核中处理大小端相关的内容。

Why Worry About Byte Order

In general, the underlying byte order of the processor is completely transparent to the programmer. However, there can be a problem, for example, when data is exchanged with another system, since the other system may interpret multi-byte values differently.

For example, since it is not possible to predict the type of system at either end of the network, network protocols must define the byte order that is used for multi-byte values in their headers. This is called the network byte order, and for TCP/IP, it is big endian. Thus, the sending system converts the data from it local byte order to the network byte order. Then, the receiving system converts the data from network byte order to its local byte order. In practice, if either system uses the same byte order as the network byte order, the conversion operation is optimized out and no conversion takes place.

Another example is the USB protocol, which defines that multi-byte values will use the little endian byte order.

Interfaces

The following type identifiers correspond to the u16, u32, and u64 types, except they are defined with the bitwise attribute, which is used to restrict their use as integers. The bitwise attribute is used by the sparse utility to make sure the variable is converted to the local processor type before other (unsafe) operations are performed on the variable.

1
2
3
4
5
6
7
__le16
__le32
__le64

__be16
__be32
__be64

其中,be代表big end,le代表low end。

For example, if you want to add a constant to a__le16 type, you can do so, but you have to use the proper sequence:

1
2
3
__le16 sum, a, b; 
sum = a + b; /* INVALID! "warning: incompatible types for operation \(+)" */
sum = cpu_to_le16(le16_to_cpu(a) + le16_to_cpu(b)); /* Ok */

The following macros return the value after it has been converted.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <linux/kernel.h>

__u16 le16_to_cpu(const __le16);
__u32 le32_to_cpu(const __le32);
__u64 le64_to_cpu(const __le64);

__le16 cpu_to_le16(const __u16);
__le32 cpu_to_le32(const __u32);
__le64 cpu_to_le64(const __u64);

__u16 be16_to_cpu(const __be16);
__u32 be32_to_cpu(const __be32);
__u64 be64_to_cpu(const __be64);

__be16 cpu_to_be16(const __u16);
__be32 cpu_to_be32(const __u32);
__be64 cpu_to_be64(const __u64);


参考资料:

  1. stackoverflow
  2. Byte Order
  3. SparseAnnotations