JTAGでFlashを焼く

UrJTAGやOpenOCDなどでCFIやNANDなFlashにbootを焼く場合二つのケースがあります。

* 既存のbootが動いている状態に焼く
* まっさら、または誤ったプログラムを書いてしまった状態に焼く

前者の場合は、初期化のコードが動いていてSDRAMやFlashが見える状態になっていて、簡単な手順で出来る事が多いです。

後者の場合は、本来bootがやってる初期化をUrJTAGやOpenOCDでやる必要がでてきてしまい、結構いばらの道です。いろいろ検索すると情報があるケースもありますが、無い場合はブートローダーのコードを参考にして初期化の処理を作る必要があります。

できるだけ消したり誤ったプログラムを焼かなければ良いのですが、一度焼いてブートせずFlashが見えなくなったときは、後者になるのであきらめずにがんばってください。^ ^;

仕様の分からないJTAGコネクタなどは結構厳しく、私もうまくいってないものが多いです。

追記：ピンを確認するためのプログラムを作ってみました。

https://qiita.com/yamori813/items/e493937c508977ae5cab

# KS8695の場合

古いSOCのKS8695(ARM 922T)のOpenOCD(0.10.0)の設定ファイルです。KS8695はKENDINが開発したSOCでその後、KENDINがMICREL買収されてMICRELでも販売されていました。

![写真（2019-02-17 13.46） #2.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/78f7355c-d1fb-9d1e-feb7-0c303fc7a431.jpeg)

```
# KS8695 OpenOCD configuration

source ../../tcl/target/ks869x.cfg

set _FLASHNAME $_CHIPNAME.flash0
flash bank $_FLASHNAME cfi 0x02000000 0x0200000 2 2 $_TARGETNAME 

init

proc flash_ks { } {

        halt
        mww 0x3ffe600 0xff
        mww 0x3ffe608 0xa0
        mww 0x3ff4010 0x8fe00040

        echo "... init routine ..."

        #this is the board init configuration file
        #which sets up the sdram and flash memory 
        #so that user can download code into sdram
        #and run it.
        #This file is used to enabe the demo board
        #when there is no code resides in the flash
        #memory
#       adapter_khz 8000
#       arm7_9 dcc_downloads enable       ;# Enable faster DCC downloads

        #Time to set up the SDRAM and Flash memory
        #comment set up external banks
        #CAN ALE
        #B31:22 = 3FC (end address = 0x3FCFFFF)
        #B21:12 = 3FC (start address = 0x3FC0000)
        #dword(0x03FF4000) = 0xFF3FCFFF
        mww 0x03ff4000 0xff3fcfff
        #CAN RD
        #B31:22 = 3FD (end address = 0x3FDFFFF)
        #B21:12 = 3FD (start address = 0x3FD0000) 
        #dword(0x03FF4004) = 0xFF7FDFFF
        mww 0x03ff4004 0xff7fdfff
        #CAN WR
        #B31:22 = 3FE (end address = 0x3FEFFFF)
        #B21:12 = 3FE (start address = 0x3FE0000)
        #dword(0x03FF4008) = 0xFFBFEFFF
        mww 0x03ff4008 0xffbfefff

        #======================================================================
        #################### MOST IMPORTANT TO BURN IMAGE #####################
        #======================================================================
        # *** Set up rom/flash  ***
        #======================================================================
        #Bank 0
        #B31:22 = 2FF (end address = 0x2FFFFFF)
        #B21:12 = 200 (start address = 0x2000000)
        #dword(0x03FF4010) = 0xBFE00070 
#        mww 0x03ff4010 0xbfe00070
        #Bank 1
        #B31:22 = 3FB (end address = 0x3FBFFFF)
        #B21:12 = 300 (start address = 0x3000000)
        #dword(0x03FF4014) = 0xFEF00070
#        mww 0x03ff4014 0xfef00070

        #External I/O and ROM/SRAM/FLASH General Register 
        # Enable CAN RD, CAN WR and CAN ALE
        #dword(0x03FF4020) =   0x30FF000F 
        #mww 0x03ff4020 0x30ff000f
        mww 0x03ff4020 0x30ff000a  
        #======================================================================

        #======================================================================
        # *** Set up SDRAM ***  
        #======================================================================
        #SDRAM Control Register 0 (0x4030)
        #B31:22 = 0FF (end address = 0xFFFFFF)
        #B21:12 = 000 (start address = 0x0)
        #dword(0x03FF4030) = 0x3FC0000E 
        mww 0x03ff4030 0x3fc0000e

        #SDRAM Control Register 1 (0x4034)
        #B31:22 = 1FF (end address = 0x1FFFFFF)
        #B21:12 = 100 (start address = 0x1000000)
        #dword(0x03FF4034) = 0x7FD0000E 
        mww 0x03ff4034 0x7fd0000e

        # Set global RAS/CAS timing
        #dword(0x03FF4038) = 0x0000000A 
        mww 0x03ff4038 0x0000000a
        #======================================================================


        #comment send NOP command 
        #dword(0x03FF403C) = 0x00030000 
        mww 0x03ff403c 0x00030000
        #comment wait for command to complete
        #comment send precharge command
        #dword(0x03FF403C) = 0x00010000 
        mww 0x03ff403c 0x00010000
        #comment wait for command to complete
        #dword(0x03FF4040) = 0x00000014 
        mww 0x03ff4040 0x00000014
        #comment wait for command to complete
        #comment set the refresh timer back
        #dword(0x03FF4040) = 0x00000168 
        mww 0x03ff4040 0x00000168
        #comment wait for command to complete
        #comment send Mode command
        #dword(0x03FF403C) = 0x00020033 #0x00020003
        mww 0x03ff403c 0x00020033
        #comment set clock to be the fastest one
        #dword(0x03FF0004) = 0x00
        mww 0x03ff4004 0x00000000
         
        flash info 0

        flash write_image erase u-boot.bin 0x02000000

        exit
}
```

ネットで見つけた情報といろいろ試行錯誤しました。

以下のように実行します。

```
bash-3.2$ ../openocd -f ../ft232h.cfg -f ks.cfg -c flash_ks
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: 15000 kHz
adapter speed: 6000 kHz
Info : auto-selecting first available session transport "jtag". To override use 
'transport select <transport>'.
fast memory access is enabled
dcc downloads are enabled
Info : clock speed 6000 kHz
Info : JTAG tap: ks869x.cpu tap/device found: 0x00922f0f (mfg: 0x787 (<unknown>)
, part: 0x0922, ver: 0x0)
Info : Embedded ICE version 2
Info : ks869x.cpu: hardware has 2 breakpoint/watchpoint units
flash_ks
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x400000d3 pc: 0x00700a6c
MMU: disabled, D-Cache: disabled, I-Cache: enabled
... init routine ...
Info : Flash Manufacturer/Device: 0x00ad 0x2249
#0 : cfi at 0x02000000, size 0x00200000, buswidth 2, chipwidth 2
        #  0: 0x00000000 (0x4000 16kB) not protected
        #  1: 0x00004000 (0x2000 8kB) not protected
        #  2: 0x00006000 (0x2000 8kB) not protected
        #  3: 0x00008000 (0x8000 32kB) not protected
        #  4: 0x00010000 (0x10000 64kB) not protected
        #  5: 0x00020000 (0x10000 64kB) not protected
        #  6: 0x00030000 (0x10000 64kB) not protected
        #  7: 0x00040000 (0x10000 64kB) not protected
        #  8: 0x00050000 (0x10000 64kB) not protected
        #  9: 0x00060000 (0x10000 64kB) not protected
        # 10: 0x00070000 (0x10000 64kB) not protected
        # 11: 0x00080000 (0x10000 64kB) not protected
        # 12: 0x00090000 (0x10000 64kB) not protected
        # 13: 0x000a0000 (0x10000 64kB) not protected
        # 14: 0x000b0000 (0x10000 64kB) not protected
        # 15: 0x000c0000 (0x10000 64kB) not protected
        # 16: 0x000d0000 (0x10000 64kB) not protected
        # 17: 0x000e0000 (0x10000 64kB) not protected
        # 18: 0x000f0000 (0x10000 64kB) not protected
        # 19: 0x00100000 (0x10000 64kB) not protected
        # 20: 0x00110000 (0x10000 64kB) not protected
        # 21: 0x00120000 (0x10000 64kB) not protected
        # 22: 0x00130000 (0x10000 64kB) not protected
        # 23: 0x00140000 (0x10000 64kB) not protected
        # 24: 0x00150000 (0x10000 64kB) not protected
        # 25: 0x00160000 (0x10000 64kB) not protected
        # 26: 0x00170000 (0x10000 64kB) not protected
        # 27: 0x00180000 (0x10000 64kB) not protected
        # 28: 0x00190000 (0x10000 64kB) not protected
        # 29: 0x001a0000 (0x10000 64kB) not protected
        # 30: 0x001b0000 (0x10000 64kB) not protected
        # 31: 0x001c0000 (0x10000 64kB) not protected
        # 32: 0x001d0000 (0x10000 64kB) not protected
        # 33: 0x001e0000 (0x10000 64kB) not protected
        # 34: 0x001f0000 (0x10000 64kB) not protected

CFI flash: mfr: 0x00ad, id:0x2249

qry: 'QRY', pri_id: 0x0002, pri_addr: 0x0040, alt_id: 0x0000, alt_addr: 0x0000
Vcc min: 2.7, Vcc max: 3.6, Vpp min: 0.0, Vpp max: 0.0
typ. word write timeout: 32 us, typ. buf write timeout: 1 us, typ. block erase t
imeout: 256 ms, typ. chip erase timeout: 8192 ms
max. word write timeout: 512 us, max. buf write timeout: 1 us, max. block erase 
timeout: 8192 ms, max. chip erase timeout: 8192 ms
size: 0x200000, interface desc: 2, max buffer write size: 0x1

Spansion primary algorithm extend information:
pri: 'PRI', version: 1.0
Silicon Rev.: 0x0, Address Sensitive unlock: 0x0
Erase Suspend: 0x2, Sector Protect: 0x1
VppMin: 0.2, VppMax: 0.0

auto erase enabled
wrote 131072 bytes from file u-boot.bin in 2.937661s (43.572 KiB/s)
```

上記の設定は完全にさらの状態から焼くための設定です。もし正しいbootが動いていて初期化が出来ていれば、flash_ksの初期化は

```
        mww 0x3ffe608 0xa0
        mww 0x3ff4010 0x8fe00040
```

だけで大丈夫です。

OpenOCDは設定ファイルが複雑でこれまであまり使わなかったのですが、書き込みがとんでもなく早くて、ちゃんと焼けてるか心配になります。

ちなみに上の操作で焼いているu-bootはこれです。

https://github.com/yamori813/u-boot-1.1.4-ks8695

FreeBSDのpkgのarmのgcc4でks8695l_configでビルドできます。

![RLogin-FT.png](https://qiita-image-store.s3.amazonaws.com/0/104066/9306dd25-4a91-faf1-da14-6a480ed5056e.png)

urjtagやopenocdでベンダーやプロダクトコードは見えてるけどCFIの情報が見えない場合はなんらかのおまじないが必要です。

```
jtag> detectflash 0xffe00000
dev ID=22da   man ID=00c2
urj_flash_amd_detect: mid 1000, did 1000
error: flash: mid != 0x01
```

OpenOCDはarmがメインですが書き込みが早いです。UrJTAGはいろいろなアーキテクチャの対応がありmipsも充実してますが、書き込みが遅いです。ターゲット毎に使える方を使っています。

余談ですが、ARMの20ピンのJTAGをMIPSの14ピンに変換する治具を作ったのですが、部品やケースにあたって使えない事があり、残念な結果です。。。

![写真（2019-02-20 21.26）.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/b03c7c7c-83df-16cb-b6a8-e86c1f7bd3c6.jpeg)