1028在uboot中自动获取mac的方式
一、查看uboot中随机获取mac的位置
源码位置:ls1028/OK1028-linux-fs/packages/firmware/u-boot/net/eth-uclass.c
#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, pdata->enetaddr);
char tmp[50] = {'\n'};
if (dev->seq == 0){
sprintf(tmp, "setenv ethaddr %pM\n", pdata->enetaddr);
}
else{
sprintf(tmp, "setenv eth%daddr %pM\n", dev->seq, pdata->enetaddr);
}
run_command(tmp, 0);
run_command("saveenv", 0);
#else
printf("\nError: %s address not set.\n",
dev->name);
return -EINVAL;
#endif
1.首先从第一个函数**net_random_ethaddr(pdata->enetaddr)**上看
文件路径:ls1028/OK1028-linux-fs/packages/firmware/u-boot/include/net.h
/**
* net_random_ethaddr - Generate software assigned random Ethernet address
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Generate a random Ethernet address (MAC) that is not multicast
* and has the local assigned bit set.
*/
static inline void net_random_ethaddr(uchar *addr)
{
int i;
unsigned int seed = get_ticks();
for (i = 0; i < 6; i++)
addr[i] = rand_r(&seed);
addr[0] &= 0xfe; /* clear multicast bit */
addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
}
get_ticks() 的功能,这个函数是获取以毫秒级为单位的时间。
rand_r() 的功能为传入一个指针类型的参数,会产生一个随机序列,需要注意的是,在传入参数不变的情况下,产生的随机序列也是不会发生改变的。
注:
1.组播的MAC地址是最高字节的低位为一,例 如 01-00-00-00-00-00 。所以要使用 addr[0] &= 0xfe 把组播位清除掉。
在实际使用中,组播数据是使用通过数据链路层进行MAC地址绑定然后进行转发,所以一个以太网卡在绑定了一个组播的IP地址以后,必须还要绑定一个组播的MAC地址,才能像单播那样工作。
还有就是在网上说的多播和组播是一个东西,只不过名字是不同的。
2.MAC地址最高字节(MSB)的低第二位(LSb)表示这个MAC地址表示全球唯一MAC地址,或者本地MAC地址,即U/L (Universal/Local)位,如果为0,表示是全局地址。这里设置的为1表示本地
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cy5aajRG-1665489352279)(https://bkimg.cdn.bcebos.com/pic/7af40ad162d9f2d36c26cc35a7ec8a136327cc31?x-bce-process=image/watermark,image_d2F0ZXIvYmFpa2U4MA==,g_7,xp_5,yp_5/format,f_auto)]
2.打印提示信息
printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
dev->name, dev->seq, pdata->enetaddr);
打印设备名字、设备号、和获取的使用net_random_ethaddr()函数获取的MAC地址。
注: 一个疑问点,为什么在命令的最后有一个M,在实际的打印信息中是没有这个M的
3.保存环境变量
在保存环境变量时,要先了解两个函数:sprintf() 和 run_command
(1)sprintf()用法:
sprintf()用法和printf()类似,但是也有不同,在printf中输出的目标是显示器,而sprintf的输出目标是指针所指的缓存区域。
(2)run_command的解释:
这个命令大概就是说要把传递进来的 tmp 变量拆分一下,分别把前半段的命令拆分出来存储在 argv[0] 位,把后面设置的环境变量的参数也是拆分出来存储在 argv[1] 中,之后由 find_cmd() 函数去查找是否存在 argv[0] 存储的命令。查找到了就去执行相对应的命令。
其中的运行过程相当于在uboot命令行中执行命令的效果是一样的。
4.加入打印信息验证
U-Boot 2019.10 (Sep 30 2022 - 16:14:20 +0800)
SoC: LS1028A Rev1.0 (0x870b0110)
Clock Configuration:
CPU0(A72):1500 MHz CPU1(A72):1500 MHz
Bus: 400 MHz DDR: 1600 MT/s
Reset Configuration Word (RCW):
00000000: 3c004010 00000030 00000000 00000000
00000010: 00000000 018f0000 0030c000 00000000
00000020: 01e031a0 00002580 00000000 00008296
00000030: 00000000 00000050 00000000 00000000
00000040: 00000000 00000000 00000000 00000000
00000050: 00000000 00000000 00000000 00000000
00000060: 00000000 00000000 100e7014 00000000
00000070: eb580000 03000000
Model: Forlinx OK1028A-C Board
Board: LS1028A Rev1.0-RDB, Version: A, boot from XSPI NOR
SERDES1 Reference : Clock1 = 100.00MHz Clock2 = 100.00MHz
DRAM: 1.9 GiB
DDR 1.9 GiB (DDR4, 32-bit, CL=11, ECC off)
Using SERDES1 Protocol: 60248 (0xeb58)
PCIe0: pcie@3400000 disabled
PCIe1: pcie@3500000 Root Complex: no link
WDT: Started with servicing (60s timeout)
MMC: FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from SPI Flash... SF: Detected w25q128 with page size 256 Bytes, erase size 64 KiB, total 16 MiB
OK
In: serial
Out: serial
Err: serial
Net: eth0: enetc-0
Warning: enetc-2 (eth2) using random MAC address - b2:d1:c6:67:38:17
/******************************************************/
Saving Environment to SPI Flash... SF: Detected w25q128 with page size 256 Bytes, erase size 64 KiB, total 16 MiB
Erasing SPI flash...Writing to SPI flash...done
OK
, eth2: enetc-2, eth4: swp0, eth5: swp1, eth6: swp2, eth7: swp3
Hit any key to stop autoboot: 0
=>
设置环境变量 setenv eth4addr
编辑环境变量 editenv eth5addr
保存环境变量 saveenv