カーネルのバージョン:Linuxバージョン3.10.14
eth0のの各開発ボードブートカードの物理アドレスとして、1はランダムであります
その後の行は、物理アドレス設定macコマンドを達成するために、インターネット上で見つけることができます:
ifconfigコマンドeth0の下
にifconfig eth0をHWエーテル1234567890ab
ifconfigコマンドeth0をアップ
そして、カーネルコマンドラインifconfigコマンドは、私が試してみたい、と相互作用しているかを確認するために好奇心がかかり、自動的にカーネルによって直接MACを設定する方法。
2.分析入門
コマンドはifconfigコマンドであるため、コードはbusyboxのですが、私たちは、ifconfigコマンドの導入のカーネルのドキュメントディレクトリにある、コードファイルは次の場所にあります。紹介:ドキュメント\ネットワーク\のifenslave.c
2.1を以下に示し、対応するifconfigコマンドeth0をダウンifconfigコマンドはeth0アップ関数です。
たとえば、私たちがノックするときにifconfig eth0のダウン時間を、実際にはそれが呼び出すことです。
set_if_down(" eth0を"、master_flags.ifr_flags)。
マップ上のファイルに加えて、以下の機能が使用されます。
set_if_addrは(); // (IP、マスク、ブロードキャスト、宛先を含む)のアドレスを設定し set_master_hwaddrを(); // 物理アドレス、MACを設定します
次は追跡するため、例えばは、eth0 /ダウンifconfigコマンドを起動し、ifconfigコマンドeth0をHWエーテルカーネルを呼び出す方法
3. set_if_up()関数を分析
3.1分析set_if_up()
set_if_up()関数が呼び出されます| set_if_flags(IFF_UP "eth0を"、旗)を追加し、インターフェイス(eth0)のifNameをオープンフラグ
3.2分析set_if_up() - > set_if_flags( "eth0の"、旗| IFF_UP)
次のように関数は次のとおりです。
静的 INT set_if_flags(CHAR *のifName、ショートフラグ) { 構造体いるifreq IFR; INT RES = 0 ; ifr.ifr_flagsは = フラグを、 strncpyを(ifr.ifr_name、のifName、IFNAMSIZ); // ifr.ifr_name = "eth0の" RES = IOCTL (skfd、SIOCSIFFLAGS、&IFR); // のioctl()コマンドによって、カーネル変数SIOCSIFFLAGSに送信され、IFRソケット IF(RES < 0 ){ saved_errno = ; errnoを v_print("インターフェイス'%s'はエラー:SIOCSIFFLAGSに失敗しました:%S \ nを" のifName、にstrerror(saved_errno)); } 他{ v_print(" インターフェイス'%S':%04Xに設定されたフラグ\ N。" 、のifName、フラグ); } 戻りRES; }
カーネルでそれを達成するための場所を確認するために探して3.3マクロSIOCSIFFLAGS
ネット\コアを見つけます\のDev_ioctl.c dev_ioctl()関数
次のように機能コードの重要な部分は次のとおりです。
int型 dev_ioctl(構造体 NET * NET、符号なし整数 CMD、無効 __user * のArg) { 構造体いるifreq IFR; int型RET; char型 * コロン; // ... ... スイッチ(CMD){ // ... ... ケース SIOCSIFFLAGS: // 設定されたフラグ、このようにifconfigアップ/ダウンなどの ケース:SIOCSIFMETRIC ケース SIOCSIFMTU: // 設定MUT長 ケース SIOCSIFHWADDR: // 物理アドレス、MACを設定 // ... ... dev_load(NET、ifr.ifr_name); // ifr.ifr_name(eth0の)名前でカードをロードする rtnl_lock(); // net_deviceするためには、操作との競合を避けるために、ロックされて RET = dev_ifsioc(NET、&IFR、CMDを); / / 最後に、関数呼び出し rtnl_unlockを(); 戻りRET; // ... }
上記からわかるように、物理アドレスも最終的に、彼らは呼ぶ、ここで実行されているとき、私たちは、Macの流れを設定しdev_ifsioc(ネット&IFR、CMD ) 機能を
4.バックは非常に簡単で、そして最終的にはifconfigコマンドは、最大カーネルプロセスを呼び出すはeth0:
set_if_up() - > set_if_flags(" eth0の"、旗| IFF_UP) - > dev_ifsioc(ネット、&IFR、CMD) - > dev_change_flags(DEV、IFR - > ifr_flags) - > __dev_change_flags(DEV、フラグ);
次いで、4.1 __dev_change_flags(DEV、フラグ)関数は、eth0のを切り替える)((達成__dev_closeを呼び出し、逆IFF_UPビットかどうかのフラグの値によって決定される)、または__dev_openれます
下図のように:
net_device_ops構造4.2と__dev_openでのメンバ関数は、()のオープンを達成するためにNICドライバを呼び出します。
__dev_open(DEV): DEV - > netdev_ops-> ndo_validate_addr(DEV); // テストDEV-> dev_addr(HW ADDR)有効な、通常eth_validate_addr()を呼び出す関数である、あなたがhw_addrに注意を払う必要があるが[0]の最下位ビットがすることはできませんです1 DEV-> netdev_ops-> ndo_open(DEV); // ifconfigコマンドを達成するために()関数を呼び出すオープン
4.3同様__dev_close()メンバ関数はクロージャを達成するため次の呼び出し:
DEV-> netdev_ops-> ndo_stop(DEV); //はダウンifconfigコマンドを達成するために、停止()関数を呼び出します
4.4どこに位置net_device_ops構造メンバ関数を見つけるために
構造体net_device DEV変数の型は、上記で述べたように、そして構造体net_deviceは、当社のネットワークカードドライバ機器のいずれかを表し、登録文書はregister_netdevにより、カーネル内()カーネル関数を登録するには、変数のカーネルドライバ/ netディレクトリにあります。
我々は)私たちのボードDM9000カードを持って、たとえば、ファイルは、ドライバ/ネット/イーサネット/のDavicom / dm9000.cに位置しており、その後、あなたは(それがndo_open見つけることができます:
以下のようにifconfigのeth0 HWエーテルNIC設定処理について5です。
set_master_hwaddr(master_ifname、&(slave_hwaddr.ifr_hwaddr)) - > のioctl(skfd、SIOCSIFHWADDR、&IFR) - > dev_ifsioc(NET、&IFR、CMD) - > dev_set_mac_address(DEV、&ifr-> ifr_hwaddrの値) - > // 設定するMACアドレス DEV - > netdev_ops-> ndo_set_mac_address(DEV、&ifr-> ifr_hwaddrの値); // 最後のコールnet_deviceオプスメンバ関数セットを達成するために、
6.カーネルブート自動的に設定された固定MACアドレスを実装
分析プロセスの後、我々はそれを実装する必要があります。
一例として、私たちのボードに6.1 DM9000カード
私たちは、ネット/イーサネット/のDavicom / /ドライバーにregister_netdev()の場所を見つける dm9000.c のdm9000_probeに機能:
その後、6.2 register_netdev()関数は、以下のコードを追加します。
ストラクト のsockaddrのHWaddrを; // MACアドレス構造ストアに rtnl_lockを(); RET = dev_close(jz_ndev); // ケースで、カードを閉鎖する最初必要性 ; rtnl_unlock() hwaddr.sa_family = ndev-> 型; のHWaddr .sa_data [ 0 ] = 0x12を ; // ノート、データが[0]の最下位ビットが1ではない、それは最初の奇数ない hwaddr.sa_data [ 1 ] = 0x34の; hwaddr.sa_data [ 2 ] = 0x56 ; [hwaddr.sa_data 3 ] = 0x78と; hwaddr.sa_dataの[ 4 ] =0x90を; hwaddr.sa_data [ 5 ] = 0xAB ; rtnl_lock(); RET = dev_set_mac_address(jz_ndev、&のHWaddr); // 我々の分析に関数を呼び出すは、MACアドレスを設定すること )(rtnl_unlockします。
6.3コンパイル - テスト
入力開始後にifconfigコマンドを、あなたはカーネルは私が設定役立っている見ることができます。