Linux kernel 2.6.39 + CodeSourcery 2011.03-41 = … Continue.

After some investigation I found that by default Linux kernel uses software handlers (traps) for unaligned memory loads. [1] What does it mean? It means that by default for ARM processors “A bit” in Control Register is set to 1.From “Cortex-A8 Technical Reference Manual” [2]:

[1] | A bit | Banked | Enables strict alignment of data to detect alignment faults in data accesses:
0 = strict alignment fault checking disabled, reset value
1 = strict alignment fault checking enabled.

So at the moment we have default software handling for unaligned memory access faults in kernel and new CodeSourcery 2011.03-41 cross-compiler with “Unaligned access support” feature enabled by default. As I understand, It means that compiler tries to optimize unaligned memory access with assumption that “A bit” in Control Register is unset (reset value) and hardware should handle all unaligned memory loads. But this bit is set by Linux kernel, thus, after memory access optimisation by cross-compiler ARM processor generates alignment faults, which are handled by software traps in kernel.

There are two solutions for this issue. The first one is described in my previous post (“-mno-unaligned-access” parameter). And the second is to disable alignment faults checking in Linux kernel (clear “A bit” in Control Register). I think the second solution is more preferable as hardware unaligned loads support is much faster than software handling. After some investigation I found that alignment traps generation can be controlled using “ALIGNMENT_TRAP” kernel config parameter in “arch/arm/Kconfig”, but this parameter is by default true and it can’t be configured in menuconfig. In order to be able to change it’s value just add “Software alignment trap” text after “bool”:

config ALIGNMENT_TRAP
bool “Software alignment trap”

And unset it in menuconfig:

Kernel Features —>
    [ ] Software alignment trap


After that recompile your kernel. You can check if alignment fault checking is disabled or not in kernel traces:

[ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7f

Here “cr=…” is a value of ARM’s Control Register. As you can see “A bit” (bit #1) is set (0x7f = b01111111). After disabling alignment fault checking you should see something like that:

[ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7d

Here 0x7d = b01111101 – “A bit” is unset.

P.S. According to kernel documentation disabling alignment fault checking can lead to some unpredictable behavior in some network protocols. At the moment I’m trying to stabilize and test 2.6.39 kernel compiled with CodeSourcery 2011.03-41.

[1] - Linux kernel documentation (“Documentation/unaligned-memory-access.txt”).
[2] – Cortex-A8 Technical Reference Manual.

from:http://blog.galemin.com/tag/codesourcery/

你可能感兴趣的:(Linux kernel 2.6.39 + CodeSourcery 2011.03-41 = … Continue.)