eFuse

Armadillo-IoT ゲートウェイ A6 で採用している CPU (i.MX6ULL) には、一度しか書き込むことのできない eFuse が搭載されています。 eFuse には、 CPUがブートする時の設定や MAC アドレスなどが書かれます。Armadillo-IoT ゲートウェイ A6 は組み込み機器を作り込むエンジニアを対象にした製品ですので、 eFuse もユーザーに開放し、細かな制御を可能にしています。しかし eFuse はその性質上、一度書き間違うと直すことができません。十分に注意してください。

[警告]

eFUSEは一度書き込むと元に戻すことができません。eFUSEの設定によってはArmadillo-IoT ゲートウェイ A6 が正常に動作しなくなる可能性がありますので、書き込みを行う際には細心の注意を払うようお願いいたします。eFUSEの設定によって異常が起こった場合は保証対象外となります。

MACアドレスは Armadillo-IoT ゲートウェイ A6 の出荷時に書き込まれているので、新たに書き込む必要はありません。この章では 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 現在の情報です。異るリビジョンのリファレンスマニュアルでは、章番号およびタイトルが異なる場合があります。

A.1. ブートモードとジャンパーピン

Armadillo-IoT ゲートウェイ A6 では サブユニット SW1(ユーザースイッチ) を microSD 側に設定することで、 JP1 及び JP2 双方ともショートさせることができます。 詳細は、「スライドスイッチの設定について」を参照ください。

A.1.1. ブートモードと JP2

i.MX6ULL にはブートモードを決める BOOT_MODE0BOOT_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-IoT ゲートウェイ A6 では、そのうちオンボードeMMC と microSDカードに対応しています。Internal Bootモードでは、GPIO によって eFuseの設定を上書き (override) できるようになっています。つまり eFuse の設定がどうなっていようと、GPIO のピンでブートデバイスを決めることができます。

Boot From Fusesモードでは、単純に言えば GPIO による override が禁止され eFuse に書き込まれた状態でしかブートしません。この機能を有効にすることで、フィールドに出した製品が悪意ある人によって意図していないブートをし、被害が出ることを防ぐことができます。(もちろん、ブート後に root アカウントを乗っ取られるような作りでは、意味がありませんが…)

A.1.2. ブートデバイスと JP1

Internal Bootモードでは、GPIO によって eFuseの設定を上書き (override) できるようになってると紹介しましたが、JP1 はまさにこの機能を使っています。 JP1 は LCD1_DATA05LCD1_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-IoT ゲートウェイ A6 では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-IoT ゲートウェイ A6では、eMMC が uSDHC1に、 microSDカードが uSDHC2 に接続されています。ブート時にどちらのコントローラーからブートするかを決めている eFuse が 0x450[12:11] です。 0x450[12:11]00 であれば uSDHC1 つまりオンボード eMMC から、01 であれば uSDHC2 つまり microSDカードからブートします。言い換えると Armadillo-IoT ゲートウェイ A6 でオンボード 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


A.2. eFuse の書き換え

Armadillo-IoT ゲートウェイ A6 では、U-Boot のコマンドによって eFuseの書き換えをサポートしています。 U-Boot については 10章ブートローダー (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 コマンドは、 bankwordcnthexval を引数に取ります。

bank
eFuse のバンク番号
word
eFuse のワード番号
cnt
eFuse を読み出す個数
hexval
書き込む値

A.3. Boot From Fusesモード

A.3.1. BT_FUSE_SEL

Boot From Fuses を有効にするには、 eFuse に書き込んだ値が正しいことを i.MX6ULL に教える必要があります。そのための eFuse が BT_FUSE_SEL (0x460[4]) です。BOOT_MODE00 、つまり JP2 がオープンで、且つこのビットが 1 であれば Boot From Fuses モードになります。 BOOT_MODE00 でも このビットが 0 であれば Boot From Fusesモードにはならず、 SD/MMC マニュファクチャリングモードやシリアルダウンロードモードになってしまいます。SD/MMCマニュファクチャリングモードについては 「8.12 SD/MMC manufacture mode」に、シリアルダウンロードモードについては「8.9 Serial Downloader」に記載されています。

[警告]

Armadillo-IoT ゲートウェイ A6 では BOOT_MODE00 で、且つ BT_FUSE_SEL0 の場合は SD/MMC マニュファクチャリングモードで eMMC から起動します。Internal Boot モードで起動する場合は、JP2 をショートしてください。

A.3.2. eMMC からのブートに固定

オンボード eMMC からだけブートさせたい場合は、ブートデバイスの種類で MMC と、コントローラーで uSDHC1 を選択することで可能です。忘れずに BT_FUSE_SEL1 にします。

オンボード 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_CFG1BOOT_CFG2 は、OCOTP_CFG4 にマップされており Bank 0 Word 5 です。つまり 010000000 01100010 の 16 bit (0x4062) を Bank 0 Word 5 に書き込めば良いことが分ります。 BOOT_CFG3BOOT_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-IoT ゲートウェイ A6 ができあがりました。

[警告]

eMMC からしか起動しないので、あやまって eMMCに書き込まれている U-Boot を消してしまうと、二度と起動しないようになります。注意してください。

[注記]

eMMC Fast Boot機能を使う場合や Power Cycle を Enable にする場合は、当該ビットを 1 に変更してください。

同じ要領で、SDからだけしかブートしないようにすることも可能です。しかし eFuse によるブートデバイスの固定は、意図しないブートを防ぐことが目的です。 Armadillo-IoT ゲートウェイ A6 で microSDからのブートに固定することは可能ですが、別の microSDカードを挿入されてしまうと、その別の microSDカードからブートしてしまうので目的を達成できません。理解してお使いください。

A.3.3. eFuse のロック

書き込んだ eFuse の値を変更されてしまっては、Boot From Fuseモードにしている意味がありません。i.MX6ULLでは eFuse を変更できなくするビットも用意されています。

リファレンスマニュアル「5.3 Fusemap Descriptions Table」を確認してください。