Armadillo-610 で採用している CPU (i.MX6ULL) には、一度しか書き込むことのできない eFuse が搭載されています。 eFuse には、 CPUがブートする時の設定や MAC アドレスなどが書かれます。Armadillo-610 は組み込み機器を作り込むエンジニアを対象にした製品ですので、 eFuse もユーザーに開放し、細かな制御を可能にしています。しかし eFuse はその性質上、一度書き間違うと直すことができません。十分に注意してください。
| |
---|
eFUSEは一度書き込むと元に戻すことができません。eFUSEの設定によってはArmadillo-610が正常に動作しなくなる可能性がありますので、書き込みを行う際には細心の注意を払うようお願いいたします。eFUSEの設定によって異常が起こった場合は保証対象外となります。 |
MACアドレスは Armadillo-610 の出荷時に書き込まれているので、新たに書き込む必要はありません。この章では 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
というピンがあります。 Armadillo-610 では、BOOT_MODE0
は 0
、BOOT_MODE1
は 1
となるよう回路が設計されており、ブートモードは必ず Internal Boot モードとなります。
Internal Bootモードでは、 on-chip boot ROMに書き込まれているコードが実行し、ブート可能なデバイスを検索します。リファレンスマニュアル「8.5 Boot devices (internal boot)」に、i.MX6ULL がブートできるデバイスの一覧が記載されています。Armadillo-610 では、そのうちオンボードeMMC と microSDカードに対応しています。
Internal Bootモードでは、GPIO によって eFuseの設定を上書き (override) できるようになっています。この機能は eFuse の BT_FUSE_SEL
が 0
の場合のみ有効となります。eFuse の設定とは異なり何度も再設定できる点では便利ですが、overrideに対応したピンには i.MX6ULL の電源投入時に決まった信号を入力しておかなければいけないため、ハードウェア設計上は不便になります。
Armadillo-610では、GPIO による override を利用することで、仕様が確定していない段階ではブートデバイスを自由に何度も切り替えることを可能にしつつ、BT_FUSE_SEL
を 1
にして GPIO による override を無効化することで、仕様が確定した段階では自由なハードウェア設計が可能になるよう配慮しています。また、GPIO による override を無効化することで、フィールドに出した製品が悪意ある人によって意図していないブートをし、被害が出ることを防ぐことができます。(もちろん、ブート後に root アカウントを乗っ取られるような作りでは、意味がありませんが…)
Internal Bootモードでは、GPIO によって eFuseの設定を上書き (override) できるようになってると紹介しましたが、Armadillo-610 では、Armadillo-610 拡張ボードの JP1 はまさにこの機能を使っています。 JP1 は BJP1(Armadillo-610 CON2_42ピン) に接続されており、 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-610 ではSDカード または 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-610では、eMMC が uSDHC1に、 microSDカードが uSDHC2 に接続されています。ブート時にどちらのコントローラーからブートするかを決めている eFuse が 0x450[12:11]
です。 0x450[12:11]
が 00
であれば uSDHC1 つまりオンボード eMMC から、01
であれば uSDHC2 つまり microSDカードからブートします。言い換えると Armadillo-610 でオンボード 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-610 では、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
-
書き込む値
A.4. eFuse の設定によるブートデバイスの選択
eFuse の設定によるブートデバイスの選択を可能にするには、 eFuse に書き込んだ値が正しいことを i.MX6ULL に教える必要があります。そのための eFuse が BT_FUSE_SEL
(0x460[4]
) です。Armadillo-610 では、このビットが 1
であれば、GPIO による override が無効になり eFuse の設定にしたがってブートデバイスが選択されるようになります。
オンボード 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-610 ができあがりました。
| |
---|
eMMC からしか起動しないので、あやまって eMMCに書き込まれている U-Boot を消してしまうと、二度と起動しないようになります。注意してください。 |
| |
---|
eMMC Fast Boot機能を使う場合や Power Cycle を Enable にする場合は、当該ビットを 1 に変更してください。 |
同じ要領で、SDからだけしかブートしないようにすることも可能です。しかし eFuse によるブートデバイスの固定は、意図しないブートを防ぐことが目的です。 Armadillo-610 で microSDからのブートに固定することは可能ですが、別の microSDカードを挿入されてしまうと、その別の microSDカードからブートしてしまうので目的を達成できません。理解してお使いください。
書き込んだ eFuse の値を変更されてしまっては、Boot From Fuseモードにしている意味がありません。i.MX6ULLでは eFuse を変更できなくするビットも用意されています。
リファレンスマニュアル「5.3 Fusemap Descriptions Table」を確認してください。