Assigning an Explicit Size to Data Items

Sometimes kernel code requires data items of a specific size, either to match predefined binary structures[39] or to align data within structures by inserting “filler” fields (but please refer to Section 10.4.4 later in this chapter for information about alignment issues).

The kernel offers the following data types to use whenever you need to know the size of your data. All the types are declared in <asm/types.h>, which in turn is included by <linux/types.h>:

u8;   /* unsigned byte (8 bits) */
u16;  /* unsigned word (16 bits) */
u32;  /* unsigned 32-bit value */
u64;  /* unsigned 64-bit value */

These data types are accessible only from kernel code (i.e., __KERNEL__ must be defined before including <linux/types.h>). The corresponding signed types exist, but are rarely needed; just replace u with s in the name if you need them.

If a user-space program needs to use these types, it can prefix the names with a double underscore: __u8 and the other types are defined independent of __KERNEL__. If, for example, a driver needs to exchange binary structures with a program running in user space by means of ioctl, the header files should declare 32-bit fields in the structures as __u32.

It’s important to remember that these types are Linux specific, and using them hinders porting software to other Unix flavors. Systems with recent compilers will support the C99-standard types, such as uint8_t and uint32_t; when possible, those types should be used in favor of the Linux-specific variety. If your code must work with 2.0 kernels, however, use of these types will not be possible (since only older compilers work with 2.0).

You might also note that sometimes the kernel uses conventional types, such as unsigned int, for items whose dimension is architecture independent. This is usually done for backward compatibility. When u32 and friends were introduced in version 1.1.67, the developers couldn’t change existing data structures to the new types because the compiler issues a warning when there is a type mismatch between the structure field and the value being assigned to it.[40] Linus didn’t expect the OS he wrote for his own use to become multiplatform; as a result, old structures are sometimes loosely typed.



[39] This happens when reading partition tables, when executing a binary file, or when decoding a network packet.

[40] As a matter of fact, the compiler signals type inconsistencies even if the two types are just different names for the same object, like unsigned long and u32 on the PC.

Get Linux Device Drivers, Second Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.