如何使用 linux 内核中的命令行参数更改 mac 地址
How to change a mac address using the command line parameters in the linux kernel
我想在 u-boot 级别更改 mac 地址,如下所示。
# setenv bootargs 'console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=${ethaddr}'
# setenv ethaddr 11:22:33:44:55:66
# saveenv
并且在 driver、
static unsigned char my_ethaddr[MAX_ADDR_LEN];
/* need to get the ether addr from armboot */
static int __init ethaddr_setup(char *line)
{
char *ep;
int i;
printk("command line : %s\n", line);
memset(my_ethaddr, 0, MAX_ADDR_LEN);
/* there should really be routines to do this stuff */
for (i = 0; i < 6; i++)
{
my_ethaddr[i] = line ? simple_strtoul(line, &ep, 16) : 0;
if (line)
line = (*ep) ? ep+1 : ep;
printk("mac[%d] = 0x%02Xn", i, my_ethaddr[i]);
}
return 0;
}
__setup("ethaddr=", ethaddr_setup);
启动时,日志消息如下。
[ 0.000000] Kernel command line: console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=${ethaddr}
[ 0.000000] command line : ${ethaddr}
[ 0.000000] mac[0] = 0x00, mac[1] = 0x00, mac[2] = 0x0E, mac[3] = 0x00, mac[4] = 0xDD, mac[5] = 0x00
命令行信息是${ethaddr},对吗?
mac 地址不正确。
我该如何解决?
您在以下位置使用了单引号:
setenv bootargs '... ethaddr=${ethaddr}'
所以 ${ethaddr}
没有展开,bootargs
变量包含文字字符串 ethaddr=${ethaddr}
,然后将其传递到内核,这就是您在调试输出中看到的内容。有关详细信息,请参阅 How the Command Line Parsing Works 上的 U-Boot 文档。
您可以使用双引号,或者根本不使用引号,在这种情况下 ${ethaddr}
将在分配给 bootargs
时展开,尽管您需要先设置它:
# setenv ethaddr 11:22:33:44:55:66
# setenv bootargs console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=${ethaddr}
# printenv bootargs
bootargs=console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=11:22:33:44:55:66
请注意,在某些系统中,ethaddr
变量被 U-Boot 本身用来配置第一个网络设备的 MAC 地址,以及 Linux 网络驱动程序可能会继续使用那个地址,所以你不需要明确地将它传递给内核。请参阅 U-Boot Environment Variables.
上的文档
此外 U-Boot 可以配置为防止修改 ethaddr
变量,尽管这里可能不是这种情况,因为当它是 U-Boot 时会打印错误消息:
Can't overwrite "ethaddr"
我想在 u-boot 级别更改 mac 地址,如下所示。
# setenv bootargs 'console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=${ethaddr}'
# setenv ethaddr 11:22:33:44:55:66
# saveenv
并且在 driver、
static unsigned char my_ethaddr[MAX_ADDR_LEN];
/* need to get the ether addr from armboot */
static int __init ethaddr_setup(char *line)
{
char *ep;
int i;
printk("command line : %s\n", line);
memset(my_ethaddr, 0, MAX_ADDR_LEN);
/* there should really be routines to do this stuff */
for (i = 0; i < 6; i++)
{
my_ethaddr[i] = line ? simple_strtoul(line, &ep, 16) : 0;
if (line)
line = (*ep) ? ep+1 : ep;
printk("mac[%d] = 0x%02Xn", i, my_ethaddr[i]);
}
return 0;
}
__setup("ethaddr=", ethaddr_setup);
启动时,日志消息如下。
[ 0.000000] Kernel command line: console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=${ethaddr}
[ 0.000000] command line : ${ethaddr}
[ 0.000000] mac[0] = 0x00, mac[1] = 0x00, mac[2] = 0x0E, mac[3] = 0x00, mac[4] = 0xDD, mac[5] = 0x00
命令行信息是${ethaddr},对吗? mac 地址不正确。
我该如何解决?
您在以下位置使用了单引号:
setenv bootargs '... ethaddr=${ethaddr}'
所以 ${ethaddr}
没有展开,bootargs
变量包含文字字符串 ethaddr=${ethaddr}
,然后将其传递到内核,这就是您在调试输出中看到的内容。有关详细信息,请参阅 How the Command Line Parsing Works 上的 U-Boot 文档。
您可以使用双引号,或者根本不使用引号,在这种情况下 ${ethaddr}
将在分配给 bootargs
时展开,尽管您需要先设置它:
# setenv ethaddr 11:22:33:44:55:66
# setenv bootargs console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=${ethaddr}
# printenv bootargs
bootargs=console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=11:22:33:44:55:66
请注意,在某些系统中,ethaddr
变量被 U-Boot 本身用来配置第一个网络设备的 MAC 地址,以及 Linux 网络驱动程序可能会继续使用那个地址,所以你不需要明确地将它传递给内核。请参阅 U-Boot Environment Variables.
此外 U-Boot 可以配置为防止修改 ethaddr
变量,尽管这里可能不是这种情况,因为当它是 U-Boot 时会打印错误消息:
Can't overwrite "ethaddr"