Set MAC-Address on boot


(Frank W.) #1

Hi,

Is it possible to set MAC via cmdline?

On raspberry pi i can set it via

smsc95xx.macaddr=B8:27:EB:59:EB:25

Regards Frank


#2

No. You can set it from dts


(Frank W.) #3

If i set ot via dts,all users using my kernels having my mac if they don’t change dts and recompile. This is only problematic if 2 such devices are in same lan-segment (like in my lan).

But maybe its a start to get rid of random mac.

How can it be done?

Maybe its a good start for testing dto :slight_smile: can you give me such example?

I’m trying to set via uboot,passing as self-defined param in cmdline and parsing cmdline in linux to set via ip-command


(Frank W.) #4

found here an interesting article regarding it: http://zedboard.org/content/passing-mac-address-kernel-device-tree-blob

basicly we can set mac by dts

local-mac-address = [00 0a 35 00 00 01];
mac-address = [00 0a 35 00 00 01];

used second one:

            mac@0 {                                                                                                                              
                    compatible = "mediatek,eth-mac";                                                                                             
                    mac-address = [02 02 02 02 02 02];                                                                                           
                    phandle = <0x39>;                                                                                                            
                    reg = <0x0>;                                                                                                                 
                    phy-mode = "trgmii";  

root@bpi-r2:~# ls /sys/firmware/devicetree/base/ethernet\@1b100000/mac\@0/                                                                           
compatible  fixed-link  mac-address  name  phandle  phy-mode  reg
cat /sys/firmware/devicetree/base/ethernet\@1b100000/mac\@0/mac-adddress | hexdump
0000000 0202 0202 0202
0000006

root@bpi-r2:~# ip link show eth0              
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 02:02:02:02:02:02 brd ff:ff:ff:ff:ff:ff

works so far

now the second info from the thread…they say i can pass the mac-adress set in uboot via ethaddr (+saveenv)

U-Boot> printenv ethaddr
ethaddr=02:03:04:05:06:07

root@bpi-r2:~# cat /sys/firmware/devicetree/base/aliases/ethernet0                                            
/ethernet@1b100000/mac@0root@bpi-r2:~#

but mac is the one from dts, not from uboot

root@bpi-r2:~# ip link show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 02:02:02:02:02:02 brd ff:ff:ff:ff:ff:ff

any idea what i’m making wrong? if i leave the mac-address in dts, i got the random mac, but not the one set in uboot… do i need to set alias in dts from uboot? here (2018-11) i have only the eth for linking not the gmac-subnode…

alias {
    ethernet0 = &eth;
};

is that right? still not working…maybe because dts-ethernet-node in uboot is not the same as in kernel (in uboot link to eth,in kernel to gmac0)

@weijiegao can you help here?

can you give me an example how to set mac-addr via devicetree overlay?

have read this:

i need to overlay the node gmac0 and dt-overlay-source should look like this, right?

/dts-v1/;
/plugin/;
 
/ {
    fragment@0 {
        target = <&gmac0>;
        __overlay__ {
            mac-address = [02 01 02 03 04 05];
        };
    };
};

dtc -@ -I dts -O dtb -o bpi-r2-mac.dtb bpi-r2-mac.dts

to load in uboot (untested):

fatload ${device} ${partition} ${fdt_addr_r} ${bpi}/${board}/${service}/dtb/${fdtfile}; // full dtb maybe not used if appended DTB (r2), how to deal with the following commands (does dto work with appended DTB)?
// https://www.denx.de/wiki/DULG/UBootCmdFDT
fdt addr ${fdt_addr_r}
fdt resize // why this without parameter (bytes to add or target-size)

setexpr fdtovaddr ${fdt_addr_r} + F000 //why F000, why not using ${filesize}??
fatload ${device} ${partition} ${fdtovaddr} ${bpi}/${board}/${service}/dtb/bpi-r2-mac.dtb && fdt apply ${fdtovaddr}

as far as i understand, fdtovaddr is temporary address to load a fdto before apply it to the base-fdt it is set 60kb after base (base-fdt+ previous loaded fdto should not exceed 60kb)

how are the ranges to define ${fdt_addr_r}? can i use scriptaddr (0x83000000) here? i only use it for loading environment…kernel will be loaded in ${loadaddr} (also for tftp)

maybe i can use

for <name> in <word list> ; do <list> ; done

to load multiple dto’s

currently hang on separating kernelimage and fdt


(Frank W.) #5

after getting kernel with separate dtb running, i continue with DTO…

compiling above dts gives me this warning:

bpi-r2-mac.dtb: Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property

is this needed or how to fix this?

i tried to load it, but in uboot there seem no fdt apply

fdt - flattened device tree utility commands

Usage:
fdt addr [-c]  <addr> [<length>]   - Set the [control] fdt location to <addr>
fdt move   <fdt> <newaddr> <length> - Copy the fdt to <addr> and make it active
fdt resize [<extrasize>]            - Resize fdt to size + padding to 4k addr + some optional <extrasize> if needed
fdt print  <path> [<prop>]          - Recursive print starting at <path>
fdt list   <path> [<prop>]          - Print one level starting at <path>
fdt get value <var> <path> <prop>   - Get <property> and store in <var>
fdt get name <var> <path> <index>   - Get name of node <index> and store in <var>
fdt get addr <var> <path> <prop>    - Get start address of <property> and store in <var>
fdt get size <var> <path> [<prop>]  - Get size of [<property>] or num nodes and store in <var>
fdt set    <path> <prop> [<val>]    - Set <property> [to <val>]                                                                                      
fdt mknode <path> <node>            - Create a new node after <path>                                                                                 
fdt rm     <path> [<prop>]          - Delete the node or <property>                                                                                  
fdt header                          - Display header info                                                                                            
fdt bootcpu <id>                    - Set boot cpuid                                                                                                 
fdt memory <addr> <size>            - Add/Update memory node                                                                                         
fdt rsvmem print                    - Show current mem reserves                                                                                      
fdt rsvmem add <addr> <size>        - Add a mem reserve                                                                                              
fdt rsvmem delete <index>           - Delete a mem reserves                                                                                          
fdt chosen [<start> <end>]          - Add/update the /chosen branch in the tree                                                                      
                                        <start>/<end> - initrd start/end addr

dto gets loaded, but after it i get “usage”…seems apply does trigger it

loaddto=echo "loaddto:${dto}";fdt addr ${dtaddr};fdt resize; setexpr fdtovaddr ${dtaddr} + F000; fatload ${device} ${partition} ${fdtovaddr} ${bpi}/${board}/${service}/dtb/${dto} && fdt apply ${fdtovaddr}

documentation of uboot uses also apply (doc/README.fdt-overlays)

  1. You are now ready to apply the overlay. => fdt apply $fdtovaddr

seems i need “OF_LIBFDT_OVERLAY”-option in uboot…

after that i got this:

fdt=4.19.13-main.dtb
27836 bytes read in 10 ms (2.7 MiB/s)
dto=bpi-r2-mac.dtb
loaddto:bpi-r2-mac.dtb
229 bytes read in 7 ms (31.3 KiB/s)
failed on fdt_overlay_apply(): FDT_ERR_NOTFOUND
base fdt does did not have a /__symbols__ node
make sure you've compiled with -@
## Booting kernel from Legacy Image at 82000000 ...
   Image Name:   Linux Kernel 4.19.13-main
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    7311880 Bytes = 7 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
ERROR: Did not find a cmdline Flattened Device Tree
Could not find a valid device tree

i checked it via

[11:36:58]$ fdtdump bpi-r2-4.19.13-main_nodt.dtb | grep -C3 __symbols__

**** fdtdump is a low-level debugging tool, not meant for general use.
**** If you want to decompile a dtb, you probably want
****     dtc -I dtb -O dts <filename>

so it seems i need to compile base dtb by myself…

[11:37:14]$ dtc -@ -I dts -O dtb -o bpi-r2-base.dtb arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
Error: arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts:8.1-9 syntax error
FATAL ERROR: Unable to parse input tree

line 8 is first include…so it seems i need to pass include-dir

i tried this, because include-folder in root contains the dt-bindings subfolder (including the input/input.h), but same result

dtc -i ./include -@ -I dts -O dtb -o bpi-r2-base.dtb arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts

also tried to build dtb with “make dtbs”…same

kernel seems to use make to build dtb’s

arch/arm/Makefile:

%.dtb: | scripts
        $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@

but how to add “-@” to generate symbols? and modifying Makefile is maybe not the best way…only for testing

tried also moving from phandle to path like mentioned here: https://www.kernel.org/doc/Documentation/devicetree/overlay-notes.txt

added

export DTC_FLAGS=-@

to my build.sh and now i see the symbols

[09:59:40]$ fdtdump bpi-r2.dtb | grep -C3 __symbols__

**** fdtdump is a low-level debugging tool, not meant for general use.
**** If you want to decompile a dtb, you probably want
****     dtc -I dtb -O dts <filename>

        device_type = "memory";
        reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
    };
    __symbols__ {
        cpu_opp_table = "/opp-table";
        cpu0 = "/cpus/cpu@0";
        cpu1 = "/cpus/cpu@1";

uboot boots it…and i see mac set via dto :slight_smile:

 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP g0
    link/ether 02:01:02:03:04:05 brd ff:ff:ff:ff:ff:ff                          
3: wan@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 0
    link/ether 02:01:02:03:04:05 brd ff:ff:ff:ff:ff:ff

(Frank W.) #6

i tested uboot’s ethaddr-way now and it seems that it needs separate fdt, also overwrites address set by dto…

BPI-R2> printenv ethaddr
ethaddr=02:04:04:04:04:04
BPI-R2> printenv eth1addr
eth1addr=02:05:05:05:05:05

root@bpi-r2:~# ip a
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP g0
    link/ether 02:04:04:04:04:04 brd ff:ff:ff:ff:ff:ff
3: wan@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 0
    link/ether 02:04:04:04:04:04 brd ff:ff:ff:ff:ff:ff

but maybe it needs the mac-address-property and alias

aliases {
    serial2 = &uart2;
    ethernet0 = &gmac0;
};
...
gmac0: mac@0 {
    ...
    mac-address = [02 02 02 02 02 02];

i have only set mac-address in dto+alias (4.19-main) and it works there. if dto is not loaded maybe mac-address is needed in bpi-r2’s base dts

have added it now also for 4.14 (both cpu-ports):

root@bpi-r2:~# ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP g0
    link/ether 02:04:04:04:04:04 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP g0
    link/ether 02:05:05:05:05:05 brd ff:ff:ff:ff:ff:ff

(Thomas) #7

I am using systemd to change mac addresses: /etc/systemd/network/10-wan.link

[Match]
OriginalName=wan

[Link]
MACAddress=XX:XX:XX:XX:XX:XX