平台:openwrt + QCA9561
方法1:
在rcS或者rc.local启动脚本中加入以下指令(适用于小批量的更改)
ifconfig NI hw ether xx:xx:xx:xx:xx:xx //NIC是网卡名称,xx是mac
方法二:
在对应网卡的network配置文件中加入(适用于小批量的更改)
option macaddr xx:xx:xx:xx:xx:xx
方法三:
高通无线相关的校准数据都是保存在openwrt的Flash的ART分区的,通过修改art中的mac地址对应区的内容从而修改mac
从启动时候的log中可以查看到flash的分区情况
Creating 6 MTD partitions on "spi0.0":
[ 0.690000] 0x000000000000-0x000000040000 : "u-boot"
[ 0.690000] 0x000000040000-0x000000050000 : "u-boot-env"
[ 0.700000] 0x000000050000-0x000000e80000 : "rootfs"
[ 0.700000] mtd: partition "rootfs" set to be root filesystem
[ 0.710000] mtd: partition "rootfs_data" created automatically, ofs=8D0000, len=5B0000
[ 0.720000] 0x0000008d0000-0x000000e80000 : "rootfs_data"
[ 0.730000] 0x000000e80000-0x000000ff0000 : "kernel"
[ 0.730000]
0x000000ff0000-0x000001000000 : "art"
[ 0.740000] 0x000000050000-0x000000ff0000 : "firmware"
[ 0.770000] ag71xx_mdio: probed
[ 0.890000] ag71xx_mdio: probed
[ 0.900000] eth0: Atheros AG71xx at 0xb9000000, irq 4
Qualcomm Atheros官方说明文档中对于ART分区的规定了MAC0也就是ETH0的MAC地址保存在0x0-0x5偏移地址 中,MAC1也就是ETH1的MAC地址保存在0x6-0xB偏移地址中,无线的MAC地址分别保存在0x1002-0x1008与 0x5002-0x5008偏移地址中。如果是单Radio设备,那么只有First Radio Calibration Data,如果是双Radio设备,会同时有First/Second Radio Calibration Data。
另外openwrt是用mtd的方式进行分区的,可以通过cat /proc/mtd查看art在flash中的那块block里面
dev: size erasesize name
mtd0: 00040000 00010000 "u-boot"
mtd1: 00010000 00010000 "u-boot-env"
mtd2: 00e30000 00010000 "rootfs"
mtd3: 005b0000 00010000 "rootfs_data"
mtd4: 00170000 00010000 "kernel"
mtd5: 00010000 00010000 "art"
mtd6: 00fa0000 00010000 "firmware"
上面可以看出art是在mtd5,那用cat /dev/mtd5 | hexdump 指令可以查看到mtd5的具体内容:
0000000
0016 fbb0 00b3 0016 fbb0 00b2 ffff ffff
0000010 ffff ffff ffff ffff ffff ffff ffff ffff
*
0001000 0202
0016 fbb0 00b0 0000 0000 0000 0000
0001010 0000 0000 0000 0000 0000 0000 0000 1f00
0001020 7702 0000 0000 0400 0c00 7d00 0300 08ff
0001030 0076 c13e 6320 0220 0011 1101 0010 0010
0001040 0010 0020 2020 0808 081c 0000 0000 0000
0001050 ff00 0002 0402 0606 0600 0000 0000 000f
0001060 0e0e 0300 2ce2 0002 0e1c f0f0 f000 f0f0
0001070 f000 0000 0000 0000 0000 0000 0000 0000
0001080 0000 0000 0000 0000 0000 7089 ac10 008e
0001090 0000 0012 008f 0000 0013 0090 0000 000c
00010a0 008d 0000 000e 008e 0000 0011 008e 0000
00010b0 0009 008e 0000 000a 008f 0000 000c 008f
00010c0 0000 0070 ac70 89ac 7089 ac70 89ac 3232
00010d0 3232 3232 3232 3030 3030 3030 3030 3030
00010e0 3030 2e2e 2e2e 2e2e 2e2e 2e2e 2e2e 2e2e
00010f0 2e2e 2e2e 2e2e 2e2e 2e2e 2e2e 2e2e 2e2e
*
0001130 2e2e 2e2e 2e2e 1112 1517 4142 4547 3132
0001140 3537 7075 acb8 7075 acb8 7075 acb8 7075
0001150 acb8 7075 acb8 7075 acb8 7075 acb8 7075
*
0001170 acb8 3c7c 3c7c 3c7c 3c7c 3c7c 3c7c 3c7c
0001180 3c7c 3c7c 3c7c 3c7c 3c7c 3c7c 3c7c 3c7c
*
00011a0 3c7c 1001 0000 2222 0200 0000 0000 0000
00011b0 0000 0000 0000 4400 0000 0000 00ff 0000
00011c0 0000 0000 0000 0000 0000 0000 000e 0e03
00011d0 002d e200 020e 1ce0 e0f0 0ce0 e0f0 6c00
00011e0 0000 0000 0000 0000 001c 1c00 0000 0000
00011f0 0000 0000 0000 004c 5468 788c a0b9 cd00
0001200 0000 0000 0000 0000 0000 0000 0000 0000
*
0001280 0000 0000 0000 0000 0000 0000 0000 004c
0001290 5468 788c a0b9 cd4c 5868 8cb4 bdb9 cd4c
00012a0 5868 8cb4 bdb9 cd14 1414 0a14 1414 0a14
00012b0 1414 0a14 1414 0a14 1414 0a14 1414 0a14
00012c0 1414 0a14 1414 0a14 140a 0a00 000a 0a00
00012d0 000a 0a00 0014 140a 0a00 000a 0a00 000a
00012e0 0a00 0014 140a 0a00 000a 0a00 000a 0a00
00012f0 0014 140a 0a00 000a 0a00 000a 0a00 0014
0001300 140a 0a00 000a 0a00 000a 0a00 0014 140a
0001310 0a00 000a 0a00 000a 0a00 0014 140a 0a00
0001320 000a 0a00 000a 0a00 0014 140a 0a00 000a
0001330 0a00 000a 0a00 0014 140a 0a00 000a 0a00
0001340 000a 0a00 0014 140a 0a00 000a 0a00 000a
0001350 0a00 0014 140a 0a00 000a 0a00 000a 0a00
0001360 0014 140a 0a00 000a 0a00 000a 0a00 0014
0001370 140a 0a00 000a 0a00 000a 0a00 0014 140a
0001380 0a00 000a 0a00 000a 0a00 0014 140a 0a00
0001390 000a 0a00 000a 0a00 0014 140a 0a00 000a
00013a0 0a00 000a 0a00 0010 1618 4046 4830 3638
00013b0 4c54 6878 8ca0 b9cd 4c54 6878 8ca0 b9cd
*
00013f0 4c54 6878 8ca0 b9cd 3c7c 3c7c 3c7c 3c7c
0001400 3c7c 3c7c 3c7c 3c7c 3c7c 3c7c 3c7c 3c7c
*
0001440 ffff ffff ffff ffff ffff ffff ffff ffff
*
0010000
上面红色部分0x0-0x5偏移地址 中,MAC1也就是ETH1的MAC地址保存在0x6-0xB偏移地址中,无线的MAC地址分别保存在0x1002-0x1007与 0x5002-0x5007偏移地址中。
导出这个文件假设导出文件命名为art-bk,然后用二进制文件编辑器修改对应的位,最后用ftp传到/tmp中,通过下面指令将原来的mtd5的art覆盖
mtd write art-bk art
方法四:
通过程序直接读取/dev/mtd5的内容,然后修改对应的位(适用于规模化生产)
int openwrt_mac_write(char *nic, char *value,int count)
{
int size = 0;
struct mtd_info_user mtdInfo;
struct erase_info_user mtdEraseInfo;
int fd = open(/dev/mtd5, O_RDWR | O_SYNC);
unsigned char *buf, *ptr;
int i;
if(fd < 0) {
printf("Could not open mtd device: %s\n", /dev/mtd5);
return -1;
}
if(ioctl(fd, MEMGETINFO, &mtdInfo)) {
printf("Could not get MTD device info from %s\n", /dev/mtd5);
close(fd);
return -1;
}
mtdEraseInfo.length = size = mtdInfo.erasesize;
buf = (unsigned char *)malloc(size);
if(NULL == buf){
printf("Allocate memory for size failed.\n");
close(fd);
return -1;
}
if(read(fd, buf, size) != size){
printf("read() %s failed\n", /dev/mtd5);
goto write_fail;
}
mtdEraseInfo.start = 0x0;
for (mtdEraseInfo.start; mtdEraseInfo.start < mtdInfo.size; mtdEraseInfo.start += mtdInfo.erasesize) {
ioctl(fd, MEMUNLOCK, &mtdEraseInfo);
if(ioctl(fd, MEMERASE, &mtdEraseInfo)){
printf("Failed to erase block on %s at 0x%x\n", /dev/mtd5, mtdEraseInfo.start);
goto write_fail;
}
}
if (!strcmp(nic, "wan"))
ptr = buf + WAN_OFFSET;
else if(!strcmp(nic, "lan"))
ptr = buf + LAN_OFFSET;
else if(!strcmp(nic, "ath0"))
ptr = buf + WIFI_OFFSET;
memcpy(ptr,value,count);
lseek(fd, 0, SEEK_SET);
if (write(fd, buf, size) != size) {
printf("write() %s failed\n", /dev/mtd5);
goto write_fail;
}
close(fd);
free(buf);
return 0;
write_fail:
close(fd);
free(buf);
return -1;
}
方法五:
通过fopen,fread,fseek,fwrite来修改/dev/mtd5