Update MAC address T20 using dd

Hello forum,

I have run into an issue with the MAC address. When we flash our own image (linux) on the Colibri, the configblock becomes corrupted. As a result, we create a new configblock using createconfigblock.sh and then load it using update.sh -c.

Unfortunately, some Colibri’s were shipped offshore without this fix and thus have a MAC address that is regenerated every boot, causing problems. We only have SSH and TCP available (port 22 and 80).

A similar issue exists for the T30 variant that we use, but for those we have have a solution: manually write the MAC address using dd.

The following bash commands set the configblock, which is sent with scp, using dd:

echo 0 > /sys/block/mmcblk0boot1/force_ro
dd of=/dev/mmcblk0boot1 seek=262144 if=/home/root/configblock.bin count=1 bs=32
echo 1 > /sys/block/mmcblk0boot1/force_ro

After applying and rebooting, the configblock is fine again and the MAC address becomes persistent.
If I understand this correctly, the dd command writes the configblock on the boot partition at the exact right offset (256kb, right after the Bootloader).

However, I have been unable to create a procedure that does a similar thing for the T20. It does not have the same boot partition. I have tried to modify the command, but does not seem to work:

echo 0 > /sys/block/mmcblk0/force_ro
dd of=/dev/mmcblk0 seek=262144 if=/home/root/configblock_256.bin count=1 bs=32
echo 1 > /sys/block/mmcblk0boot1/force_ro

My question is, where is the configblock_256.bin located on a Colibri T20 256MB V1.2A? I assume the offset (256kb) is not correct. Would this method work for T20? If not, are there other alternatives I could try? My only concern is making the MAC address unique and persistent.

Any help is greatly appreciated!

Kind regards,

Martin J.

Colibri T20 has a raw NAND flash and uses UBI/UBIFS on top of /dev/mtd3 for kernel/dtb/rootfs
Config block lockated at /dev/mtd2. You can run commands

#ubinfo -a
#mtdinfo -a

for more details

It’s highly recommended erase all flash, create a config block and then flash a Linux as described here. However if a MAC address is only problem you can set U_boot ethaddr variables from U_boot console

Colibri T20 # setenv ethaddr  00:01:02:03:04:05 
Colibri T20 # saveenv

Or by using fw_setenv tool from Linux console.

Hey Alex,

Thanks for the pointers. Unfortunately, both methods described above cause me to run into a follow-up error. Perhaps you can help me one more step.

I found the config block at mtd2 (also the MAC address at mtd7), however, writing it causes the node to no longer boot. I cannot verify what the exact issue is because the test node is in a remote location. I have tried the following:

flash_eraseall /dev/mtd2
nandwrite -p /dev/mtd2 /home/root/configblock_256.bin

After a nanddump, I can see the write was successful. However, after rebooting, the node no longer comes online.

Next I tried to fix it with fw_setenv. I added u-boot-fw-utils to the bsp and I have the tools available on my device. I can run fw_printenv to check the environment. However, fw_setenv ethaddr 01:02:03:04:05:06 returns an error to me:

Warning: Bad CRC, using default environment
MTD erase error on /dev/mtd2: Invalid argument
Error: can't write fw_env to flash

The /etc/fw_env.config contains the following (minus comments):

# NOR example
# MTD device name	Device offset	Env. size	Flash sector size	Number of sectors
/dev/mtd1		0x0000		0x4000		0x4000
/dev/mtd2		0x0000		0x4000		0x4000

The fw_printenv returns the following (no ethaddr exists yet):

Warning: Bad CRC, using default environment
bootcmd=run distro_bootcmd
mmc_boot=if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; fi
boot_net_pci_enum=pci enum
boot_net_usb_start=usb start
usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; fi
ubifs_boot=if ubi part UBI && ubifsmount ubi${devnum}:boot; then setenv devtype ubi; setenv bootpart 0; run scan_dev_for_boot; fi
boot_prefixes=/ /boot/
boot_scripts=boot.scr.uimg boot.scr
boot_targets=mmc1 mmc0 usb0 pxe dhcp 
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done
bootcmd_mmc1=setenv devnum 1; run mmc_boot
bootcmd_mmc0=setenv devnum 0; run mmc_boot
bootcmd_usb0=setenv devnum 0; run usb_boot
bootcmd_pxe=run boot_net_usb_start; run boot_net_pci_enum; dhcp; if pxe get; then pxe boot; fi
bootcmd_dhcp=run boot_net_usb_start; run boot_net_pci_enum; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done

And for good measure, here is cat /proc/mtd:

dev:    size   erasesize  name
mtd0: 0e000000 00040000 "MFS"
mtd1: 00300000 00040000 "BCT"
mtd2: 00040000 00040000 "PT"
mtd3: 00200000 00040000 "EBT"
mtd4: 00040000 00040000 "BMP"
mtd5: 00200000 00040000 "ENV"
mtd6: 00800000 00040000 "LNX"
mtd7: 00040000 00040000 "ARG"
mtd8: 08000000 00040000 "USR"
mtd9: 00040000 00040000 "MSE"
mtd10: 00040000 00040000 "MIP"
mtd11: 00040000 00040000 "MCS"
mtd12: 00040000 00040000 "MDF"
mtd13: 00040000 00040000 "MDU"
mtd14: 01000000 00040000 "MLX"
mtd15: 02000000 00040000 "MAP"
mtd16: 04000000 00040000 "MWW"

Do you have any idea why either methods won’t work? Unfortunately, I do not have a means to get a u-boot interface going, so I’m hoping one of either methods has a fix.
At this point, hardcoding the MAC address into the image might be a viable solution!

Kind regards,

Martin J.

We are using UBI on top of MTD to manage bad blocks and wear leveling. Please use Linux ubiupdatevol command or U-Boot commands

#ubi part ubi    
#ubi write <RAM address> <UBI partition name> <filesize>

Hey Alex,

I have added mtd-utils 2.1.2 to my build and have the mtd tools available. However, when I attempt to run ubiupdatevol I get an error in return. Do you have any pointers what I am missing or how to solve this?

./ubiupdatevol.mtd-utils /dev/mtd2 /media/card/uploads/configblock_256.bin 
libubi: error!: "/dev/mtd2" has major:minor 90:4, but this does not correspond to any existing UBI device or volume
ubiupdatevol: error!: "/dev/mtd2" is not an UBI volume node

This is what I have for mtd2

mtdinfo /dev/mtd2
Name:                           PT
Type:                           nand
Eraseblock size:                262144 bytes, 256.0 KiB
Amount of eraseblocks:          1 (262144 bytes, 256.0 KiB)
Minimum input/output unit size: 4096 bytes
Sub-page size:                  4096 bytes
OOB size:                       128 bytes
Character device major/minor:   90:4
Bad blocks are allowed:         true
Device is writable:             true

What exact software versions of things are you talking about? Please note that there were several variants of things throughout the lifetime of the Colibri T20.