Armadillo-640 で採用している CPU (i.MX6ULL) には、一度しか書き込むことのできない eFuse が搭載されています。 eFuse には、 CPUがブートする時の設定や MAC アドレスなどが書かれます。Armadillo-640 は組み込み機器を作り込むエンジニアを対象にした製品ですので、 eFuse もユーザーに開放し、細かな制御を可能にしています。しかし eFuse はその性質上、一度書き間違うと直すことができません。十分に注意してください。
| |
---|
eFUSEは一度書き込むと元に戻すことができません。eFUSEの設定によってはArmadillo-640が正常に動作しなくなる可能性がありますので、書き込みを行う際には細心の注意を払うようお願いいたします。eFUSEの設定によって異常が起こった場合は保証対象外となります。 |
MACアドレスは Armadillo-640 の出荷時に書き込まれているので、新たに書き込む必要はありません。この章では U-Boot を使って eFuse の書き換えを行い、ブートモードを制御する方法を説明します。
eFuse を変更する場合は、必ず「i.MX 6ULL Applications Processor Reference Manual」を参照してください。重要な章は、以下の 4つです。
-
Chapter 5: Fusemap
-
Chatper 8: System Boot
-
Chapter 37: On-Chip OTP Controller
-
Chapter 58: Ultra Secured Digital Host Controller
以降、本章では i.MX 6ULL Applications Processor Reference Manual を「リファレンスマニュアル」と呼びます。
| |
---|
章番号や章タイトルは、i.MX 6ULL Applications Processor Reference Manual Rev. 1, 11/2017 現在の情報です。異るリビジョンのリファレンスマニュアルでは、章番号およびタイトルが異なる場合があります。 |
i.MX6ULL にはブートモードを決める BOOT_MODE0
と BOOT_MODE1
というピンがあります。 BOOT_MODE0
は GND になっているので必ず 0
になります。BOOT_MODE1
は JP2 に接続されています。 JP2 がショートされていると BOOT_MODE1
は 1 になり Internal Boot モードになります。開放されていると 0 となり、 Boot From Fuses というモードになります。
Internal Bootモードでは、 on-chip boot ROMに書き込まれているコードが実行し、ブート可能なデバイスを検索します。リファレンスマニュアル「8.5 Boot devices (internal boot)」に、i.MX6ULL がブートできるデバイスの一覧が記載されています。Armadillo-640 では、そのうちオンボードeMMC と microSDカードに対応しています。Internal Bootモードでは、GPIO によって eFuseの設定を上書き (override) できるようになっています。つまり eFuse の設定がどうなっていようと、GPIO のピンでブートデバイスを決めることができます。
Boot From Fusesモードでは、単純に言えば GPIO による override が禁止され eFuse に書き込まれた状態でしかブートしません。この機能を有効にすることで、フィールドに出した製品が悪意ある人によって意図していないブートをし、被害が出ることを防ぐことができます。(もちろん、ブート後に root アカウントを乗っ取られるような作りでは、意味がありませんが…)
Internal Bootモードでは、GPIO によって eFuseの設定を上書き (override) できるようになってると紹介しましたが、JP1 はまさにこの機能を使っています。 JP1 は LCD1_DATA05
と LCD1_DATA11
の制御をしていますが、これらのピンはそれぞれ BOOT_CFG1[5]
と BOOT_CFG2[3]
を override しています。「8.3.2 GPIO boot overrides」の 表「8-3. GPIO override contact assignments」を確認してください。
ややこしい事に、この BOOT_CFG
で始まる eFUSE は、リファレンスマニュアルの中では eFuse のアドレスでも表記されています。 BOOT_CFG1
は eFuse のアドレスで言うと 0x450
の下位 8 bit つまり 0x450[7:0]
であり、 BOOT_CFG2
は上位 8 bit つまり 0x450[15:8]
にあたります。これは「5.1 Boot Fusemap」の表「5-5. SD/eSD Boot Fusemap」または表「5-6. MMC/eMMC Boot Fusemap」を確認することでわかります。
さらにややこしい事に、eFuse を書き込む場合にはこれら全ての値が使えず、On-Chip OTP Controller の bank と word の値が必要になります。これらの値は リファレンスマニュアルの「On-Chip OTP Controller」を参照してください。後で出てきますが Boot From Fuses で使用する BT_FUSE_SEL
という eFuse のように GPIO による override ができないものもあります。
表A.1 GPIO override と eFuse
信号名 | eFuse名 | eFuseアドレス | OCOTP名 | Bank | Word |
---|
LCD1_DATA05
| BOOT_CFG1[5]
| 0x450[5]
| OCOTP_CFG4 | 0 | 5 |
LCD1_DATA11
| BOOT_CFG2[3]
| 0x450[11]
| OCOTP_CFG4 | 0 | 5 |
N/A | BT_FUSE_SEL
| 0x460[4]
| OCOTP_CFG5 | 0 | 6 |
Armadillo-640 ではmicroSDカード または eMMC からのブートになるので、ブートデバイスを選択する eFuse BOOT_CFG1[7:4]
は、010x
または 011x
になります。
リファレンスマニュアル「8.5.3.1 Expansion device eFUSE configuration」には、さらに詳しく SD/MMCデバイスの設定について記載されています。テーブル「8-15. USDHC boot eFUSE descriptions」によれば、eFuse の 0x450[7:6]
が 01
の場合に SD/MMC デバイスからブートすることを決めています。さらに 0x450[5]
が 0
なら SDが、 0x450[5]
が 1
なら MMC が選択されます。つまり、4から 7 bit までの間で 5 bit 目だけが MMC か SD かを決めています。 BOOT_CFG1[5]
が 0
の場合はコントローラーは SDデバイスが繋がっている前提で、 BOOT_CFG1[5]
が 1
の場合は MMCデバイスが繋っている前提で動作します。
i.MX6ULL には、SD/MMC のコントローラーである uSDHC が 2つ搭載されています。 Armadillo-640では、eMMC が uSDHC1に、 microSDカードが uSDHC2 に接続されています。ブート時にどちらのコントローラーからブートするかを決めている eFuse が 0x450[12:11]
です。 0x450[12:11]
が 00
であれば uSDHC1 つまりオンボード eMMC から、01
であれば uSDHC2 つまり microSDカードからブートします。言い換えると Armadillo-640 でオンボード eMMC からブートしたい場合は、0x450[5]
を 1
に、 0x450[12:11]
を 00
にします。逆に microSDカードから起動したい場合は 0x450[5]
を 0
に、0x450[12:11]
を 01
にします。
表A.2 ブートデバイスと eFuse
ブートデバイス | eFuse 0x450[5] | 0x450[12:11] |
---|
オンボード eMMC | 1
| 00
|
microSDカード | 0
| 01
|
Armadillo-640 では、U-Boot のコマンドによって eFuseの書き換えをサポートしています。 U-Boot については 9章ブートローダー (U-Boot) 仕様 を参照してください。
eFuse の書き換えは、 fuse
コマンドを使います。
| |
---|
U-Boot の fuse コマンドのソースコードは、以下の 2つです。 -
cmd/fuse.c
-
drivers/misc/mxc_ocotp.c
|
=> help fuse
fuse - Fuse sub-system
Usage:
fuse read <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words,
starting at 'word'
fuse sense <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words,
starting at 'word'
fuse prog [-y] <bank> <word> <hexval> [<hexval>...] - program 1 or
several fuse words, starting at 'word' (PERMANENT)
fuse override <bank> <word> <hexval> [<hexval>...] - override 1 or
several fuse words, starting at 'word'
=>
-
fuse read
-
eFuse の値を Shadow Registerから読み出します。i.MX6ULL の eFuse は、すべて Shadow Register を持ち、起動時に eFuse から Shadow Register に値がコピーされます。詳しくはリファレンスマニュアル「37.3.1.1 Shadow Register Reload」を確認してください。
-
fuse sense
-
eFuse の値を eFuse から読み出します
-
fuse prog
-
eFuse の値を書き換えます
fuse
コマンドは、 bank
、 word
、cnt
、 hexval
を引数に取ります。
-
bank
-
eFuse のバンク番号
-
word
-
eFuse のワード番号
-
cnt
-
eFuse を読み出す個数
-
hexval
-
書き込む値
Boot From Fuses を有効にするには、 eFuse に書き込んだ値が正しいことを i.MX6ULL に教える必要があります。そのための eFuse が BT_FUSE_SEL
(0x460[4]
) です。BOOT_MODE
が 00
、つまり JP2 がオープンで、且つこのビットが 1
であれば Boot From Fuses モードになります。 BOOT_MODE
が 00
でも このビットが 0
であれば Boot From Fusesモードにはならず、 SD/MMC マニュファクチャリングモードやシリアルダウンロードモードになってしまいます。SD/MMCマニュファクチャリングモードについては 「8.12 SD/MMC manufacture mode」に、シリアルダウンロードモードについては「8.9 Serial Downloader」に記載されています。
| |
---|
Armadillo-640 では BOOT_MODE が 00 で、且つ BT_FUSE_SEL が 0 の場合は SD/MMC マニュファクチャリングモードで eMMC から起動します。Internal Boot モードで起動する場合は、JP2 をショートしてください。 |
オンボード eMMC からだけブートさせたい場合は、ブートデバイスの種類で MMC と、コントローラーで uSDHC1 を選択することで可能です。忘れずに BT_FUSE_SEL
を 1
にします。
オンボード eMMC のスペックは、以下の通りです。リファレンスマニュアル 8.5.3 Expansion device および 表「5-6. MMC/eMMC Boot Fusemap」を確認してください。「可変」列が「不」となっている値は、変更しないでください。例えば、オンボード eMMC は 1.8 V に対応していません。 bit 9 の SD Voltage Selection で 1
の 1.8 V では動作しません。
表A.3 オンボード eMMC のスペック
名前 | Bit | eFuse | 値 | bit列 | 可変 |
---|
BOOT_CFG2
| [15:13]
| Bus Width | 8 bit | 010
| 不 |
[12:11]
| Port Select | uSDHC1 | 00
| 不 |
[10]
| Boot Frequencies | 500 / 400 MHz | 00
| 可 |
[9]
| SD Voltage Selection | 3.3 V | 0
| 不 |
[8]
| - | - | 0
| - |
BOOT_CFG1
| [7:5]
| eMMC | - | 011
| 不 |
[4]
| Fast Boot | Regular | 0
| 可 |
[3]
| SD/MMC Speed | High | 0
| 不 |
[2]
| Fast Boot Acknowledge Disable | Enabled | 0
| 可 |
[1]
| SD Power Cycle Enable | Enabled | 1
| 可 |
[0]
| SD Loopback Clock Source Sel | SD Pad | 0
| 不 |
値を見易いように、 BOOT_CFG2
を上にしています。 BOOT_CFG1
と BOOT_CFG2
は、OCOTP_CFG4
にマップされており Bank 0 Word 5 です。つまり 010000000 01100010
の 16 bit (0x4062
) を Bank 0 Word 5 に書き込めば良いことが分ります。 BOOT_CFG3
と BOOT_CFG4
はここでは無視します。
BT_FUSE_SEL
は Bank 0 Word 6 の 4 bit 目になるので 0x10 を書き込みます。
=> fuse read 0 5
Reading bank 0:
Word 0x00000005: 00000000
=> fuse prog 0 5 0x4060
Programming bank 0 word 0x00000005 to 0x00004060...
Warning: Programming fuses is an irreversible operation!
This may brick your system.
Use this command only if you are sure of what you are doing!
Really perform this fuse programming? <y/N>
y
=> fuse read 0 6
Reading bank 0:
Word 0x00000006: 00000000
=> fuse prog -y 0 6 0x10
Programming bank 0 word 0x00000006 to 0x00000010...
=> fuse read 0 6
Reading bank 0:
Word 0x00000006: 00000010
(電源入れなおしても、SDからブートしない)
| |
---|
fuse prog にオプション -y を付けると 「 Really perform this fuse programming? <y/N> 」と聞かれません。
|
これで eMMC からしか起動しない Armadillo-640 ができあがりました。
| |
---|
eMMC からしか起動しないので、あやまって eMMCに書き込まれている U-Boot を消してしまうと、二度と起動しないようになります。注意してください。 |
| |
---|
eMMC Fast Boot機能を使う場合や Power Cycle を Enable にする場合は、当該ビットを 1 に変更してください。 |
同じ要領で、SDからだけしかブートしないようにすることも可能です。しかし eFuse によるブートデバイスの固定は、意図しないブートを防ぐことが目的です。 Armadillo-640 で microSDからのブートに固定することは可能ですが、別の microSDカードを挿入されてしまうと、その別の microSDカードからブートしてしまうので目的を達成できません。理解してお使いください。
書き込んだ eFuse の値を変更されてしまっては、Boot From Fuseモードにしている意味がありません。i.MX6ULLでは eFuse を変更できなくするビットも用意されています。
リファレンスマニュアル「5.3 Fusemap Descriptions Table」を確認してください。