STM32F3DISCOVERYボード向けに実行プログラムをLDCで作ってみようとしてハマった
表題のとおり、STM32F3DISCOVERYボード向けに実行プログラムをLDCで作ってみようとしてハマった。
import ldc.attributes; extern(C): @nogc: nothrow: pragma(LDC_no_moduleinfo); @(section("_reset")) void _reset() { int y = void; auto x = 42; y = x; while (true) {} }
ENTRY(_reset); MEMORY { CCRAM : ORIGIN = 0x10000000, LENGTH = 8K FLASH : ORIGIN = 0x08000000, LENGTH = 256K RAM : ORIGIN = 0x20000000, LENGTH = 40K } SECTIONS { .text : { /* Vector table */ LONG(ORIGIN(RAM) + LENGTH(RAM)) LONG(_reset + 1); /* Reset handler */ _reset = .; *(.text._reset) *(.text*) } > FLASH /DISCARD/ : { *(.ARM.exidx*) *(.note.gnu.build-id*) } }
実行バイナリを作る手順はこのような感じ。
$ ldc2 -march=thumb -mcpu=cortex-m4 -c -g main.d $ arm-none-eabi-ld main.o -T layout.ld -nostartfiles -o main.bin
OpenOCDを起動する。
$ openocd -f board/stm32f3discovery.cfg Open On-Chip Debugger 0.9.0 (2015-09-02-10:42) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html adapter speed: 1000 kHz adapter_nsrst_delay: 100 Info : The selected transport took over low-level target control. The results m$ ght differ compared to plain JTAG/SWD none separate srst_only separate srst_nogate srst_open_drain connect_deassert_srst Info : Unable to match requested speed 1000 kHz, using 950 kHz Info : Unable to match requested speed 1000 kHz, using 950 kHz Info : clock speed 950 kHz Info : STLINK v2 JTAG v16 API v2 SWIM v0 VID 0x0483 PID 0x3748 Info : using stlink api v2 Info : Target voltage: 2.919073 Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
別ターミナルからGDBを使ってプログラムを実行しようとしたところ、以下のような状況になった。
$ gdb -q main.bin Reading symbols from main.bin...done. (gdb) target remote :3333 Remote debugging using :3333 warning: Architecture rejected target-supplied description 0x00000000 in ?? () (gdb) load Loading section .text, size 0x8 lma 0x8000000 Loading section _reset, size 0x1a lma 0x8000008 Start address 0x8000008, load size 34 Remote connection closed
OpenOCD側の出力はこのようになった。
Info : accepting 'gdb' connection on tcp/3333 undefined debug reason 7 - target needs reset adapter speed: 1000 kHz target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08000008 msp: 0x2000a000 adapter speed: 8000 kHz target state: halted target halted due to breakpoint, current mode: Thread xPSR: 0x61000000 pc: 0x2000003a msp: 0x2000a000 adapter speed: 1000 kHz target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08000008 msp: 0x2000a000 Error: gdb requested a non-existing register Info : dropped 'gdb' connection
gdb側でloadしようとするとconnection closedになってしまう。
$ arm-none-eabi-objdump -Cd main.bin main.bin: file format elf32-littlearm Disassembly of section .text: 08000000 <_reset-0x8>: 8000000: 2000a000 .word 0x2000a000 8000004: 08000009 .word 0x08000009 Disassembly of section _reset: 08000008 <_reset>: 8000008: b082 sub sp, #8 800000a: 202a movs r0, #42 ; 0x2a 800000c: 9000 str r0, [sp, #0] 800000e: 9001 str r0, [sp, #4] 8000010: e7ff b.n 8000012 <_reset+0xa> 8000012: 2000 movs r0, #0 8000014: 2800 cmp r0, #0 8000016: d102 bne.n 800001e <_reset+0x16> 8000018: e7ff b.n 800001a <_reset+0x12> 800001a: e7ff b.n 800001c <_reset+0x14> 800001c: e7f9 b.n 8000012 <_reset+0xa> 800001e: b002 add sp, #8 8000020: 4770 bx lr
readlelfでみるとsoft-float ABIになっている。
STM32F3DISCOVERYはCortex-M4Fなのでhardware floatにしなければないらないようだ。
$ arm-none-eabi-readelf -h main.bin ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: ARM Version: 0x1 Entry point address: 0x8000008 Start of program headers: 52 (bytes into file) Start of section headers: 1568 (bytes into file) Flags: 0x5000200, Version5 EABI, soft-float ABI Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 2 Size of section headers: 40 (bytes) Number of section headers: 16 Section header string table index: 13
float-abiを指定してみる。
$ ldc2 -march=thumb -mcpu=cortex-m4 -c -g -float-abi=hard main.d $ arm-none-eabi-ld main.o -T layout.ld -nostartfiles -o main.bin
結果変わらず。
$ arm-none-eabi-readelf -h main.bin ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: ARM Version: 0x1 Entry point address: 0x8000008 Start of program headers: 52 (bytes into file) Start of section headers: 1568 (bytes into file) Flags: 0x5000200, Version5 EABI, soft-float ABI Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 2 Size of section headers: 40 (bytes) Number of section headers: 16 Section header string table index: 13
LDCはtarget tripleの指定もできる。これが通って欲しい。けどだめそうだ。 軽く本体のソースを読んだ感じ、LDC側はthumbv7emやeabihfを解釈できないようだった。
$ ldc2 -mtriple=thumbv7em-unknown-none-eabihf -c -g main.d Targeting 'thumbv7em-unknown-none-eabihf' (CPU '' with features '') Error: target 'thumbv7em-unknown-none-eabihf' is not yet supported
$ ldc2 -march=thumb -mcpu=cortex-m4 -float-abi=hard -mabi=eabihf -c -g main.d
でもsoft-float ABIなバイナリが生成されてしまう。(上記にも書いたがそもそもeabihfをまともに解釈しないようだ)