Does anyone know how to put a program in an ARM assembler at an arbitrary address in memory? By default, the program is located starting from the address 0x00000008, but it is necessary that it be located, for example, at the address 0x20002000. I tried to use DCD 0x20002000
, but this only changes the register-pointer, while the program remains at the old address. The SPACE 0x400
command works well, but if the address is too large, then the compilation takes a very long time. Tell me, maybe faced with this?
You can usually achieve this result by modifying the linker script you are using, or by providing certain command-line options to GNU ld.
From the information you provided, I am assuming that your code is currently starting right after the two first vector entries table, i.e. the Initial SP Value, and the Reset Value, and that your vector table is located at 0x00000000.
example1.s should more or less look like your current code:
.cpu cortex-m3
.thumb
.syntax unified
.global Reset_Handler
.equ StackTop, 0x1000
.word StackTop
.word Reset_Handler
Reset_Handler:
b .
.end
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-as -o example1.o -c example1.s
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-ld -g -e Reset_Handler -Ttext-segment=0x00000000 -Map=example1.map -o example1.elf example1.o
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-objdump -d example1.elf
example1.elf: file format elf32-littlearm
Disassembly of section .text:
00000000 <Reset_Handler-0x8>:
0: 00001000 .word 0x00001000
4: 00000008 .word 0x00000008
00000008 <Reset_Handler>:
8: e7fe b.n 8 <Reset_Handler>
The code will then be located at 0x00000008.
example2.s defines a new linker section named .vectors.
We will now use GNU ld --section-start command-line option to force the .vectors section to reside at 0x00000000, and still use -Ttext-segment to force the .text section/ text segment to reside at 0x20002000.
example2.s:
.cpu cortex-m3
.thumb
.syntax unified
.global Reset_Handler
.equ StackTop, 0x1000
.section .vectors
.word StackTop
.word Reset_Handler
.section .text
Reset_Handler:
b .
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-as -o example2.o -c example2.s
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-ld -g -e Reset_Handler --section-start=.vectors=0x00000000 -Ttext-segment=0x20002000 -Map=example2.map -o example2.elf example2.o
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-ld: warning: address of `text-segment' isn't multiple of maximum page size
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-objdump -d -j .vectors -j .text -d example2.elf
example2.elf: file format elf32-littlearm
Disassembly of section .vectors:
00000000 <.vectors>:
0: 00001000 .word 0x00001000
4: 20002000 .word 0x20002000
Disassembly of section .text:
20002000 <Reset_Handler>:
20002000: e7fe b.n 20002000 <Reset_Handler>
.end
The vector table is still located at the correct memory location, but the code now resides at 0x20002000.
In order to describe the exact changes required in the linker script you are using for achieving the same result, I would need to see its content.
There are basically two ways to control the location of the code region using Keil. Either using the scatter file, or using the 'target' tab in the build options dialogue.
You can define an IROM region which includes the region where you want your code to be located. You can also start by using this dialogue to generate an initial scatter file, then modify the scatter file based on the Keil documentation.
However, the location you have given here is in the RAM region, which is a little unusual (maybe inefficient, but valid). Have you considered how to initialise your target after power cycling it?
The biggest problem is that at reset, Cortex-M3 will ALWAYS read from addresses 0, 4 (and 8 due to prefetch). You need to provide an initial stack pointer (or not use the stack), and your reset vector (with bit 0, the T-bit, set). There may be hardware banking of the memory map (device specific), but the programmer's view is always that these fetches start at address 0.
User contributions licensed under CC BY-SA 3.0