ページ 1 / 1
startup.sに関する参考サイトはありませんか
Posted: 2011年1月24日(月) 10:46
by およよ
Cygwin GCCで、SH-2A用プログラムを組んでいます。
スタートアッププログラムstartup.sのリセットベクタを
編集する必要が出てきたのですが、参考になるサイトがありません。
手元にある組み込み関連の書籍にも詳しく書かれておらず、
手のつけようがありません。参考になるサイトをご存知のかたはいらっしゃいませんか。
やりたいことは、
「ベクタ・テーブルが先頭になるようにセクションを配置。
ベクタ番号8(先頭から9番目)にベクタ・テーブルの先頭アドレスを配置してください」
という指示を守るということです。
以下編集すべきstartup.sの一部を抜粋します。
コード:
# パワーオンリセットベクタ
.org 0x00
.long __startup
.long _stack_base
# マニュアルリセットベクタ
.long __startup
.long _stack_base
.org 0x84
# Trap33
#.long _trap33_exception
.org 0x88
# Trap34
#.long _trap34_exception
.org 0x200
# ERI_0
.long 0x0
# RXI_0
.long 0x0
# TXI_0
.long 0x0
# TEI_0
.long 0x0
.org 0x400
.global __startup
.type __startup, @function
コーディングの参考にせよ、というasmfunc.sの抜粋を以下に示します。
コード:
/*-------------------------------------*/
/* Vector table for exception handlers */
/*-------------------------------------*/
.section .VECTOR, "ax"
vector_table:
.long boot_por /* 0 Power-on reset vector, PC */
.long stack_base /* 1 Power-on reset vector, SP */
.long boot_mr /* 2 Manual reset vector, PC */
.long stack_base /* 3 Manual reset vector, SP */
.long trap /* 4 General illigal instruction */
.long trap /* 5 - */
.long trap /* 6 Slot illigal instruction */
.long trap /* 7 - */
.long vector_table /* 8 - <Used by SPI-FlashBoot> ←これをコードに記述する */
.long trap /* 9 CPU address error */
.long trap /* 10 DMA address error */
.long trap /* 11 NMI */
.long trap /* 12 - */
.long trap /* 13 FPU exception */
.long trap /* 14 User debug interface */
.long trap /* 15 Bank overflow */
.long trap /* 16 Bank underflow */
.long trap /* 17 Division by 0 */
.long trap /* 18 Division overflow */
#はコメントアウトなのか?TABはスペースは意味が異なるのか?
ドットに続く文字は予約語なのか?あるいはユーザー変数なのか?
ファイル名は任意なのか?そもそもこれはアセンブラなのか?
全く分からず困っています。
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月24日(月) 11:36
by softya(ソフト屋)
>#はコメントアウトなのか?TABはスペースは意味が異なるのか?
#はコメントアウトですね。
TABかスペースどちらでも。
>ドットに続く文字は予約語なのか?あるいはユーザー変数なのか?
アセンブラの予約語です。
>ファイル名は任意なのか?そもそもこれはアセンブラなのか?
makefileに書いてあると思いますので、そこを変えればどうにでもなります。むやみに変える必要はないと思いますが。
gas(GNU Assembler)と言うアセンブラですね。
英語マニュアルですが。
http://sourceware.org/binutils/docs-2.18/as/index.html
CPU機種別に機能が分かれています。
>やりたいことは、
>「ベクタ・テーブルが先頭になるようにセクションを配置。
>ベクタ番号8(先頭から9番目)にベクタ・テーブルの先頭アドレスを配置してください」
>という指示を守るということです。
SuperHのベクタテーブルの構造はすでに覚えていませんが、リンカスクリプトでセクションの配置を制御できます。
なのでmakefileとリンカスクリプトを確認してみてください。
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月24日(月) 11:58
by およよ
早速のご回答ありがとうございます。
> 英語マニュアルですが。
>
http://sourceware.org/binutils/docs-2.18/as/index.html
> CPU機種別に機能が分かれています。
ううむ、藪をつついて蛇が出てきたようですね・・・
参考サイトも書籍むなく不安ではありますが、
これだけてがかりがあれば、とりあえずOKです。
英文の説明だけでなんとかやってみましょう。
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月24日(月) 14:35
by softya(ソフト屋)
startup.sならサイトを見つけたんですがベクターテーブルの組み込み方が全く違うのでかえって混乱すると思って避けました。
一応参考書籍を挙げておきますが、お望みのことが書かれているかは自信がありません。
「SH-2マイコンで学ぶ組み込み開発入門」
http://shop.cqpub.co.jp/book_guide/detail/49931/
「SH-2開発ブック for MES & gcc」
http://www.cutt.co.jp/book/978-4-87783-215-5.html
「インターフェイス2010年7月号 マイコンと周辺装置のつなげかた~SH-2A編~」
http://www.kumikomi.net/interface/contents/201007.php
もっとちゃんとしたのだと、
「O'Reilly Japan - CとGNU開発ツールによる組み込みシステムプログラミング 第2版」
http://www.oreilly.co.jp/books/9784873113265/
「O'Reilly Japan - GNUソフトウェアプログラミング」
http://www.oreilly.co.jp/books/4900900206/
「O'Reilly Japan - GNU Make 第3版」
http://www.oreilly.co.jp/books/4873112699/
辺りだと思います。
少なくとも予定通りに並んだかはリンカでマップ出力してアドレスを確認して下さい。
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月24日(月) 19:51
by およよ
GNU Make、インターフェース2010年7月号は持っています。
CとGNU開発ツール・・・あたりが本命のような。
とにかく記述の自由度が高いのかして、ひとつとして同じスタイルの
コーディング例がないですし。。。とりあえずゆっくりと解読してみます。
余談ですがインターフェース、記事ごとに開発環境が
ばらばらなのもいかがなものかと。
私みたいな初心者は毎度大混乱です。
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月24日(月) 20:09
by softya(ソフト屋)
およよ さんが書きました:GNU Make、インターフェース2010年7月号は持っています。
CとGNU開発ツール・・・あたりが本命のような。
とにかく記述の自由度が高いのかして、ひとつとして同じスタイルの
コーディング例がないですし。。。とりあえずゆっくりと解読してみます。
ベクタテーブルは、C言語で言えば単なる関数ポインタの配列ですのでアドレス(ラベル名)を並べているだけです。
ちなみに
.org 0x00
は以降のセクション内のアドレスを0x00に変更します。
.long __startup
は、longで4バイトの領域で_startup ラベルのアドレスを格納するって意味になると思います。
およよ さんが書きました:
余談ですがインターフェース、記事ごとに開発環境が
ばらばらなのもいかがなものかと。
私みたいな初心者は毎度大混乱です。
色んなライターさんが同時に書いているので、しょうがない処はあるんですどね。
それぞれに得意なものが違いますし。
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月24日(月) 22:09
by およよ
なるほど、かなり明瞭に構造が見えてきました。
つまり、#以降は1行コメント。
Exception Vectorはリセットベクタをベクタ番号0から順に羅列しただけのもの。
本来長ったらしいテーブルになるところ、.org を使って
目的のベクタ・テーブルアドレスまで一気にオフセットできる。
ジャンプ先ラベルのアドレスを格納するのに、long型=4byteを要する。
電源ONや手動リセットなど例外要因が発生した時、
ジャンプ先のラベルに記述されたアセンブラプログラムを実行する。
「ベクタ・テーブルが先頭になるようにセクションを配置。
ベクタ番号8(先頭から9番目)にベクタ・テーブルの先頭アドレスを配置してください」
この課題を今のターゲットSH7262(SH2A-FPU)に適用すると、
SH-2A、SH2A-FPU ソフトウェアマニュアル
3.1.3 例外処理ベクタテーブル 表3.3 より
コード:
# パワーオンリセットベクタ
.org 0x00
.long __startup
.long _stack_base
# マニュアルリセットベクタ
.long __startup
.long _stack_base
# (システム予約)
.org 0x20 /* ベクタ番号 8 */
.long vector_table
#以下省略
となりますね。
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月24日(月) 22:21
by およよ
すみません、自分自身のラベルをコードに含め忘れました。
コード:
vector_table:
# パワーオンリセットベクタ
.org 0x00
.long __startup
.long _stack_base
# マニュアルリセットベクタ
.long __startup
.long _stack_base
# (システム予約)
.org 0x20 /* ベクタ番号 8 */
.long vector_table
#以下省略
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月24日(月) 23:19
by softya(ソフト屋)
それで大丈夫だと思います。
あとは、リンカスクリプトとリンク時にマップを出してアドレスが合っているか確認してください。
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月25日(火) 12:01
by およよ
startup.sを上記のように修正し、
LEDを点滅させるサンプルコードdownload_sample.cをコンパイルしました。
結果、download_sample.mapは次のようになりました・・・
コード:
Memory Configuration
Name Origin Length Attributes
*default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
.start 0x000000001c000000 0x550
0x000000001c000000 _sstarttext = .
0x000000001c000000 _user_vector_base = .
startup.o(.text)
.text 0x000000001c000000 0x550 startup.o
0x000000001c000400 _startup
0x000000001c000550 _estarttext = .
.text 0x000000001c000550 0xcc
0x000000001c000550 _stext = .
*(.text)
.text 0x000000001c000550 0xcc download_sample.o
0x000000001c000550 interrupt_handler
0x000000001c00055a main
0x000000001c00061c _etext = .
.rela.dyn 0x000000001c00061c 0x0
.rela.text 0x0000000000000000 0x0 startup.o
.rdata 0x000000001c00061c 0x0
0x000000001c00061c _srdata = .
*(.rodata)
*(.rodata.str1.4)
0x000000001c00061c _erdata = .
.data 0x000000001c00061c 0x0
0x000000001c00061c _sdata = .
*(.data)
.data 0x000000001c00061c 0x0 startup.o
.data 0x000000001c00061c 0x0 download_sample.o
*(.COMMON)
*(.zdata)
0x000000001c00061c _edata = .
.bss 0x000000001c00061c 0x0
0x000000001c00061c _sbss = .
*(.bss)
.bss 0x000000001c00061c 0x0 startup.o
.bss 0x000000001c00061c 0x0 download_sample.o
0x000000001c00061c _ebss = .
0x000000001c00061c _end = .
0x000000001c100000 . = 0x1c100000
0x000000001c100000 _stack_base = .
0x00000000fff8fffc . = 0xfff8fffc
0x00000000fff8fffc _user_vbr = .
LOAD startup.o
LOAD download_sample.o
OUTPUT(download_sample.elf elf32-sh)
.debug_line 0x0000000000000000 0x11b
.debug_line 0x0000000000000000 0xca startup.o
.debug_line 0x00000000000000ca 0x51 download_sample.o
.debug_info 0x0000000000000000 0x101
.debug_info 0x0000000000000000 0x4b startup.o
.debug_info 0x000000000000004b 0xb6 download_sample.o
.debug_abbrev 0x0000000000000000 0x88
.debug_abbrev 0x0000000000000000 0x14 startup.o
.debug_abbrev 0x0000000000000014 0x74 download_sample.o
.debug_aranges 0x0000000000000000 0x40
.debug_aranges
0x0000000000000000 0x20 startup.o
.debug_aranges
0x0000000000000020 0x20 download_sample.o
.debug_frame 0x0000000000000000 0x48
.debug_frame 0x0000000000000000 0x48 download_sample.o
.debug_loc 0x0000000000000000 0x62
.debug_loc 0x0000000000000000 0x62 download_sample.o
.debug_pubnames
0x0000000000000000 0x31
.debug_pubnames
0x0000000000000000 0x31 download_sample.o
.debug_str 0x0000000000000000 0x81
.debug_str 0x0000000000000000 0x81 download_sample.o
0x8e (size before relaxing)
.comment 0x0000000000000000 0x12
.comment 0x0000000000000000 0x12 download_sample.o
またまた良く分かりませんが、
.debug_aranges セクションに 0x20 startup.o が見えますね。
セクション メモリアドレス 謎のアドレス オブジェクトファイル
最初のセクションはELFセクションだと思いますが、
謎のアドレスが何なのかが判明しないとなんとも言えません。
別に用意されている memory.def セクション定義にて
コード:
.start 0x1C000000 : {
_sstarttext = .;
_user_vector_base = .;
startup.o(.text)
_estarttext = .;
}
を記述してあり、プログラムは 0x1C000000 以降に配置されます。
いずれここも触ることになるでしょうが・・・
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月26日(水) 14:17
by softya(ソフト屋)
申し訳ない。遅くなりました。
SH7262のハードウェアマニュアルを見てみたのですが、ベクタテーベルの8番目は未定義みたいなのですが、なぜ8番目に設定する必要があるのでしょうか?
1c000000だと内蔵RAMのメモリアドレスだと思うのですが、VBRが1c000000に切り替えられないとうまく動作しませんが、ここら辺はブートモードやブートローダなどの関わる話なので、今までの話からではうまく作られているかどうかは判断できません。
アドレスマップはちゃんとしているように見えますが、オフセット値が表示されないのでイマイチ自信は持てませんね。クロスリファレンス(--cref) も表示すればわかるようになるのか?
gccのldのリンクマップってこんなに分かりづらかったっけ?うーむ。
Re: startup.sに関する参考サイトはありませんか
Posted: 2011年1月26日(水) 14:56
by およよ
いかんせん .MAP は初めて見るものなので、
分かりにくいけどこんなもんかな・・・という印象しかありません。
memory.def のアドレスを試行錯誤で調整し
これを訂正したところ、なんとか正常動作を確認しました・・・解決になってませんが。
ベクタ番号8について、インターフェース2010年6,7月号にもあるのですが
とにかくそこに配置せよということですので、従っています。
雑誌付録CPUのプログラムを簡単にするため、
雑誌執筆陣がイレギュラーな起動手順を踏んでいることに
初学の私が気づいていないだけかも知れません。
ここからはメモリのレイアウトに関わってくるので、
公開の場で質問することの意義がなくなってきたかもしれません。
状況を整理して、もう少し考えてみます。