ZYNQ LinuxのGigabitEtherのMACアドレスはどのように設定されるのか(後編)
LinuxのデバイスツリーはU-Bootが読み込んでいますが、実は、U-Bootはdevicetree.dtbをそのままメモリに展開しているのではなく、改変しています。
具体的に言うと、./common/fdt_support.c のvoid fdt_fixup_ethernet(void *fdt)でデバイスツリーの書き換えが行われています。
この関数は、まず、/aliasesの中を探して、ethernetで始まるプロパティを探します。
この値が
ethernet0 = "/amba@0/ps7-ethernet@e000b000";
だったとしましょう。
そうしたら、do_fixup_by_path()という関数が、
/amba@0の中のps7-ethernet@e000b000"のパスに、mac-addressとlocal-mac-addressという2つのプロパティを設定しようとします。
local-mac-addressは存在しない場合でも新規に作成するので、デバイスツリーにlocal-mac-addressが無くてもお構いなしです。それどころか、デバイスツリーで書いたlocal-mac-addressの値も無視して上書きします。
優先順位
MACアドレスの採用される優先順位の高い順に並べると、
- uEnv.txtの追加設定
- zynq-common.hに書かれたethaddr
- EEPROMの情報
- U-Bootが生成する乱数
----------- 越えられない壁 --------
(U-Bootがデバイスツリーを書き換えるから) - Linuxのデバイスツリーに書かれたプロパティ
- mac-address
- local-mac-address
- address
- ハードウェアレジスタの内容
- U-Bootが設定
- FSBLで設定した値
- Linuxの生成した乱数
となっています。
U-Bootがデバイスツリーを書き換えているのは、./common/fdt_support.cのfdt_fixup_ethernet()の中にある
do_fixup_by_path(fdt, path, "mac-address", &mac_addr, 6, 0); do_fixup_by_path(fdt, path, "local-mac-address", &mac_addr, 6, 1);
の部分です。
これをコメントアウトしてしまえば優先順位5以下のものが使用できるようになります。
なお、FSBLで設定した値を使うには、U-Bootのdefconfigで
#CONFIG_ZYNQ_GEM=y
とコメントアウトしてください。
最後の最後はLinuxが生成した乱数が使用されます。
LinuxからはMACアドレスを変更できないのか?
できません。
ドライバの中では、構造体に入っているlp->ndev->dev_addrという値がMACアドレスとして採用されますが、
この値は、probe時にデバイスツリー(あるいはU-Bootが書き換えたデバイスツリー)から設定されるほか、xemacps_update_hwaddr()という関数で書き換えられます。しかし、xemacps_update_hwaddr()もprobe時にしか呼び出されないので、
結局のところ、起動時に設定された値から変更することはできないのです。
結論
ボードごとに個別のMACアドレスを持たせたいなら、eEnv.txtにethaddの設定を書くのが簡単です。
ethaddr=02:11:22:33:44:55 uenvcmd=fatload mmc 0 0x03000000 uImage && fatload mmc 0 0x02A00000 devicetree.dtb && bootm 0x03000000 - 0x02A00000
ただし、ボードごとではなく、SDカードごとになってしまいます。
ボードごとにMACアドレスを振りたいならば、I2CのEEPROMを接続して、U-Bootで環境変数ethaddrを無効にし、EEPROMのアドレスとオフセットを指定したU-Bootを再構築してください。
I2CのEEPROMではなく、SPI ROMの値を使うにはどうしたらいいでしょうね・・
まぁ、ZYNQのボードにはI2CのEEPROMやIDチップを乗せておくのが無難です。
| 固定リンク
コメント
以下のコマンドでは駄目ですか?
# ifconfig eth0 down
# ifconfig eth0 hw ether 00:11:22:33:44:55
# ifconfig eth0 up
組み込みLinuxで、この方法で変更しています。
機器毎にカーネルの再構築は出来ないためです。
投稿: FLATSTONE | 2018.01.26 23:20
XILINXのxemacpsのドライバでは、その方法だと新しいMACアドレスが設定されても、すぐに元のMACアドレスに戻ってしまいます。
投稿: なひたふ | 2018.01.27 12:32