Linux Data Alignment

The last problem to write portable code is worth considering how to access misaligned data - for example, how to read a 4 byte value stored in the address is not a multiple of 4 bytes i386 users often unaligned accesses. data items, but not all systems allow this many modern systems generate an exception, each time the program tries unaligned data transfer time; the data transfer is handled by exception handling, a great deal of sacrifice performance if you need to access. unaligned data, you should use the following macro:

 

#include <asm/unaligned.h> get_unaligned(ptr); put_unaligned(val, ptr);

 

These macros are untyped, and with each data item, whether it be one, two, four, or eight bytes long. They are defined in any kernel version.

 

Another problem is the alignment of the data structure of cross-platform portability. The same data structure (defined in the C- language source file) may be different on different platforms compiler compiler be structured according to the different respective platform conventions member alignment.

 

In order to write a data structure that can move data across the system used, you should always enforce natural alignment of data items, plus standardization of a particular alignment of Natural alignment means storing data items in the address of an integer multiple of its size (e.g., 8-byte entries in integer multiples of the address. 8). to force natural alignment while preventing the compiler in an undesirable manner arranged members amount, you should use stuffers members to avoid leaving in the data structure the next hole.

 

To demonstrate how to force the compiler to align, dataalign release program in misc-progs source directory, and a peer kdataalign module is part of the misc-modules, which is the output of the program on several platforms and output modules in the SPARC64 :

 

 

249

 

 

arch Align:

char

short

int

long

ptr

long-long

u8

U16

u32

u64

i386

1

2

4

4

4

4

1

2

4

4

i686

1

2

4

4

4

4

1

2

4

4

alpha

1

2

4

8

8

8

1

2

4

8

Armw4l

1

2

4

4

4

4

1

2

4

4

ia64

1

2

4

8

8

8

1

2

4

8

mips

1

2

4

4

4

8

1

2

4

8

ppc

1

2

4

4

4

8

1

2

4

8

sparc

1

2

4

4

4

8

1

2

4

8

sparc64

1

2

4

4

4

8

1

2

4

8

x86_64

1

2

4

8

8

8

1

2

4

8

 

kernel: arch Align: char short int long ptr long-long u8 u16 u32 u64 kernel: sparc64     1    2     4   8    8   8         1  2   4   8

 

Interesting to note that not all platforms are aligned 64-bit values ​​on 64-bit boundaries, so you need to fill those members to enforce alignment and ensure portability.

 

Finally, we know that the compiler may insert themselves quietly filled structure to ensure that each member is aligned to the good performance of the target processor. Device to match a desired structure if you intend to define a structure, this automatic filling may hamper your attempts. the solution to this problem is to tell the compiler that this structure must be "compact" and can not increase stuffers. For example, the kernel header file <linux / edd.h> defines several data and x86 BIOS interface structure, and it contains the following definitions:

 

 

struct

{

 

 

 

 

}


 

 

u16 id; u64 lun;

u16 reserved1;

u32 reserved2;

 

    attribute   ((packed)) scsi;

 

If no attribute ((packed)), lun two members may be added in front or bytes stuffers

6, if we compile on 64 bit platforms this structure.

Guess you like

Origin www.cnblogs.com/fanweisheng/p/11146096.html