Search code examples
cmakesegmentation-faultarmqemustm32f4

qemu-arm Segmentation Fault


Take a simple file:

int main(void) {
  return 0;
}

My CMakeLists.txt file:

cmake_minimum_required(VERSION 3.20)
project(TRA
        VERSION 0.0.1
        DESCRIPTION "STM32 Traffic Controller"
        LANGUAGES C ASM)

set(BSP_DRIVER_FILES
  BSP/tra/startup_stm32f429xx.s
  BSP/tra/Core/Src/system_stm32f4xx.c
)
set(BSP_COMPILER_FLAGS
  -DUSE_HAL_DRIVER
  -DSTM32F429xx
  -I${CMAKE_SOURCE_DIR}/BSP/tra/Core/Inc
  -I${CMAKE_SOURCE_DIR}/BSP/tra/Drivers/STM32F4xx_HAL_Driver/Inc
  -I${CMAKE_SOURCE_DIR}/BSP/tra/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy
  -I${CMAKE_SOURCE_DIR}/BSP/tra/Drivers/CMSIS/Device/ST/STM32F4xx/Include
  -I${CMAKE_SOURCE_DIR}/BSP/tra/Drivers/CMSIS/Include
) 

add_executable(tra)
target_sources(tra PRIVATE
  ${BSP_DRIVER_FILES}
  code/tra.c
)
set(COMPILER_FLAGS
  ${BSP_COMPILER_FLAGS}
  -O0 -g -ggdb3
  -mcpu=cortex-m4 -mthumb -mfloat-abi=soft
  -fdata-sections -ffunction-sections
  --specs=rdimon.specs
)
target_compile_options(tra PRIVATE
  ${COMPILER_FLAGS}
)
target_link_options(tra PRIVATE
  -mcpu=cortex-m4 -mthumb -mfloat-abi=soft
  --specs=rdimon.specs -lm -lc
  -Wl,--gc-sections
)

Running qemu-arm build/tra. I get

qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault (core dumped)

My understanding was that this issue was commonly caused by qemu not handling hardware FPU, however I'm specifying software floating point here. Also, I have removed FPU initialization code from my startup.c file. With gdb:

# Start
qemu-arm -g 1234 build/tra
# Attach
arm-none-eabi-gdb -q --nh -ex 'file build/tra' -ex 'target remote localhost:1234'

I get the segmentation fault at SystemInit(). Running gdb list, it shows the commented out FPU initialization code, so I don't see how that could be the issue. Therefore, I'm at a loss as to what is going on.


Solution

  • You're building a bare-metal binary for a Cortex-M CPU, and then trying to run it on qemu-arm, which is the emulator for running Cortex-A Linux binaries.

    If you're building a bare-metal binary, you need to build it for the exact machine type that you want to run it on, which means you need to target a machine type supported by qemu-system-arm, and you need to tell qemu-system-arm to use that machine type.