読者です 読者をやめる 読者になる 読者になる

kubo39's blog

ただの雑記です。

STM32F3DISCOVERYボード向けに実行プログラムをLDCで作ってみようとしてハマった

表題のとおり、STM32F3DISCOVERYボード向けに実行プログラムをLDCで作ってみようとしてハマった。

D言語ソースコード

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をまともに解釈しないようだ)