2007年12月24日

Flash2Advance Ultra (2GB) の解析:その1

先日のブログでフラッシュ種別の判別方法について記載したが、現在所有しているFlash2Advance Ultra 2Gで試してみた。

手順としては以下の通り。
  • アドレス 0x0930ECA8 に 0x5354 を write
  • アドレス 0x0802468A に 0x1234 を write (× 500回)
  • アドレス 0x0800ECA8 に 0x5354 を write
  • アドレス 0x0802468A に 0x5354 を write
  • アドレス 0x0802468A に 0x5678 を write (× 500回)
  • アドレス 0x0930ECA8 に 0x5354 を write
  • アドレス 0x0802468A に 0x5354 を write
  • アドレス 0x08ECA800 に 0x5678 を write
  • アドレス 0x080268A0 に 0x1234 を write
  • アドレス 0x0802468A に 0xABCD を write (× 500回)
  • アドレス 0x0930ECA8 に 0x5354 を write
  • アドレス 0x0930ECA8 に 0x5354 を write
  • アドレス 0x09E2468A に 0x9413 を write
  • アドレス 0x08000000 に 0x0090 を write
以上で、FlashメモリがIDモード(?)に移行する。
移行後、以下のアドレスにアクセスすることでベンダIDとプロダクトIDが取得できるみたい。
  • ベンダID(0x08000000) : 0x0089
  • プロダクトID(0x08000004) : 0x880D

また、IDモードに移行する前と移行した後での、メモリ空間ダンプ結果は以下の通り。

■移行前■
0x08000000 : 2E 00 00 EA 24 FF AE 51  69 9A A2 21 3D 84 82 0A
0x08000010 : 84 E4 09 AD 11 24 8B 98 C0 81 7F 21 A3 52 BE 19


■移行後■
0x08000000 : 89 00 00 EA 0D 88 AE 51  01 00 A2 21 01 00 82 0A
0x08000010 : 89 00 09 AD CF BF 8B 98 01 00 7F 21 01 00 BE 19


まだ、フラッシュの書き込み・消去方法等は分かっていないが、とりあえず今日はここまで‥‥


参考リンク

GBATEK和訳:http://meraman.dip.jp/index.php?M3DSS_GBATEK_GBA

2007年12月14日

Flash種別の判別方法(GBA FLinkerの解析)

F2A Ultra 2Gの制御(リード/ライト)を行うプログラムを作成しようと思案中。
そのために、カートリッジのフラッシュをどのように判別・アクセスをするのかを調査してみる。

FLinkerというツールにおいて、GBAのフラッシュやマジコン系のフラッシュへアクセスするソースコードが公開されているので、内容を確認してみた。

フラッシュ種別の判別
  • カートリッジの先頭アドレス(0x08000000)に0x90を書き込む
  • カートリッジの先頭アドレスを読み出す。読み出した値により‥‥
  • 0x00 → Hudson Cartridge
  • 0x2e → 一般的なROM
  • 0x89 → Intelのフラッシュ(具体的なデバイス種別は、他の方法で判別する)
  • 0xb0 → Sharpのフラッシュ
上記のように、デバイス種別の判別にはデバイスごとに異なる様子。
F2A Ultraにどのようなデバイスが搭載されているのかわからないことにはどうしようも無いな‥‥


参考リンク
FLinker:http://www.devrs.com/gba/software.php#misc

2007年12月4日

CART実行するためのリンカスクリプト

GBAでCART実行するプログラムを作る場合、
  • コンパイル(リンク)したプログラムでは、.dataセクションはROM上に存在する
  • 実動作をさせる場合には、.dataセクションはRAM上にコピーしなければならない
そのため、リンカスクリプトもMB用のものとは変えて作成しなければならない。
リンカスクリプトの作成時には、.dataセクション(.bssセクションも)が、LMAはROM上のアドレスで、VMAはRAM上のアドレスになるようにしなければならない。

devkitARMのリンカスクリプトも参考に、以下のリンカスクリプトを作成した。


MEMORY {
rom : ORIGIN = 0x08000000, LENGTH = 32M
iwram : ORIGIN = 0x03000000, LENGTH = 32K
ewram : ORIGIN = 0x02000000, LENGTH = 256K
}

SECTIONS {
. = ORIGIN(rom)
.text :
{
*(.text)
*(.glue_7)
*(.glue_7t)
} > rom
.rodata :
{
*(.rodata*)
} > rom

__data_lma = .;
.data : AT(__data_lma)
{
*(.data)
} > ewram
.bss :
{
*(.bss)
} > ewram
}
赤字の部分がポイント。
これで、リンカスクリプトは(たぶん)OK.

ただし、実際にROMで実行する場合は、.dataセクションをRAMへコピーするコードも作成する必要がある。


参考ページ
GNUリンカLDの使い方 : http://www.sra.co.jp/wingnut/ld/ld-ja_3.html

2007年12月2日

GBAのcartかmbか動的に判断する方法

GBAでは、カートリッジ(cart)から起動する方法とブートケーブル(mb)から起動する方法がある。
(ちなみに、mbは"Multi Boot"の頭文字)

2つの方法で、起動時のアドレスが異なる。(cart : 0x08000000, mb : 0x02000000)
これを利用してプログラムで起動モードに合わせて動的に処理を変更するプログラムが書ける。



.arm @ARMモードの場合。THUMBモードの場合はこれではダメ
movs r0, pc, lsl #5
bcs cart_proc
b mb_proc

cart_proc:
@ cart起動時の処理

mb_proc:
@ mb起動時の処理




ロジックは、プログラムの通りだが、
  • プログラムカウンタ(PC)を5ビット左シフトして、
  • キャリーが発生した場合は、cart起動
  • キャリーが発生しなかった場合は、mb起動
と判断すれば良い。(分かり易くするため、ブランチ命令をムダに使ってます‥)


devkitARMでも同様な処理をしているが、こちらはTHUMBモードで動作させているので、
アセンブラの書き方は異なっている。
THUMBモードはまだ良く分かっていないので、今回はARMモードでプログラム作成。

2007年12月1日

devkitARMのcrt解析

GBAでプログラミングを行うにあたり、crtファイルでどのような処理を行えば良いか調べる。
そのために、devkitProで公開されているdevkitARM(GBA等のARMプロセッサ用の開発ツールキット)のcrtがどのような処理を行っているか、ソースコードを追いかけてみる。
  1. GBAヘッダを定義 → GBAでは、ROMの先頭に所定のヘッダデータが必要
  2. IMEレジスタに、"割り込み可”を設定
  3. CPUモードの"IRQモード”および”SYSモード”のスタックポインタを設定
  4. .text領域の開始アドレスをチェック(CARTかMBかをチェックするため)
  5. CARTの場合は、EWRAMをゼロクリア
  6. .bbs領域をゼロクリア
  7. .data領域を、ROMからRAM(IWRAM)にコピー
  8. libcの初期化コードを実行
  9. ユーザプログラム(main関数)へジャンプ

3.で設定されるスタックポインタの値は、
  • IRQモード → 0x03007FA0
  • SYSモード → 0x03007F00
となっている。スタックサイズとしてこれで十分なのだろうか‥‥?


参考ページ
  • devkitPro ‥ GBAやDS等用の開発キットを提供しているプロジェクト
  • ARMメモ ‥ ARMプロセッサのデータシート和訳