Byte ordering is the order of bytes within a word. Processors can number the bytes in a word such that the least significant bit is either the first (left-most) or last (right-most) value in the word. The byte ordering is called big-endian if the most significant byte is encoded first, with the remaining bytes decreasing in significance. The byte ordering is called little-endian if the least significant byte is encoded first, with the remaining bytes growing in significance.
Do not ever assume any given byte ordering when writing kernel code (unless you are writing code for a specific architecture, of course). The Linux kernel supports machines of both byte ordersincluding machines that can select from either ordering upon bootand generic code must be compatible with either.
Figure 19.1. Big-endian byte ordering.
Figure 19.2. Little-endian byte ordering.
The i386 architecture is little-endian. Most other architectures are big-endian.
00000000 00000000 00000100 00000011
The internal storage in memory is different on big- versus little-endian, as shown in Table 19.3.
Notice how the big-endian architecture stores the most significant bytes in its smallest address. This is the exact inverse of little-endian.
As a final example, here is a simple code snippet to test whether a given architecture is big- or little-endian:
int x = 1; if (*(char *)&x == 1) /* little endian */ else /* big endian */
History of Big- and Little-Endian
The terms big-endian and little-endian derive from Jonathan Swift's 1726 satirical novel, Gulliver's Travels. In the novel, the fictional Lilliputians' major political issue is whether eggs should be cracked open on the big end or the little end. Those who favor the big end are big-endians, whereas those who favor the small are little-endians.
The similarity between the Lilliputians and our big-endian versus little-endian debate is that the argument is rooted deeper in politics than technical merits.
Byte Ordering in the Kernel
This header file also includes a family of macros from include/linux/byteorder/, which help with conversions to and from the various orderings. The most commonly needed macros are
u23 __cpu_to_be32(u32); /* convert cpu's byte order to big-endian */ u32 __cpu_to_le32(u32); /* convert cpu's byte order to little-endian */ u32 __be32_to_cpu(u32); /* convert big-endian to cpu's byte order */ u32 __le32_to_cpus(u32); /* convert little-endian to cpu's byte order */
These convert from one byte order to another. In the case that the orders are the same (for example, if converting from native ordering to big-endian, and the processor is big-endian), the macros do nothing. Otherwise, they return the converted value.