【Raspberry Pi】u-bootでJTAGピンを有効にする

スポンサーリンク

Raspberry Piで、ベアメタルなソフト開発をするのに、JTAGデバックできた方が便利なのだが、初期状態ではJTAGの信号がGPIOコネクタに割り当てられていない。
そこで、u-bootの初期化ソースコードを修正して、JTAGピンを有効化し「JTAGデバッガ」を接続できるようにする。

JTAGデバッガ

JTAGデバッガは各社色々あるが、ネットでRaspberry Piで動作報告されてるのは下記のものがある。(他のものも使えると思う)

  • Olimex ARM-USB-TINY-H
  • Segger J-LINK

ARM-USB-TINY-Hは安価でいいが、私が持ってる環境では動作できなかった。手持ちにあった「J-Link」ではRaspberry Pi 2とZeroでは動作確認できた。Raspberry Pi 3は、Cortex-A53で新しめのCPUなので未対応?なのか私の環境ではまだ動作できてないが、今後試して確認できたら報告していきたい。

※追記(2019/5/8)※
J-Linkも、Raspberry Pi 3のCortex-A53には対応済み(2018 Jun.14)のようです。下記URL。

J-Link 64-bit support
64-bit support added to the J-Link, specifically for the ARMv8A architecture. Tested with ARM Cortex-A53 multi core devi...

JTAGデバッガのピン配置

JTAGデバッガのピン配置は「ARM JTAG 20」というARM社より決められており(参考1)、この20ピンコネクタ配列で作られたJTAGデバッガが一般に多い。

ピン番号(奇数番) 機能(奇数番) ピン番号(偶数番) 機能(偶数番)
1 VTREF 2 VTARGET
3 nTRST 4 GND
5 TDI 6 GND
7 TMS 8 GND
9 TCK 10 GND
11 RTCK 12 GND
13 TDO 14 GND
15 nSRST 16 GND
17 DBGRQ 18 GND
19 DBGACK 20 GND

Raspberry PiのJTAGピン配置

Raspberry Pi側のJTAGピンは、40ピンコネクタにGPIOと共用となっている。そこでJTAGを利用するには、プログラムでGPIOのモードをAlternativeモードに設定し、JTAGポートとして設定する必要がある。その設定を行うため、対象のピン番号とGPIO、GPIOモードの対応を下記に示す。Alternativeモードの対応についてはBCM2835 ARM Peripheralsの資料(参考3)を参照。

ピン番号 GPIO番号 GPIOモード 機能(JTAG)
15 GPIO22 ALT4 ARM_TRST
7 GPIO4 ALT5 ARM_TDI
13 GPIO27 ALT4 ARM_TMS
22 GPIO25 ALT4 ARM_TCK
18 GPIO24 ALT4 ARM_TDO

Raspberry PiとJTAGデバッガの接続

上記で示した対応表をまとめると、JTAGデバッガとRaspberry Piのコネクタは下記の対応で接続する必要がある。

機能 ピン番号(Raspberry Pi) ピン番号(ARM JTAG 20)
VTREF 1 1
TRST 15 3
TDI 7 5
TMS 13 7
TCK 22 9
TDO 18 13
GND 20,25 4,6,..,20

私は、USB-シリアルのケーブルも接続できるように、下記写真のケーブルを作成した。

u-bootでJTAGピンを有効にする

u-bootソースコードの初期化処理の箇所を修正する。
尚、コンパイル方法については前の記事を参照。

【Ubuntu 18.04/16.04 LTS】Raspberry Pi用のu-bootをコンパイルする
「Raspberry Pi」用に、u-bootをUbuntのLinux上でコンパイルする。 ARMクロスコンパイル環境の準備 ARMツールチェーンなどのコンパイル環境は、下記記事でインストール済の環境を使う。 macOSでもコンパイル可能。...

1)/arch/arm/cpu/arm1176/start.S

以下#ifdef〜#endifの行を追加

reset:
        /*
         * set the cpu to SVC32 mode
         */
        mrs     r0, cpsr
        bic     r0, r0, #0x3f
        orr     r0, r0, #0xd3
        msr     cpsr, r0

#ifdef CONFIG_BCM2835
        /* setup JTAG pin */
        ldr     r1, =0x20200000       @ GPFSEL0
        ldr     r0, [r1]
        bic     r0, r0, #7 << (3*4)   @ GPIO 04 clear
        orr     r0, r0, #2 << (3*4)   @ GPIO 04 set ALT5(ARM_TDI)
        str     r0, [r1]

        ldr     r1, =0x20200008       @ GPFSEL2
        ldr     r0, [r1]
        bic     r0, r0, #7 << (3*2)   @ GPIO 22 clear
        orr     r0, r0, #3 << (3*2)   @ GPIO 22 set ALT4(ARM_TRST)
        bic     r0, r0, #7 << (3*4)   @ GPIO 24 clear
        orr     r0, r0, #3 << (3*4)   @ GPIO 24 set ALT4(ARM_TDO)
        bic     r0, r0, #7 << (3*5)   @ GPIO 25 clear
        orr     r0, r0, #3 << (3*5)   @ GPIO 25 set ALT4(ARM_TCK)
        bic     r0, r0, #7 << (3*7)   @ GPIO 27 clear
        orr     r0, r0, #3 << (3*7)   @ GPIO 27 set ALT4(ARM_TMS)
        str     r0, [r1]
#endif

/*
 *************************************************************************
 *

2)/arch/arm/cpu/armv7/start.S

以下#if〜#endifの行を追加

reset:
        /* Allow the board to save important registers */
        b       save_boot_params
save_boot_params_ret:
        /*
         * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
         * except if in HYP mode already
         */
        mrs     r0, cpsr
        and     r1, r0, #0x1f           @ mask mode bits
        teq     r1, #0x1a               @ test for HYP mode
        bicne   r0, r0, #0x1f           @ clear all mode bits
        orrne   r0, r0, #0x13           @ set SVC mode
        orr     r0, r0, #0xc0           @ disable FIQ and IRQ
        msr     cpsr,r0

#if defined(CONFIG_BCM2836) || defined(CONFIG_BCM2837_32B)
        /* setup JTAG pin */
        ldr     r1, =0x3F200000       @ GPFSEL0
        ldr     r0, [r1]
        bic     r0, r0, #7 << (3*4)   @ GPIO 04 clear
        orr     r0, r0, #2 << (3*4)   @ GPIO 04 set ALT5(ARM_TDI)
        str     r0, [r1]

        ldr     r1, =0x3F200008       @ GPFSEL2
        ldr     r0, [r1]
        bic     r0, r0, #7 << (3*2)   @ GPIO 22 clear
        orr     r0, r0, #3 << (3*2)   @ GPIO 22 set ALT4(ARM_TRST)
        bic     r0, r0, #7 << (3*4)   @ GPIO 24 clear
        orr     r0, r0, #3 << (3*4)   @ GPIO 24 set ALT4(ARM_TDO)
        bic     r0, r0, #7 << (3*5)   @ GPIO 25 clear
        orr     r0, r0, #3 << (3*5)   @ GPIO 25 set ALT4(ARM_TCK)
        bic     r0, r0, #7 << (3*7)   @ GPIO 27 clear
        orr     r0, r0, #3 << (3*7)   @ GPIO 27 set ALT4(ARM_TMS)
        str     r0, [r1]
#endif

/*
 * Setup vector:
 * (OMAP4 spl TEXT_BASE is not 32 byte aligned.

作成したu-bootを起動してみる

上記で作成したu-boot.binをSDカードに書込み(前の記事参照)電源起動してu-bootが起動すると、JTAGデバッガが使える状態になる。
JTAGデバッガから、自作プログラムを転送してのソースデバックなどできる。

u-bootは最初0x8000番地から実行されるが、その後、後ろのアドレスに自分自身を移動して動作する。なので自作プログラムは、0x8000番地〜に配置するように作ればOK。
又、u-bootが移動するアドレス関係を理解しシンボル情報が解決できればu-boot自体のデバックも可能。

【Raspberry Pi】u-bootを動かす
前の記事で作成した、u-bootを、「Raspberry Pi」に入れて、動かしてみる。 シリアル接続の準備 u-bootでは、シリアル通信を使って、コマンド入出力する。 シリアル-USB変換ケーブルが必要で、私はアマゾンから下記を入手。搭...

コンパイル済u-bootバイナリファイル(2016/8/25追記)

GitHubに公開、後の記事で紹介。

【Raspberry Pi】u-bootバイナリファイル公開(JTAGピン有効版)
関連記事で報告した、Raspbery Pi Zero〜3用のコンパイル済みu-bootのバイナリファイルをGitHubに公開した。(下記URL) u-boot起動に必要な全てのファイルを同梱。JTAGピンも有効にしてあり、コンパイル環境を揃...

参考

  1. ARM DSTREAM システムおよびインターフェースデザイン リファレンス(p.3-17)
  2. ベアメタルで遊ぶRaspberry Pi
  3. BCM2835 ARM Peripherals
  4. raspberrypi/documentation
  5. KMC Staff Blog:U-Bootのデバッグ

コメント

タイトルとURLをコピーしました