Production Data
SOM EEPROM
Each Cargt i.MX SOM has a small I²C EEPROM at address 0x50 that Cargt programs during production. It holds the part number, serial number, build date and the DRAM configuration. The boot loader uses the DRAM fields to select the DDR timing for the memory fitted to that SOM, so one boot image works for every memory option of a SOM.
Record Format
The record starts at offset 0 and is 48 bytes long. Multi-byte fields are big-endian. Cargt production programs version 2 records, with the reserved bytes set to 0.
Offset |
Size |
Field |
Contents |
|---|---|---|---|
0 |
4 |
Magic |
|
4 |
2 |
Size |
Size of the record in bytes |
6 |
1 |
Version |
Record version (1, 2 or 3) |
7 |
13 |
Part number |
Cargt part number, |
20 |
4 |
Serial number |
Cargt serial number |
24 |
9 |
Date |
Build date, |
33 |
2 |
DRAM size |
DRAM size in MB |
35 |
2 |
DRAM speed |
DRAM speed in MT/s |
37 |
1 |
DRAM ranks |
Number of DRAM ranks (version 2 and later) |
38 |
1 |
DDR configuration ID |
DDR configuration used by the i.MX 95 (version 3 and later) |
39 |
5 |
Reserved |
|
44 |
4 |
CRC32 |
CRC32 of bytes 0 to 43 |
Reading the EEPROM in U-Boot
On i.MX 8M Plus, i.MX 91 and i.MX 93 SOMs, SPL prints the record on the console at every boot, followed by the DDR timing it selected from it. From an i.MX 93 00363 (2 GB, two ranks) on the 00428 carrier:
U-Boot SPL 2026.04-lf_v2026.04+g6eeef838dac+p0 (Jun 02 2026 - 15:03:39 +0000)
...
Reading Cargt EEPROM over I2C...
Cargt EEPROM read complete.
...
Cargt EEPROM Production Information:
Part number: 012-00363-FE
Production date: 20260929
Serial number: <decimal> (0x<hex>)
EEPROM struct version: 0x2
DRAM rank: 2
DRAM size: 2048 MB
DRAM speed: 3733 MT/s
CRC32: 0x<crc> (OK)
Selected board timing: 2048MB @ 3733 MT/s (rank 2)
DDR: 3733MTS
To print it again, stop autoboot and run cargt_eeprom read at the U-Boot
prompt:
u-boot=> cargt_eeprom read
Cargt EEPROM Production Information:
Part number: 012-00363-FE
Production date: 20260929
Serial number: <decimal> (0x<hex>)
EEPROM struct version: 0x2
DRAM rank: 2
DRAM size: 2048 MB
DRAM speed: 3733 MT/s
CRC32: 0x<crc> (OK)
Version 3 records (i.MX 95) add a DDR config ID line. Older U-Boot
builds print the serial number in hexadecimal only and leave out the CRC
line.
How the DRAM Fields Are Used
i.MX 8M Plus, i.MX 91 and i.MX 93: SPL reads the DRAM size, speed and rank count, and selects the matching DDR timing built into the image.
i.MX 95: DDR training runs before SPL, in the OEI firmware on the Cortex-M33. OEI reads the DDR configuration ID, or matches older records by size and rank count. If the EEPROM is blank or invalid, OEI tries each configuration in turn, two-rank configurations first.
Warning
Do not change the DRAM fields. A DRAM size larger than the memory actually fitted lets Linux use memory that does not exist, which causes random crashes under load rather than a clean boot failure. If you think a SOM’s EEPROM is wrong, contact Cargt.
If the EEPROM is blank or its CRC is wrong, SPL assumes one rank. A version 1 record, or a version 2 record with a rank of 0, is treated as two ranks.
cargt_eeprom setrank <1|2> rewrites the DRAM rank field and the CRC, and
updates a version 1 record to version 2. It is a repair tool for SOMs
programmed with the wrong rank count; use it only when Cargt asks you to.
Ethernet MAC Addresses
U-Boot chooses each Ethernet port’s MAC address in this order:
The
ethaddr(first port) oreth1addr(second port) variable in the U-Boot environment, if set.The MAC address programmed in the SoC’s eFuses (one-time programmable memory).
If neither is set, a random address. Without an address in the eFuses or the environment, a board gets a new MAC address, and so a new DHCP lease, at every boot.
U-Boot passes the address to Linux in the device tree, so Linux uses the same address.
Setting Addresses in the U-Boot Environment
For production, use addresses from your own IEEE-assigned range. On boards without programmed eFuses, you can instead derive stable, locally administered addresses from the SoC unique ID. Run this once per board from Linux, then reboot:
uid=$(cat /sys/devices/soc0/serial_number)
h=$(printf %s "$uid" | sha256sum | cut -c1-8)
base="02:${h:0:2}:${h:2:2}:${h:4:2}:${h:6:2}"
fw_setenv ethaddr "${base}:00" # first port, eth0
fw_setenv eth1addr "${base}:01" # second port, eth1
fw_printenv ethaddr eth1addr
The 02 first byte marks the address as locally administered, so it
cannot clash with a vendor-assigned address. Cargt verified this method on
the i.MX 95 00414.
To go back to the eFuse addresses, delete the variables:
fw_setenv ethaddr
fw_setenv eth1addr
Programming MAC eFuses is permanent and the fuse locations differ for each i.MX processor. See the processor’s reference manual (Fusemap chapter) and contact Cargt for production programming.