stubでGDBに接続だけする

1.それは、無知から始まりました..

 

もし、私が、SH7045EDK(Evaluation Development kits)を持っていたとしたら

William A. Gatliffさんのstubプログラム gdbstubs-20030326-1117CDT.tarを

そのまま、GCCでビルドすれば、動くはずです。

 

そこで、そのまま、GCCにて、motファイルまで、Williamさんに指示通りに行いました。

 

sh-elf-gcc -Wall -m2 -g -DSH2_7045EDK -DCRT0 -o sh2-stub -Wl,--script=sh2-704x.x -Wl,-Map,gdb.map ¥

-nostartfiles sh2-704x.c gdb.c sh2.c

 

リンカに対する指示、-Wl,-Map,gdb.map は、私が、付け加えました。

 

そして、このマップファイルを見てみますと、

こんな感じです。(一部抜粋)

 

Allocating common symbols

Common symbol size file

gdb_sh2_stepped_opcode

0x2 C:\DOCUME~1\junzo\LOCALS~1\Temp/cc0ydaaa.o

Memory Configuration

Name Origin Length Attributes

*default* 0x0000000000000000 0xffffffffffffffff

Linker script and memory map

0x0000000000000000 . = 0x0

.text 0x0000000000000000 0x1bfe

*(.vect)

.vect 0x0000000000000000 0x100 C:\DOCUME~1\junzo\LOCALS~1\Temp/ccARbaaa.o

0x0000000000000000 vector_table

*(.text)

.text 0x0000000000000100 0x100 C:\DOCUME~1\junzo\LOCALS~1\Temp/ccARbaaa.o

0x000000000000018c gdb_startup

0x0000000000000180 gdb_monitor_onexit

0x00000000000001cc start

0x0000000000000100 gdb_putc

0x000000000000013c gdb_getc

0x00000000000001cc start

.text 0x0000000000000200 0x12cc C:\DOCUME~1\junzo\LOCALS~1\Temp/cciIcaaa.o

0x00000000000010d8 gdb_console_output

0x00000000000011cc gdb_monitor

0x0000000000001494 gdb_handle_exception

 

これを見ると、 .vectの所に、何も書いてないでは、ないですか?

Best Technology社のGCC Developer LIteでは、

マップに、いつも、 .vectの所に、いっぱい書いてありますのに...

 

例えば

Memory Configuration

Name Origin Length Attributes

vect 0x00000000 0x00000400 r

rom 0x00000400 0x0003fc00 xr

ram 0xffffd000 0x00003000 xw

*default* 0x00000000 0xffffffff

Linker script and memory map

.vector 0x00000000 0x360

0x00000000 ___vect_top = .

0x00000000 0x4 LONG 0x400 <code 335> (_start)

0x00000004 0x4 LONG 0x0 <code 335> (0x0)

0x00000008 0x4 LONG 0x400 <code 335> (_start)

0x0000000c 0x4 LONG 0x0 <code 335> (0x0)

0x00000010 0x4 LONG 0x400 DEFINED (_int_GeneralIllegalInstruction)?<code 335> (_int_GeneralIllegalInstruction):<code 335> (_start)

0x00000014 0x4 LONG 0x400 <code 335> (_start)

0x00000018 0x4 LONG 0x400 DEFINED (_int_SlotIllegalInstruction)?<code 335> (_int_SlotIllegalInstruction):<code 335> (_start)

0x0000001c 0x4 LONG 0x400 <code 335> (_start)

0x00000020 0x4 LONG 0x400 <code 335> (_start)

0x00000024 0x4 LONG 0x400 DEFINED (_int_CPUAddressError)?<code 335> (_int_CPUAddressError):<code 335> (_start)....

 

 

それで、私は勘違いしまして、

Williamさんのプログラムでは、「ベクターが、書き込めない」と、思ったのです。

 

これは、大変な、私の間違いでして、Williamさん、ごめんなさい m(__)m

後になって解ったのですが、しっかり書き込まれています。[sh-elf-objdumpを使うとわかるのです。]

とにかく、私は、「GCCの開発環境が、何も解っていない」のが、根本的な間違いです...

 

2.SH用のGCC開発環境の概要を知る

 

これに付いては、素晴らしいホームページがあります。

安井さんと言われる方の

「GCCを用いたSH開発環境」

http://www.ops.dti.ne.jp/~coredump/sh-entw.html

 

ここで、GCCの開発環境の概略が掴めました。

素晴らしいページを、ありがとうございます。 m(__)m

お陰様を持ちまして、概略を知ることができました。

 

また、stubを用いるのではなく、GDBの方をルネサスのモニター用に変える方法は

 

「SHの開発環境をLinuxに構築する」にてhttp://www.kt.rim.or.jp/~nozawat/gdb.html

 

gdb-4.17に、パッチをあてて実現されています。(nozawa様御礼申し上げます m(__)m )

私は、今んところ、stubに熱を上げていますが...

 

 

2.1 GCC Developer Lite の構造は、どないなっとんの?

 

GCC Developer Liteを使うと、どの機種の、どういう構成で使うか?

質問されます。

 

これで、どの、リンカースクリプトを使うか決まるのです。

 

例えば、SH7047用に、seiral接続のテストプログラムを、内臓rom,ramで構成したと、します。

(stub用に、serialの設定を確かめてましてん...)

MATH

すると、その構成に応じたbatファイルが作成されます。

そのserila.batを覗いてみますと

MATH

これを見ますと、shrom.xがスクリプトで、shrom.sとserial.cをリンクしています。

 

スクリプトは、リンクの時の、いわば計画書ですよね。

shrom.sが、実際の実行書です。(sは、ソースファイルの事ですね。)

で、

 

この計画書であるスクリプトを覗いて見ますと

OUTPUT_ARCH(sh)

ENTRY("_start")

MEMORY

{

/* MODE 2/3 */

/* 内臓ROM 0x00000000〜0x0003ffff */

/* 内臓I/O 0xffff8000〜0xffffbfff */

/* 内臓RAM 0xffffd000〜0xffffffff */

/* 外部RAM 0x00200000〜0x0023ffff */

vect(r) : org = 0x00000000, len = 0x400

rom(rx) : org = 0x00000400, len = 256k-0x400

ram(wx) : org = 0xffffd000, len = 12k

}

SECTIONS

{

.vector : {

___vect_top = . ;

/* 0 */

LONG(ABSOLUTE(_start))

LONG(ABSOLUTE(0))

LONG(ABSOLUTE(_start))

LONG(ABSOLUTE(0))

/* 4 */

LONG(DEFINED(_int_GeneralIllegalInstruction)?ABSOLUTE(_int_GeneralIllegalInstruction):ABSOLUTE(_start))

LONG(ABSOLUTE(_start))

LONG(DEFINED(_int_SlotIllegalInstruction)?ABSOLUTE(_int_SlotIllegalInstruction):ABSOLUTE(_start))

LONG(ABSOLUTE(_start))

/* 8 */

LONG(ABSOLUTE(_start))

LONG(DEFINED(_int_CPUAddressError)?ABSOLUTE(_int_CPUAddressError):ABSOLUTE(_start))

LONG(DEFINED(_int_DMAAddressError)?ABSOLUTE(_int_DMAAddressError):ABSOLUTE(_start))

LONG(DEFINED(_int_NMI)?ABSOLUTE(_int_NMI):ABSOLUTE(_start))

/* 12 */...

 

最初から、.vectが細かく書かれています。

それで、それが、リンクのマップに、そのまま現れる訳ですわ。

 

 

shrom.sの方は、こんな感じです。

 

.list

.section .text

.global _start

.extern start ! start in CRT0

.extern _data

.extern _mdata

.extern _edata

.extern _stack

_start: mov.l L_STACK_POINTER,sp

! change VBR

! mov.l L_vector_table_top, r0

! ldcr0, vbr

! nop

! initialise sections

mov.l edata,r1 ! edata in r1

mov.l mdata,r2 ! mdata in r2

mov.l data,r0 ! data in r0

cmp/eq r0,r1

btstart_1

nop

start_l: mov.b @r2,r3 !get from src

mov.b r3,@r0 !place in dest

add #1,r2 !inc src

add #1,r0 !inc dest

cmp/eq r0,r1 !dest == edata?

bfstart_l

nop

start_1:

 

ソースファイルそのものですね。

 

一方、wiliamさんの計画書(スクリプト)には、.vectが細かく書かれていません。

OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh")

OUTPUT_ARCH(sh)

ENTRY(start)

SECTIONS {

. = 0;

.text : { *(.vect) *(.text) }

.rodata : { *(.rodata) *(.rodata.*) }

.rodata1 : { *(.rodata1) }

. = 0xffffd000;

.data : { *(.data) *(.data.*) }

.data1 : { *(.data1) }

.sdata : { *(.sdata) *(.sdata.*) }

.sbss : { *(.dynsbss) *(.sbss) *(.sbss.*) *(.scommon) }

.bss : { *(.dynbss) *(.bss) *(.bss.*) *(COMMON) }

.stab 0 : { *(.stab) }

.stabstr 0 : { *(.stabstr) }...

 

 

それで、マップに.vectが、細かく書かれないわけです。

Memory Configuration

Name Origin Length Attributes

*default* 0x0000000000000000 0xffffffffffffffff

Linker script and memory map

0x0000000000000000 . = 0x0

.text 0x0000000000000000 0x1c82

*(.vect)

.vect 0x0000000000000000 0x100 C:\DOCUME~1\junzo\LOCALS~1\Temp/ccS2aaaa.o

0x0000000000000000 vector_table

*(.text)

.text 0x0000000000000100 0x184 C:\DOCUME~1\junzo\LOCALS~1\Temp/ccS2aaaa.o

0x000000000000018c gdb_startup

0x0000000000000180 gdb_monitor_onexit

0x0000000000000250 start

0x0000000000000100 gdb_putc

0x000000000000013c gdb_getc

0x0000000000000250 start...

 

それで、私は勘違いしてしまったんです...

実際は、.vectにアドレスが、しっかり書き込まれています。

 

それを知るには、

sh-elf-objdump -D sh2-stub > stub.txt (MS-DOSのリダイレクトで、stub.txtに書き込みます。)

 

と、やって、ディスアセンブルするのです。(安井さん、ありがとうございます。 m(__)m )

 

sh2-stub: file format elf32-sh

 

Disassembly of section .text:

00000000 <_vector_table>:

0:00 00 .word 0x0000

2:02 50 .word 0x0250

4:ff ff .word 0xffff

6:ff fc .word 0xfffc

8:00 00 .word 0x0000

a:02 50 .word 0x0250

c:ff ff .word 0xffff

e:ff fc .word 0xfffc

10:00 00 .word 0x0000

12:1b a6 mov.l r10,@(24,r11)

14:00 00 .word 0x0000

16:1b 96 mov.l r9,@(24,r11)

18:00 00 .word 0x0000

1a:1b a6 mov.l r10,@(24,r11)

1c:00 00 .word 0x0000

1e:1b 96 mov.l r9,@(24,r11)

20:00 00 .word 0x0000

22:1b 96 mov.l r9,@(24,r11)

24:00 00 .word 0x0000

26:1b b6 mov.l r11,@(24,r11)...(一部省略)

...

00000100 <_gdb_putc>:

100:2f e6 mov.l r14,@-r15

102:7f fc add #-4,r15

104:6e f3 mov r15,r14

106:2e 42 mov.l r4,@r14

108:91 16 mov.w138 <_gdb_putc+0x38>,r1 ! 0x81d4

10a:61 10 mov.b @r1,r1

10c:61 1e exts.b r1,r1

10e:41 11 cmp/pzr1

110:89 fa bt108 <_gdb_putc+0x8>

112:92 12 mov.w13a <_gdb_putc+0x3a>,r2 ! 0x81d3

114:61 e3 movr14,r1

116:71 03 add#3,r1

118:61 10 mov.b @r1,r1

11a:22 10 mov.b r1,@r2

11c:93 0c mov.w138 <_gdb_putc+0x38>,r3 ! 0x81d4

11e:91 0b mov.w138 <_gdb_putc+0x38>...

...

 

これで、大体の仕組みが解ってきました。

 

2.2 sh7047のserial設定を、せな、あかん

 


dsp39__5.gif

 

こうなるのは、

seiralの設定が、できてないから、接続できないのです。

 

実際、SHの電源を切っても、同じメッセージがでますわ、なんと...

 

Malformed response to offset query

と、書いてあるので、

接続は出来ていたと、思ったのに、全く接続できていなかった訳です。

 

それで、SH7047のserial設定を行いました。

 

殆ど忠実に、ルネサスのハードウェアマニュアルに従いました。

 

これを、williamさんのsh704x..cのgdb_start_upの所に書く訳です。

void gdb_startup (void)

{

volatile int i;

/* enable txd/rxd lines */

/*ルネサスの SH7047F ハードウェアマニュアルに従う*/

*MST_CR1 &=0xFFF7; /*MST.SCI_3=3bit目をクリア*/

*SCR=0;

*SMR=0;

*BRR=12; /*baud=57600 bp/s */

for(i=0;i<5000;i++);

*SCR &=0x37;

*PFC_PACRL3 |=0x0300;

*PFC_PACRL1 | =0x0005; /*bit2,0を強制的に1にする*/

*PFC_PACRL1 &=0xfff5; /*bit3,1を強制的に0にする*/

for(i=0;i<5000;i++);

*SCR |=0x30;

/* for LED_0,1*/

*PFC_PAIOR  |=0x0003; /*PAの0,1ビットにLED接続する =1(出力)*/

*IO_PADR |=0x0003; /*LED all on*/

 

return;

}

 

勿論、SH7047用に、ベクタのアドレスも、書き換えなければなりません。

自分のSH7047の構成に合わせて、改変します。

#define SCI_SMR0 ((volatile char *)0xffff81d0L)

#define SCI_BRR0 ((volatile char *)0xffff81d1L)

#define SCI_SCR0 ((volatile char *)0xffff81d2L)

#define SCI_TDR0 ((volatile char *)0xffff81d3L)

#define SCI_SSR0 ((volatile char *)0xffff81d4L)

#define SCI_RDR0 ((volatile char *)0xffff81d5L)

#define MST_CR1 ((volatile short *)0xFFFF861CL)

#define PFC_PACRL3 ((volatile short *) 0xffff838aL)

#define PFC_PACRL2 ((volatile short *) 0xffff838eL)

#define PFC_PAIOR ((volatile short *) 0xffff8386L)

#define IO_PADR ((volatile short *) 0xffff8382L)

 

 

そして、ビルドして、

GDBと接続できました。

 

3.stubでGDBと接続は、できたのですが...

MATH

 

0x00000276のアドレスに書いてあるのは何だ?

と、GDBに言われました。

(文句を言われて、こんなに嬉しかったのは、始めてです (^^;; 接続できた証拠ですから...)

sh-elf-objdump -D sh2-stub

で、逆アセンブルしてものを見ると

00000250 <_start>:

250:00 09 nop

252:e0 00 mov#0,r0

254:e1 01 mov#1,r1

256:e2 02 mov#2,r2

258:e3 03 mov#3,r3

25a:e4 04 mov#4,r4

25c:e5 05 mov#5,r5

25e:e6 06 mov#6,r6

260:e7 07 mov#7,r7

262:e8 08 mov#8,r8

264:e9 09 mov#9,r9

266:ea 0a mov #10,r10

268:eb 0b mov #11,r11

26a:ec 0c mov #12,r12

26c:ed 0d mov #13,r13

26e:ee 0e mov #14,r14

270:d0 02 mov.l27c <gdbstartup_k>,r0 ! 0x18c

272:40 0b jsr@r0

274:00 09 nop

276:c3 21 trapa#32

278:00 09 nop

27a:00 09 nop

0000027c <gdbstartup_k>:

27c:00 00 .word 0x0000...

 

 

trapa #32の所です。

trapa #mm は、「命令による例外」と言うのだそうです。

serialの設定以外、割り込みのpriorityもなにも、触っていませんので

今、ここんとこを、調べている所です。

まだ、よく解らん...

H.16.2.25

 

 

This document created by Scientific Notebook 4.1. この文書は次の製品で作成しました Scientific Notebook 4.1.