是否有 Linux 或 U-Boot 支持在启动时从芯片读取 MAC 地址?

Is there Linux or U-Boot support to read a MAC address from a chip at startup?

我的公司构建的定制硬件数量如此之少,以至于购买一整块 MAC 个地址在经济上没有意义。如果有的话,我可以在我的嵌入式 Linux 板上设计什么芯片,用于在启动时自动分配全球唯一的 MAC 地址?

我已经搜索了 Linux 以及对 MAC 芯片和 EUI-48 芯片的 u-boot 驱动程序支持,但搜索结果为空。 MicroChip 部件号 24AA02E48 是一个 I2C 芯片,它包含适合作为 MAC 地址的 EUI-48 地址。还有 DS2502-48,这是我们之前通过编写单独的 u-boot 应用程序读取其 MAC 地址并将其分配给 U-Boot ethaddr 环境变量而使用的串行 1-wire 芯片,但是这是我想消除的手动步骤。 1-wire 时序非常紧凑,以至于 u-boot 应用程序有时无法正确读取 MAC 地址,因此我们从未完全自动化该过程。

是否有任何 Linux 或 u-boot 驱动程序可以配置为在启动时自动读取 MAC 地址芯片?

据我所知,你根本不需要芯片。 MAC 的标准允许您生成 "locally administered" MAC 地址,该地址不能保证全局唯一性。对于像您这样的小型制造商,这几乎总是足够好,这就是标准允许的原因。

只要确保在选择号码时遵循这些标准,例如将 U/L 位设置为“1”以保证它不会匹配注册地址(U/L 位 == “ 0”)。 "tl;dr" 生成有效本地 MAC 地址的方法是使前三对“02:00:00:”和后三对随机十六进制数字;但如果您正在构建硬件,我建议您花时间阅读标准或至少阅读维基百科页面。

如果伪随机数字偶然发生冲突,请尽可能为客户提供更改默认 MAC 选择的方法。就算有注册地址,让客户自己改也是好的。有时管理员会调整 MAC 以使路由 and/or 负载平衡更容易,并且有时他们需要躲避一个 MAC 由认为可以硬-代码“00:00:00:00:00:00”或选择 12 个随机十六进制数字。

至于从 Linux 驱动程序或 U-Boot 读取 MAC,我不知道你的设备,但我发现使用 U-Boot 最简单,因为它工作在低等级。 U-Boot 将它找到的 MAC 存储在环境变量 "ethaddr"、"eth1addr" 和 "eth2addr" 中。命令 "printenv" 是查看它们的一种方式。这是一个恰好在我面前的看板的例子:

U-Boot# printenv ethaddr eth1addr eth2addr
ethaddr=98:5d:ad:43:dd:38
eth1addr=98:5d:ad:43:dd:3a
## Error: "eth2addr" not defined

U-Boot 命令 "bdinfo" 也可能有用。再次来自我面前的板:

U-Boot# bdinfo
arch_number = 0x0000106E
boot_params = 0x80000100
DRAM bank   = 0x00000000
-> start    = 0x80000000
-> size     = 0x20000000
eth0name    = cpsw
ethaddr     = 98:5d:ad:43:dd:38
current eth = cpsw
ip_addr     = <NULL>
baudrate    = 115200 bps
TLB addr    = 0x9FFF0000
relocaddr   = 0x9F753000
reloc off   = 0x1EF53000
irq_sp      = 0x9F332F38
sp start    = 0x9F332F28

U-Boot 甚至包括一个可选的 "gen_eth_addr" 工具来生成有效的本地管理地址。这是一个用法示例,摘自他们的维基页面:https://www.denx.de/wiki/DULG/WhereCanIGetAValidMACAddress

$ make tools/gen_eth_addr
cc     tools/gen_eth_addr.c   -o tools/gen_eth_addr
$ tools/gen_eth_addr
ba:d0:4a:9c:4e:ce

遇到完全相同的问题,我可以成功使用此代码段。它从内存中某处的 I2c eeprom 读取 MAC 地址,并为 "ethaddr" 变量构建字符串。 显然,你需要在某个地方 "run setup_eth",我在 "preboot" 中做了。 希望对你有帮助。

#ethernet related setup
setup_eth=run readmac buildmac
#read mac address from eeprom
readmac=i2c dev 0; i2c read 50 FA.1 6 $loadaddr
#build the ethaddr variable
#not very nice, but does the job
buildmac=\
e=" "; sep=" " \
for i in 0 1 2 3 4 5 ; do\
setexpr x $loadaddr + $i\
setexpr.b b *$x\
e="$e$sep$b"\
sep=":"\
done &&\
setenv ethaddr $e