che sto cercando di fare un mondo ciao in architettura ARM con CMake con this toolchainbraccio-nessuno-EABI-gcc con cmake non ha punto di ingresso con la bandiera -nostdlib
mio main.c
int main()
{
char *str = "Hello World";
return 0;
}
E il mio CMakeLists.txt
cmake_minimum_required(VERSION 3.4)
SET(PROJ_NAME arm-hello-world-nostdlib)
PROJECT(${PROJ_NAME})
# Include directories with headers
#---------------------------------------------------#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
# Source
#---------------------------------------------------#
FILE(GLOB ${PROJ_NAME}_SRC
"src/*.c"
)
FILE(GLOB ${PROJ_NAME}_HEADERS
"include/*.h"
)
# Create Exe
#---------------------------------------------------#
ADD_EXECUTABLE(${PROJ_NAME} ${${PROJ_NAME}_SRC} ${${PROJ_NAME}_HEADERS})
# Specify libraries or flags to use when linking a given target.
#---------------------------------------------------#
TARGET_LINK_LIBRARIES(${PROJ_NAME} -nostdlib --specs=rdimon.specs -lm -lrdimon)
Questo lancio di configurazione l'avvertimento:
[100%] Linking C executable arm-hello-world-nostdlib
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000008000
ed eseguendo il binario con QEMU in crash l'esecuzione:
qemu-arm arm-hello-world-nostdlib
qemu: uncaught target signal 4 (Illegal instruction) - core dumped
Illegal instruction (core dumped)
Senza bandiera --nostdlib funziona perfettamente, e il comando
arm-none-eabi-objdump -s arm-hello-world-nostdlib
mostrare un sacco di informazioni in formato binario, la compilazione con il flag solo spettacolo:
samples/helloworld-nostdlib/arm-hello-world-nostdlib: file format elf32-littlearm
Contents of section .text:
8000 80b483b0 00af044b 7b600023 18460c37 .......K{`.#.F.7
8010 bd465df8 047b7047 1c800000 .F]..{pG....
Contents of section .rodata:
801c 48656c6c 6f20576f 726c6400 Hello World.
Contents of section .comment:
0000 4743433a 20284665 646f7261 20352e32 GCC: (Fedora 5.2
0010 2e302d33 2e666332 33292035 2e322e30 .0-3.fc23) 5.2.0
0020 00 .
Contents of section .ARM.attributes:
0000 41380000 00616561 62690001 2e000000 A8...aeabi......
0010 05436f72 7465782d 4d340006 0d074d09 .Cortex-M4....M.
0020 020a0612 04140115 01170318 0119011a ................
0030 011b011c 011e0622 01 .......".
Non voglio librerie STL nel mio binario, ma credo di mancare il codice assembly per trovare la voce p mista. Come può aggiungerlo manualmente?
Aggiornamento: Secondo GNU Linker doc per -nostdlib:
Non utilizzare i file di avvio del sistema standard o librerie quando di collegamento. Nessun file di avvio e solo le librerie specificate saranno passate al linker e le opzioni che specificano il collegamento delle librerie del sistema , come -static-libgcc o -shared-libgcc, vengono ignorate.
In alternativa, se qualcuno non desidera la libreria standard utente, può utilizzare flag -nodefaultlibs.
Non utilizzare le librerie di sistema standard durante il collegamento. Solo le librerie specificate vengono passate al linker e le opzioni che specificano il collegamento delle librerie di sistema, come -static-libgcc o -shared-libgcc, vengono ignorate. I file di avvio standard vengono normalmente utilizzati, a meno che non vengano utilizzati -nostartfiles.
Il compilatore può generare chiamate a memcmp, memset, memcpy e memmove. Queste voci sono generalmente risolte dalle voci in libc. Questi punti devono essere forniti attraverso qualche altro meccanismo quando viene specificata l'opzione .
A proposito, voglio un modo per creare e aggiungere i file di avvio, una possibile via di this tutorial, ma aggiungo la bontà di ottenere una risposta alla mia domanda e hanno una soluzione generale per tutti. Considero questo utile per le persone che vogliono personalizzare e conoscere i file crosscompilation, arm e startup.
Aggiornamento 2
Utilizzando inizio.S codice assembly:
.text
.align 4
.global _start
.global _exit
_start:
mov fp, #0 /* frame pointer */
ldr a1, [sp] /* 1st arg = argc */
add a2, sp, #4 /* 2nd arg = argv */
bl main
_exit:
mov r7, #1 /* __NR_exit */
swi 0
.type _start,function
.size _start,_exit-_start
.type _exit,function
.size _exit,.-_exit
per indicare il punto di ingresso fornita da ARSV e compilare utilizzando il comando:
arm-none-eabi-gcc -nostdlib -o main main.c start.S
sembra funzionare propertly. Aggiornamento di CMakeLists.txt:
#Directly works:
#arm-none-eabi-gcc -nostdlib -o main main.c start.S
cmake_minimum_required(VERSION 3.4)
SET(PROJ_NAME arm-hello-world-nostdlib)
# Assembler files (.S) in the source list are ignored completely by CMake unless we
# “enable” the assembler by telling CMake in the project definition that we’re using assembly
# files. When we enable assembler, CMake detects gcc as the assembler rather than as – this
# is good for us because we then only need one set of compilation flags.
PROJECT(${PROJ_NAME} C ASM)
# Include directories with headers
#---------------------------------------------------#
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
# Source
#---------------------------------------------------#
FILE(GLOB ${PROJ_NAME}_SRC
"src/start.S"
"src/*.c"
)
FILE(GLOB ${PROJ_NAME}_HEADERS
"include/*.h"
)
# Create Exe
#---------------------------------------------------#
ADD_EXECUTABLE(${PROJ_NAME} ${${PROJ_NAME}_SRC} ${${PROJ_NAME}_HEADERS})
# Specify libraries or flags to use when linking a given target.
#---------------------------------------------------#
TARGET_LINK_LIBRARIES(${PROJ_NAME} -nostdlib --specs=rdimon.specs -lm -lrdimon)
Se si ottiene collegando i problemi come:
arm-none-eabi/bin/ld: error: CMakeFiles/arm-hello-world-nostdlib.dir/src/main.c.obj: Conflicting CPU architectures 1/13
E 'un problema con toolchain, per Cortex-A9, funziona utilizzando:
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS}"
"-mcpu=cortex-a9 -march=armv7-a -mthumb"
"-mfloat-abi=softfp -mfpu=fpv4-sp-d16"
)
STL è C++, perché dovresti averlo nel tuo programma C? Tecnicamente è possibile impostare il punto di ingresso su main nel comando linker, ma questo salta la fase di inizializzazione di libc e quindi non è raccomandato. – Jester
Senza crosscompile, seguendo questo tutorial: https://blogs.oracle.com/ksplice/entry/hello_from_a_libc_free, funziona perfettamente, perché usa il proprio file di assemblaggio _start stub, che funziona in x86. Presumo che ho bisogno di qualcosa di simile in ARM, ma non so cosa usare, lo stesso file di assembly non funziona perché l'architettura è diversa. – vgonisanz
Si noti che l'articolo collegato in particolare non utilizza la libreria C. Che funzioni. Ciò che non è garantito funziona è il mix di '-nostdlib' con' -lc'.Dovresti decidere se hai bisogno di libc, nel qual caso non usi '-nostdlib', o se non ti serve, allora non usare' -lc' e imposta il punto di ingresso tramite l'opzione linker. – Jester