龙芯3B-itx 小板, 使用了intel82574l的网卡, 所以改mac就很简单了。
debian下安装ethtool软件包。
aptitude install ethtool
然后直接改mac地址为 00:23:9e:00:00:01
ethtool --change-eeprom eth0 magic 0x10d38086 offset 0x00 value 0x00
ethtool --change-eeprom eth0 magic 0x10d38086 offset 0x01 value 0x23
ethtool --change-eeprom eth0 magic 0x10d38086 offset 0x02 value 0x9e
ethtool --change-eeprom eth0 magic 0x10d38086 offset 0x03 value 0x00
ethtool --change-eeprom eth0 magic 0x10d38086 offset 0x04 value 0x00
ethtool --change-eeprom eth0 magic 0x10d38086 offset 0x05 value 0x01
0x10d38086 是网卡的pid vid ,lcpci -nn 可以看到
03:00.0 Ethernet controller [0200]: Intel Corporation 82574L Gigabit Network Connection [8086:10d3]
应该是新版本的内核的功能,现在修改e1000e网卡的eeprom,可以自动计算校验和了,以前需要自己算一下,eeprom的长度0x40个字, 高位在后,累加起来等于0xbaba.
可以用ethtool --eeprom-dump 来显示eeprom内容
root@henanzls:~# ethtool --eeprom-dump eth0
Offset Values
------ ------
0x0000: 00 23 9e 00 00 01 20 0c 46 f7 13 20 ff ff ff ff
0x0010: ff ff ff ff 6b 02 00 00 86 80 d3 10 ff ff 5a 80
0x0020: 00 00 01 20 74 7e ff ff 00 10 c8 00 00 00 04 27
0x0030: c9 6c 50 31 3a 07 0b 46 84 2d 40 01 00 f0 01 0f
0x0040: 00 60 80 00 04 0f ff 7f 01 4d 00 c6 00 00 ff 20
0x0050: 28 00 03 00 00 00 00 00 00 00 03 00 00 00 ff ff
0x0060: 00 01 00 40 1c 12 07 40 ff ff ff ff ff ff ff ff
0x0070: ff ff ff ff ff ff ff ff ff ff 00 01 ff ff 5e b7
校验算法在linux内核的 drivers/net/ethernet/intel/e1000e/nvm.c
提取出来如下:
<pre>
#include <stdio.h>
#include <stdint.h>
uint8_t nv[300]={
0x00,0x23,0x9e,0x00,0x00,0x01,0x20,0x0c,0x46,0xf7,0x13,0x20,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0x6b,0x02,0x00,0x00,0x86,0x80,0xd3,0x10,0xff,0xff,0x5a,0x80,
0x00,0x00,0x01,0x20,0x74,0x7e,0xff,0xff,0x00,0x10,0xc8,0x00,0x00,0x00,0x04,0x27,
0xc9,0x6c,0x50,0x31,0x3a,0x07,0x0b,0x46,0x84,0x2d,0x40,0x01,0x00,0xf0,0x01,0x0f,
0x00,0x60,0x80,0x00,0x04,0x0f,0xff,0x7f,0x01,0x4d,0x00,0xc6,0x00,0x00,0xff,0x20,
0x28,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0xff,0xff,
0x00,0x01,0x00,0x40,0x1c,0x12,0x07,0x40,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xff,0xff,0x4c,0x0c
};
#define NVM_CHECKSUM_REG 0x3f
#define NVM_SUM 0xBABA
void main(void)
{
uint16_t checksum = 0;
uint16_t i, nvm_data;
for (i = 0; i < (NVM_CHECKSUM_REG +1); i++) {
nvm_data = nv[i*2] | (nv[i*2+1]<<8);
if(i % 8==0) printf("\n0x%04x: ",i);
printf("%02x %02x ",nv[i*2],nv[i*2+1]);
checksum += nvm_data;
}
if (checksum != (uint16_t)NVM_SUM) {
printf("\nNVM Checksum Invalid,%04x\n",checksum);
checksum=checksum-nvm_data;
printf("\nold=%02x %02x\n",nvm_data&0xff,(nvm_data&0xff00)>>8);
nvm_data=NVM_SUM -checksum;
printf("\nnew=%02x %02x\n",nvm_data&0xff,(nvm_data&0xff00)>>8);
} else {
printf("\nnew=%02x %02x\n",nvm_data&0xff,(nvm_data&0xff00)>>8);
}
}
</pre>