I'm trying to build a minimal startup code for my MCU (tms570lc4357zwt, ARM Cortex-R5f), but when I build it and convert it to binary format, the size of the produced .bin file is 0.
The structure of test files is:
test
+--CMakeLists.txt
+--gnu.cmake
+--isr.S
+--linker.ld
The version of the tools I use are:
Here is my minimal piece of assembly code (isr.S):
.arm
.global isr_vector
.global bootloader
.section .flash_code_isr_vector
isr_vector:
LDR pc, = bootloader /* reset. */
LDR pc, = 0x08000004 /* undefined instruction. */
LDR pc, = 0x08000008 /* system call. */
LDR pc, = 0x0800000C /* prefetch abort. */
LDR pc, = 0x08000010 /* data abort. */
LDR pc, = 0x08000014 /* reserved. */
LDR pc, = 0x08000018 /* IRQ. */
LDR pc, = 0x0800001C /* FIQ. */
.section .flash_code_bootloader
bootloader:
B .
and I use the following linker script (linker.ld):
MEMORY
{
FLASH_TCM (rx) : ORIGIN = 0x00000000, LENGTH = 4M
RAM_TCM (rwx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM_ECC (rwx) : ORIGIN = 0x08400000, LENGTH = 512K
}
ENTRY(isr_vector)
SECTIONS
{
.flash_code_isr_vector 0x00000000 :
{
KEEP(*(.flash_code_isr_vector))
} > FLASH_TCM
.flash_code_bootloader 0x00000100 :
{
*(.flash_code_bootloader)
} > FLASH_TCM
}
Bellow, the toolchain file (gnu.cmake) and the cmake file (CMakeLists.txt) I use to build it:
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
find_program(ASM_COMPILER arm-none-eabi-gcc)
find_program(C_COMPILER arm-none-eabi-gcc)
find_program(LINKER arm-none-eabi-gcc)
find_program(ARCHIVER arm-none-eabi-ar)
find_program(RANLIB arm-none-eabi-ranlib)
set(CMAKE_ASM_COMPILER ${ASM_COMPILER})
set(CMAKE_C_COMPILER ${C_COMPILER})
set(CMAKE_C_LINK_EXECUTABLE ${LINKER})
set(CMAKE_AR ${ARCHIVER})
set(CMAKE_RANLIB ${RANLIB})
add_compile_options(-mbig-endian
-march=armv7-r
-Wall
-Wextra)
add_link_options(-mbig-endian
-nostdlib
-Wall
-Wextra)
cmake_minimum_required(VERSION 3.0)
project(test VERSION 0.0.1 LANGUAGES ASM)
add_executable(isr.elf isr.S)
add_compile_options(isr.elf PRIVATE -O0 -g)
set_target_properties(isr.elf PROPERTIES
LINK_FLAGS "-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld")
add_custom_target(isr.bin
DEPENDS isr.elf
COMMAND arm-none-eabi-objcopy -O binary isr.elf isr.bin
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
add_custom_target(isr.asm
DEPENDS isr.elf
COMMAND arm-none-eabi-objdump -D isr.elf > isr.asm
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
add_custom_target(isr.size
DEPENDS isr.elf
COMMAND arm-none-eabi-size isr.elf -A -t -x
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
The issue can be reproduced by running (in the folder containing all files) mkdir build && cd build && cmake .. -DCMAKE_TOOLCHAIN_FILE=../gnu.cmake
Now comes the issue:
When I ask the size of the .elf (invoking the isr.size
taget), I get
isr.elf :
section size addr
.flash_code_isr_vector 0x40 0x0
.flash_code_bootloader 0x4 0x100
.ARM.attributes 0x1d 0x0
Total 0x61
which seems reasonable. now when I produce the .bin file (invoking the isr.bin
target), the produced file size is 0. Does anyone have an idea why? Because when I disassemble the .elf file (invoking the isr.asm
target), the generated assembly code seems correct:
isr.elf: file format elf32-bigarm
Disassembly of section .flash_code_isr_vector:
00000000 <isr_vector>:
0: e59ff018 ldr pc, [pc, #24] ; 20 <isr_vector+0x20>
4: e59ff018 ldr pc, [pc, #24] ; 24 <isr_vector+0x24>
8: e59ff018 ldr pc, [pc, #24] ; 28 <isr_vector+0x28>
c: e59ff018 ldr pc, [pc, #24] ; 2c <isr_vector+0x2c>
10: e59ff018 ldr pc, [pc, #24] ; 30 <isr_vector+0x30>
14: e59ff018 ldr pc, [pc, #24] ; 34 <isr_vector+0x34>
18: e59ff018 ldr pc, [pc, #24] ; 38 <isr_vector+0x38>
1c: e59ff018 ldr pc, [pc, #24] ; 3c <isr_vector+0x3c>
20: 00000100 andeq r0, r0, r0, lsl #2
24: 08000004 stmdaeq r0, {r2}
28: 08000008 stmdaeq r0, {r3}
2c: 0800000c stmdaeq r0, {r2, r3}
30: 08000010 stmdaeq r0, {r4}
34: 08000014 stmdaeq r0, {r2, r4}
38: 08000018 stmdaeq r0, {r3, r4}
3c: 0800001c stmdaeq r0, {r2, r3, r4}
Disassembly of section .flash_code_bootloader:
00000100 <bootloader>:
100: eafffffe b 100 <bootloader>
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 41000000 mrsmi r0, (UNDEF: 0)
4: 1c616561 cfstr64ne mvdx6, [r1], #-388 ; 0xfffffe7c
8: 62690001 rsbvs r0, r9, #1, 0
c: 00000012 andeq r0, r0, r2, lsl r0
10: 05372d52 ldreq r2, [r7, #-3410]! ; 0xfffff2ae
14: 00060a07 andeq r0, r6, r7, lsl #20
18: 52080109 andpl r0, r8, #1073741826 ; 0x40000002
1c: Address 0x000000000000001c is out of bounds.
Thanks in advance.
In your assembly code you haven't marked your sections as allocatable so they aren't being output when you produce the binary file. If you had dumped the header files with
arm-none-eabi-objdump -x isr.elf
The output would have looked similar to:
isr.elf: file format elf32-bigarm isr.elf architecture: arm, flags 0x00000012: EXEC_P, HAS_SYMS start address 0x00000000 private flags = 5000200: [Version5 EABI] [soft-float ABI] Sections: Idx Name Size VMA LMA File off Algn 0 .flash_code_isr_vector 00000040 00000000 00000000 00000034 2**2 CONTENTS, READONLY 1 .flash_code_bootloadery 00000004 00000000 00000000 00000074 2**2 CONTENTS, READONLY 2 .ARM.attributes 0000001d 00000000 00000000 00000078 2**0 CONTENTS, READONLY
The flags are only CONTENTS
and READONLY
. It is missing the ALLOC
(allocatable) flag. Since your sections appear to also be code I'd consider modifying isr.S
by adding "ax"
attributes with something like:
.arm
.global isr_vector
.global bootloader
.section .flash_code_isr_vector,"ax",%progbits
isr_vector:
LDR pc, = bootloader /* reset. */
LDR pc, = 0x08000004 /* undefined instruction. */
LDR pc, = 0x08000008 /* system call. */
LDR pc, = 0x0800000C /* prefetch abort. */
LDR pc, = 0x08000010 /* data abort. */
LDR pc, = 0x08000014 /* reserved. */
LDR pc, = 0x08000018 /* IRQ. */
LDR pc, = 0x0800001C /* FIQ. */
.section .flash_code_bootloader,"ax",%progbits
bootloader:
B .
If you rebuild the code the bin
file should be non-zero and the ELF headers should now look something like:
Sections: Idx Name Size VMA LMA File off Algn 0 .flash_code_isr_vector 00000040 00000000 00000000 00010000 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .flash_code_bootloader 00000004 00000100 00000100 00010100 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .ARM.attributes 0000001d 00000000 00000000 00010104 2**0 CONTENTS, READONLY
The .section
directive is documented for ELF as:
ELF Version
This is one of the ELF section stack manipulation directives. The others are .subsection (see SubSection), .pushsection (see PushSection), .popsection (see PopSection), and .previous (see Previous).
For ELF targets, the .section directive is used like this:
.section name [, "flags"[, @type[,flag_specific_arguments]]]
[snip]
a section is allocatable
d section is a GNU_MBIND section
e section is excluded from executable and shared library.
w section is writable
x section is executable
M section is mergeable
S section contains zero terminated strings
G section is a member of a section group
T section is used for thread-local-storage
? section is a member of the previously-current section’s group, if any
[snip]
The optional type argument may contain one of the following constants:
@progbits section contains data
@nobits section does not contain data (i.e., section only occupies space)
[snip]
Note on targets where the @ character is the start of a comment (eg ARM) then another character is used instead. For example the ARM port uses the % character.
User contributions licensed under CC BY-SA 3.0