Uboot获取mac地址流程

5 篇文章 2 订阅
3 篇文章 0 订阅

代码

代码位置:uboot/net/eth-uclass.c

	/* Check if the device has a valid MAC address in device tree */
	if (!eth_dev_get_mac_address(dev, pdata->enetaddr) ||
	    !is_valid_ethaddr(pdata->enetaddr)) {
		source = "ROM";
		/* Check if the device has a MAC address in ROM */
		if (eth_get_ops(dev)->read_rom_hwaddr)
			eth_get_ops(dev)->read_rom_hwaddr(dev);
	}

	eth_env_get_enetaddr_by_index("eth", dev_seq(dev), env_enetaddr);
	if (!is_zero_ethaddr(env_enetaddr)) {
		if (!is_zero_ethaddr(pdata->enetaddr) &&
		    memcmp(pdata->enetaddr, env_enetaddr, ARP_HLEN)) {
			printf("\nWarning: %s MAC addresses don't match:\n",
			       dev->name);
			printf("Address in %s is\t\t%pM\n",
			       source, pdata->enetaddr);
			printf("Address in environment is\t%pM\n",
			       env_enetaddr);
		}

		/* Override the ROM MAC address */
		memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN);
	} else if (is_valid_ethaddr(pdata->enetaddr)) {
		eth_env_set_enetaddr_by_index("eth", dev_seq(dev),
					      pdata->enetaddr);
	} else if (is_zero_ethaddr(pdata->enetaddr) ||
		   !is_valid_ethaddr(pdata->enetaddr)) {
#ifdef CONFIG_NET_RANDOM_ETHADDR
		net_random_ethaddr(pdata->enetaddr);
		printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
		       dev->name, dev_seq(dev), pdata->enetaddr);
		eth_env_set_enetaddr_by_index("eth", dev_seq(dev),
					      pdata->enetaddr);
#else
		printf("\nError: %s address not set.\n",
		       dev->name);
		return -EINVAL;
#endif
	}

解析

首先尝试从设备树中读取mac地址:

eth_dev_get_mac_address(dev, pdata->enetaddr),读取设备树命名为中"mac-address"或"local-mac-address"的数组,
如果读取失败了,或者读取成功但是经检测mac地址无效(是组播地址,或者全是0),那么就进行第二步,尝试从fec网卡驱动获取mac地址。
读取成功则进行第三步。

第二步从fec网卡驱动读取mac地址:

eth_get_ops(dev)->read_rom_hwaddr(dev),之后进行第三步。

第三步从环境变量中读取mac地址:

eth_env_get_enetaddr_by_index(“eth”, dev_seq(dev), env_enetaddr),如果从环境变量中读取到的mac地址不是0,那么这个就是最终的mac地址了,不需要进行第四步。如果从驱动读取的mac地址不为0,比较从环境变量中读取到的mac地址和从其他两个来源读取的mac地址,如果不同,打印一串警告,但是最终还是采用从环境变量中的mac地址。
如果从环境变量中读取到的mac地址为0,检查从其他两个来源读取的mac地址是否有效(非0且非组播),如果有效,采用从其他两个来源中读取的mac地址,并设置到环境变量中;如果无效,进行第四步。

第四步随机生成mac地址

随机生成mac地址需要打开编译配置项CONFIG_NET_RANDOM_ETHADDR,如果没有打开,则不会随机生成mac地址。
net_random_ethaddr(pdata->enetaddr)
使用随机数生成一个mac地址。

结论

1.mac地址的优先级:环境变量中的mac地址 > 设备树中的mac地址 > fec网卡驱动中的mac地址 > 随机生成的mac地址
环境变量中的mac地址优先级最高,优先采用这个mac地址;如果没有,采用设备树中的mac地址;如果还没由或者无效,采用fec驱动中的mac地址;如果还是没有或者无效,随机生成一个mac地址(如果没配CONFIG_NET_RANDOM_ETHADDR,那么就没有mac地址了)。
2.组播地址(第8bit为1)只有设置在环境变量才生效,设置在驱动和设备树都不生效
注:
全为0视为没有。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值