1
votes

I'm building an embedded Linux, and I'm encountering an error caused by the LMA and VMA addresses of various sections not being equal:

> /opt/tc/uclibc-crosstools-gcc-4.6/usr/bin/mips-linux-uclibc-objdump -h vmlinux
...
9  __modver      00000470  802b6b90  802b6b90  002aab90  2**0
                 ALLOC
10 .data         002f5e20  802b8000  802b7b90  002abb90  2**14
                 CONTENTS, ALLOC, LOAD, DATA
11 .init.text    0001c020  805ae000  805adb90  005a1b90  2**2
                 CONTENTS, ALLOC, LOAD, READONLY, CODE
...

The problem I'm having is that the auto generated linker script (arch/mips/kernel/vmlinux.lds) has the following line:

 .init.data : AT(ADDR(.init.data) - 0) { ...}

Which to me would indicate that the .init.text VMA should be equal to the .init.text LMA. I also tried to manually add an AT for .data, such that I had .data : AT(ADDR(.data)) in the script, but that doesn't shift .data back to the correct location either. One item of interest is that the LMA and VMA's differ by 0x470 bytes, which is exactly the size of the __modver section. Can anyone shed any light on why I'm getting this behavior?

(I'm using buildroot 2011.11, uClibc 0.9.32.1, gcc 4.6, and linux 3.2 for a mips architecture.)

Thanks

John

1

1 Answers

1
votes

So, I'm answering my own question in case someone else comes across the same issue, it might save them some time -- it turns out there is a bug in the linker. The modver section was empty, but contained an ALIGN directive. It appears as though this confuses the linker, and it throws off the LMA's of all subsequent sections. The solution to this was to force a single byte variable to be included in modver (but not between start_modver and end_modver -- otherwise you introduce new problems...). This fixes the problem. The linker will eventually have to be fixed.

John