problem with crt0.o in 4.9.3 and thumb mode
Hello,
I have a question regarding crt0.o from gnu arm 4.9.3 for thumb (cortex-m3). When I finally got the software compiled and linked it would not start up. After initialising the RAM variables from ROM the startup code (from the /share directory) jumps to the label _start which I believe is in crt0.o. The second assembler instruction after _start is a jump into nirvana which leads to an exception. In my case _start ended up on address 0xb4 and the code there looked like this:
...
0x000000b4 30d8 adds r0,r0,#0xd8
0x000000b6 e59f b 0xfffffbf8
...
So I simply wrote the stack initialisation and the .bss initilisation inside the startup code and replaced the jump to _start by a jump to main. This seems to work.
My question now is: do I have to do anything else that crt0.o or crtbegin.o would have done?
Kind Regards,
Question information
- Language:
- English Edit question
- Status:
- Solved
- Assignee:
- No assignee Edit question
- Solved by:
- hugo
- Solved:
- Last query:
- Last reply:
Revision history for this message
|
#1 |
Hi Hugo,
I am not getting the code sequence you gave when compiling with -mcpu=cortex-m3 -mthumb -specs=
Best regards,
Thomas
Revision history for this message
|
#2 |
Hi Thomas,
thank you for your reponse.
Compile for all c files is:
/usr/arm/
Linking command line:
/usr/arm/
Linker script lpclnk.ld is copied from 4.9.3 distribution with only memory addresses and sizes changed and startup code lpcstt.sx is the cortex-m3 version also from 4.9.3.
I use nano.specs now but without --specs that I got the same result. I experimented with all varieties because printf("%d") is also causing an exeption. Figured writing my own printf() is the fastest way out.
Map file excerpt:
.text 0x00000000 0xf210
*(.isr_vector)
.isr_vector 0x00000000 0x44 lpcstt.o
*(.text*)
.text 0x00000044 0x0 /usr/arm/
.text 0x00000044 0x70 /usr/arm/
.text 0x000000b4 0xfc /usr/arm/
.text 0x000001b0 0x48 lpcstt.o
.......
Code in memory:
0x000000B4 30D8 ADDS r0,r0,#0xD8
0x000000B6 E59F B 0xFFFFFBF8
0x000000B8 0000 MOVS r0,r0
0x000000BA E353 B 0x00000764
0x000000BC 30CC ADDS r0,r0,#0xCC
0x000000BE 059F LSLS r7,r3,#22
0x000000C0 D003 BEQ 0x000000CA
0x000000C2 E1A0 B 0x00000406
......
Second statement is wrong already; somehow the linker inserted the wrong address.
OS is Centos 6.6 (RHEL) 64 bit processor.
Don't spend too much time on this; imho the gnu tools for arm seem to be a bit flaky; I had a lot of problems getting the code compiled and linked; does not match my experience with gnu for other processors though and really surprises me.
All I'd like to know ia what is done in the crt.... libraries.
Kind Regards,
Revision history for this message
|
#3 |
Hi Hugo,
Your objdump confused me because the instructions are actually 32bit Thumb instructions. Here is the actual code:
00000000 <_mainCRTStartup>:
0: e59f30d8 ldr r3, [pc, #216] ; e0 <change_back+0x8>
4: e3530000 cmp r3, #0
Note that the encoding is the same: 30d8 e59f 0000 e353.
There is a relocation for the address e0:
000000e0 00001502 R_ARM_ABS32 00000000 __stack
So it fails for you because __stack is not defined. You should modify your linker script to define __stack and it should work just fine.
Best regards,
Thomas
Revision history for this message
|
#4 |
It seems there is something not quite right with the linker. It pulls in Arm libraries again. When I call the linker directly (not through gcc) I get an error:
/usr/arm/
Supported emulations: armelf
Can the linker only link arm? Or thumb also? How do you specify soft float in the linker?
Revision history for this message
|
#5 |
Hi Hugo,
This should be:
/usr/arm/
for compiling and:
/usr/arm/
for linking.
Best regards.
Revision history for this message
|
#6 |
Hi Thomas,
did the options precisely as per your post. Crashes immediately at 0xb4. That is ARM code what you have posted, the cortex-m3 is thumb only (I think at least). Is is possible that thumb crt0.o from the distribution has been compiled with -marm option?
The use of -Wl, when calling the linker through gcc is not quite obvious but your options seem to work; no arm libraries there any longer.
Kind Regards,
Hagen
.
Revision history for this message
|
#7 |
Oh, and __stack is defined by the linker script; in my case it is set to 0x10008000 which I believe is the top of internal RAM of the processor.
Revision history for this message
|
#8 |
Where would I find the source code for the crtxxx.o files? I could not find it in the source code tar ball. Or is that outside the gnu compiler source code?
Revision history for this message
|
#9 |
Hi Thomas,
is it possible that there is a problem with the libraries? After going back to my own startup code the system starts up but then I get an exception in __floatisdf. The map file claims it came from the /thumb directory but the code does not look quite right to me:
excerpt from map file:
.text 0x00005bcc 0x41c /usr/arm/
program code:
0x00005F0C 0000 MOVS r0,r0
0x00005F0E E330 B 0x00006572
0x00005F10 1000 ASRS r0,r0,#0
0x00005F12 03A0 LSLS r0,r4,#14
0x00005F14 FF1E012F DCD 0xFF1E012F ; ? Undefined
0x00005F18 4030 ANDS r0,r0,r6
0x00005F1A E92D4B01 PUSH {r0,r8-r9,r11,lr}
0x00005F1E E3A0 B 0x00006662
0x00005F20 4032 ANDS r2,r2,r6
0x00005F22 E284 B 0x0000642E
0x00005F24 5102 STR r2,[r0,r4]
0x00005F26 E210 B 0x0000634A
0x00005F28 0000 MOVS r0,r0
0x00005F2A 4260 RSBS r0,r4,#0
0x00005F2C 1000 ASRS r0,r0,#0
0x00005F2E E3A0 B 0x00006672
0x00005F30 FF7CEAFF DCD 0xFF7CEAFF ; ? Undefined
0x00005F34 2080 MOVS r0,#0x80
0x00005F36 E1B0 B 0x0000629A
.....
Kind regards,
Revision history for this message
|
#10 |
Hi Thomas,
I disassembled the lib/gcc/
Kind Regards,
Revision history for this message
|
#11 |
Bingo!
I deleted the crt....o files and libg...a in the lib/gcc/
I don't want to mark that as a solution until somebody knowledgeable in the gnu linker / library system can confirm that. I'm not even sure what armv7-ar stands for but its a short term solution for me and I can get on with the job.
objdump -d works a treat and it is quite easy to identify that lib/gcc/
Revision history for this message
|
#12 |
Hi Hugo,
Let me reply to your post one by one.
Comment #6:
Yes you're right, this is ARM code indeed. The reason is that specifying only -mthumb but no -march or -mcpu means you are targetting old ARM processor (such as arm7tdmi). These cores support both ARM and Thumb mode and will, I believe, boot in ARM mode. Since you are targetting Cortex-M3 you should compile and link with -mcpu=cortex-m3 -mthumb and it should select arm-none-
Comment #7:
Indeed, the issue is really the execution mode as you found yourself.
Comment #8:
- crt0.o comes from crt0.S in libgloss/arm directory of newlib (and can thus be found in src/newlib.tar.bz2 tarball)
- crti.o and crtn.o come from crti.S and crtn.S in libgcc/config/arm directory of gcc (and can thus be found in src/gcc.tar.bz2 tarball)
- crtbegin.o and crtend.o are, I think, generated from crtstuff.c in libgcc directory of gcc (and can thus be found in src/gcc.tar.bz2 tarball)
Comment #9:
I don't see any __floatisdf in your Map excerpt so it seems normal not to find it in libgcc.a
Comment #10:
I said before, you should make sure you compile *and* link with -mcpu=cortex-m3 (of -march=armv7-m) -mthumb and it will pick things in armv7-m directory rather than thumb.
Comment #11:
As per the multilib guide in section "Architecture options usage" of readme.txt file [1], armv7-ar is for Cortex-A and Cortex-R processors in Thumb mode. I guess it should work as this would be Thumb-2 but you'd better use what is in armv7-m. For this, just compile and link with -mcpu=cortex-m3 -mthumb.
[1] https:/
Best regards,
Thomas
Revision history for this message
|
#13 |
Hi Thomas,
thank you for your reply.
#9: __floatisdf is linked on address 0x00005F0C. It is in the map file and the executable code is below.
#10: After reading your advice I did compile *and* link with -mcpu-cortex-m3 *and* -mthumb. The linker linked against lib/gcc/
#11: Thank you for your advice; I will copy those libraries instead. As I said in #10 the cpu and thumb options will include the wrong libraries.
At this point I'd actually take the opportunity to thank everybody who contributed to providing the gnu arm tool binaries.
Kind Regards,
Revision history for this message
|
#14 |
This is strange, I cannot reproduce it. I tried the following:
arm-none-eabi-gcc -c -mcpu=cortex-m3 -mthumb test.c
arm-none-eabi-gcc -o test.axf -mcpu=cortex-m3 -mthumb test.o -Wl,-Map,test.map -sepcs=rdimon.specs
With the following test.c:
int
main (void)
{
return (int) (2. + 4.5);
}
and it takes the right libgcc. Can you reproduce the issue with this example and command lines?
Best regards.
Revision history for this message
|
#15 |
Hello Thomas,
no, your example works here as well.
I actually did the options precisely as per your post #5 but I just noticed the -mcpu=cortex-3m option is missing in there. When I added the cpu option now to the linker it works with my software too.
So your post #12 under Comment #10 is really the solution.
Thank you very much for your help !
Kind Regards,
Revision history for this message
|
#16 |
I want to get ELF file in thumb too. I use you command line.
Compile for all c files is:
/usr/arm/
this can work. But linking get wrong
Linking command line:
/usr/arm/
Error is shown below:
/usr/bin/
collect2: error: ld returned 1 exit status
Revision history for this message
|
#17 |
Hi,
It seems lpclnk.ld is not in your current working directory, or there is a spelling mistake or the access rights are wrong.
Best regards.
Revision history for this message
|
#18 |
Hi Thomas,
I still have problem.
My development board is in cortex-m3. May I use the executable ELF file to run in the system that the loader is writen by myself. Now I had got a problem that jump from .text to .plt it may trigger exception. Because the jump instruction used BLX, which can not be allowed in cortex-m3.
Can I use dynamic linking in cortex-m3?
Best regards.
Revision history for this message
|
#19 |
No, dynamic linking seems counter to development for Cortex-M3. Usually Cortex-M3 is for running bare-metal applications, without a dynamic loader to patch the GOT entries that goes with a PLT. You should link statically.
Best regards,
Thomas