LoginSignup
1
1

More than 1 year has passed since last update.

MACアドレスの設定

Last updated at Posted at 2017-02-21

PCIのEthernetカードはMACアドレスがEEPROMに焼かれていますが、SOCでのEthernetサポートはMACアドレスはflashに保存されていてOSブート時にflashから読み出して設定するようになっています。

FreeBSDでのMACアドレスの設定は以下のような方法があります。

  • hintsにMACアドレスを直接書く
  • hintsにMACアドレスのFlashのアドレスを書く
  • dtsにMACアドレスを直接書く
  • dtsにMACアドレスのFlashのアドレスを書く
  • ブートローダーから渡された値を使用
  • rcでflashを読んで設定
  • ドライバが乱数で生成

これらはEthernetドライバが対応している事が条件になります。大抵のドライバは設定が無い場合はデフォルトのMACアドレスがハードコードされています。

AtherosのSOCのInterfaceのargeはflashから読み込みコードが実装されています。これはcfiなflashな場合について、flashの指定アドレスから読み込みます。指定は以下のようにhintsでおこないます。

hint.arge.0.eeprommac=0xbfff120c

設定はcfiの中の相対アドレスではなく物理アドレスになります。この設定のターゲットは

cfi0 at mem 0xbe000000-0xbfffffff on nexus0

となっていて、flashの相対アドレスの0x1ff120cから読み出している事になります。

SPIなflashを使ったターゲットではこの仕組みは機能しません。と思ったのですが、SPIなflashでも中身がメモリにマップされて読めるSOCであればcfiと同じようにアクセスできるような気がします。

FON2201ではFlashの最後の64KにAtherosが規定したデータがありこの中にMACアドレスがあります。この構造はsys/dev/ath/ath_hal/ah_soc.hに定義があります。以下のようにこれを読んでrcで設定することができます。

        # Import MAC addresses with known names
        MAGIC=`dd if=/dev/flash/spi0 bs=0x10000 skip=0x7f count=1 2>/dev/null | 
od -tx4 -N 4 | awk '/0000000/{print $2}'`
        if [ ${MAGIC} = "35333131" ]; then
                kenv WIFI_MAC_ADDR=`dd if=/dev/flash/spi0 bs=0x10000 skip=0x7f c
ount=1 2>/dev/null | od -t x1 | awk '/^0000140/{print $2":"$3":"$4":"$5":"$6":"$
7}'`
                kenv LAN_MAC_ADDR=`dd if=/dev/flash/spi0 bs=0x10000 skip=0x7f co
unt=1 2>/dev/null | od -t x1 | awk '/^0000140/{print $8":"$9":"$10":"$11":"$12":
"$13}'`

                ifconfig are0 ether `kenv LAN_MAC_ADDR`
        fi

geom_redbootはこの領域をパティションにしないので、flash全体から読み出しています。ddを使っているのはodでスキップすると遅いからです。

以前はodのjオプションを使っていましたが、512単位以外のjオプションの指定ができなくなったので、使わないようにしました。

誤って一バイト目の上位ビットが立ったMACアドレスを設定してしまうと、パケットがブロードキャストとして扱われ通信できなくなるので注意が必要です。

RT1310のターゲットのBuffalo WZR2-G300NのFlashをダンプしてMACアドレスを探してみたのですが見つかりません。どうもこの機種はWIFIチップにEEPROMが付いていて、そこにMACアドレスが入っていて、それをEthernetでも使い回しているのではないかと考えられます。

RT1310のインターフェースのfvはdtsで設定できるようにしてあるので、この機能で設定してください。

&enet0 {
        local-mac-address = [ 00 1a f1 01 1f 23 ];
};

RalinkのインターフェースのrtではカーネルオプションのUSE_GENERATED_MAC_ADDRESSで乱数でMACアドレスを生成する機能があります。

dev/usb/net/if_muge.cにも乱数でMACアドレスを生成する機能があるようです。

EtherチップのMACアドレスの設定方法は2種類あって、レジスタに放り込む方法とsetupframeというパケットに含めて送信する方法です。これはチップによって違ってて、areはレジスタに設定していてfvはsetupframeを使っています。

以下はu-bootの環境変数から拾い出すスクリプトです。

ENVPAT="/dev/flash/spi0s.u-boot-env"

        kenvmac=`kenv -q LAN_MAC_ADDR`
        if [ -z "$kenvmac" ]; then

                ETHADDR=`strings ${ENVPAT} | grep "^ethaddr="`
                if [ -n "$ETHADDR" ]; then
                        kenv LAN_MAC_ADDR=`echo ${ETHADDR} | awk -F"=" '{gsub("\"","",$2);print $2}'`

                        ifconfig rt0 ether `kenv LAN_MAC_ADDR`
                fi

        fi

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1