There is a 32Kbit (4KB) EEPROM that is used by software such as u-boot to identify the board.
If you have developed your own board, then the contents of the EEPROM will initially be blank, which can make life ‘interesting’, as there is no information for any of the software to configure itself.
Table of EEPROM Fields
|Header||0||4||The BeagleBone Magic Number 0xAA 0x55 0x33 0xEE|
|Board Name||4||8||The name of the board in ASCII - e.g. A335BNLT for the BeagleBone Black|
|Version||12||4||The board revision in ASCII|
|Serial Number||16||12||A 12 character string which comprises of:
|Configuration Options||28||32||The configuration of the board - normally all 0xFF|
|Reserved 1||60||6||All 0xFF|
|Reserved 2||66||6||All 0xFF|
|Reserved 3||72||6||All 0xFF|
|User Data||78||4018||Available for user data. Initially, it will be all 0xFF|
Reading the EEPROM
The EEPROM is connected via the i2c on I2C0 with a device address of 0x50
The contents of the EEPROM are available from Userspace using the file /sys/bus/i2c/devices/0-0050/eeprom
As the contents of the EEPROM are raw bytes, you may find it useful to use a utiliy such as hexdump to display the data.
A simple format for using hexdump is:
hexdump -e "FORMAT STRING" FILENAME -s START_BYTE -n NUMBER_OF_BYTES_TO_READ
You can find the byte range to read from the table above, so to read the Board Name use:
hexdump -e '8/1 "%c"' /sys/bus/i2c/devices/0-0050/eeprom -s 4 -n 8
Given that the EEPROM is just a file, you can use any utility you wish that can read raw files. As an example, I have written a small Python3 utility to read the EEPROM that is available on GitHub
Understanding the EEPROM fields
Most of the fields are relevent to u-boot during the boot process, as this allows a single u-boot binary to be able to boot multiple boards – which can be quite useful if you have many different board designs.
Header or Magic Number
The header bytes are read by u-boot to identify that the board is a BeagleBone.
Board Name and Version
U-boot will use the board name and Version for further configuration. The characters A335 means that the board is using an ARM 335x chip. The next 4 characters help identify the name of board.
Options for the name include:
- BNLT – BeagleBone
- BLNK – A black board, in which case u-boot will look for a file /boot/.eeprom.txt which it will then use to program the EEPROM.
- PBGL – The PocketBeagle
If you are using a standard BeagleBone, then the serial will already be programmed in. However, if you have designed your own, then you will need to design your own serial numbering scheme. It can be useful to have access to the serial number, as that can then identify the exact board for things like debugging and checking failure rates.
The 4018 bytes of user data can be used to store any information you want. I have found it useful when using bespoke boards to hold system specific information that then allows a single system image to be used for multiple board types.
Writing to the EEPROM
Given that u-boot uses the fields in the EEPROM for configuration, if you have a blank EEPROM, you will probablly need to populate at least the magic number and board name – possibly the version as well.
The simplest way to program the EEPROM is from u-boot during boot time. There are two ways you can do this:
- Using a boot script
Programming the EEPROM interactively
If you can access the u-boot console during boot, then you can interactively program the EEPROM. Accessing the console is only possible if you have a bootdelay option set in your uEnv.txt file such as:
If you have a serial connection open, you should see something like:
U-Boot SPL 2019.04-00002-gbb4af0f50f (Jul 08 2019 - 11:44:39 -0500) Trying to boot from MMC1 Loading Environment from EXT4... ** File not found /boot/uboot.env ** ** Unable to read "/boot/uboot.env" from mmc0:1 ** U-Boot 2019.04-00002-gbb4af0f50f (Jul 08 2019 - 11:44:39 -0500), Build: jenkins-github_Bootloader-Builder-128 CPU : AM335X-GP rev 2.0 I2C: ready DRAM: 512 MiB No match for driver 'omap_hsmmc' No match for driver 'omap_hsmmc' Some drivers were not found Reset Source: Global warm SW reset has occurred. Reset Source: Power-on reset has occurred. RTC 32KCLK Source: External. MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1 Loading Environment from EXT4... ** File not found /boot/uboot.env ** ** Unable to read "/boot/uboot.env" from mmc0:1 ** Board: BeagleBone Black <ethaddr> not set. Validating first E-fuse MAC BeagleBone Black: BeagleBone: cape eeprom: i2c_probe: 0x54: BeagleBone: cape eeprom: i2c_probe: 0x55: BeagleBone: cape eeprom: i2c_probe: 0x56: BeagleBone: cape eeprom: i2c_probe: 0x57: Net: eth0: MII MODE cpsw, usb_ether Press SPACE to abort autoboot in 2 seconds =>
Knowing that the EEPROM is on I2C0, you can set the i2c device and use the u-boot i2c commands to read and write the EEPROM. The format of the write command is:
i2c mw DEVICE_ADDRESS BYTE_NUMBER.2 HEX_VALUE
An example would be:
// Set i2c device i2c dev 0 // Set the header “magic number”: 0xAA5533EE i2c mw 0x50 0x00.2 aa i2c mw 0x50 0x01.2 55 i2c mw 0x50 0x02.2 33 i2c mw 0x50 0x03.2 ee // Set the Board name (bytes 0 – 4): “A335” i2c mw 0x50 0x04.2 41 i2c mw 0x50 0x05.2 33 i2c mw 0x50 0x06.2 33 i2c mw 0x50 0x07.2 35 // Set the Board name (bytes 4 – 7): “BNLT” i2c mw 0x50 0x08.2 42 i2c mw 0x50 0x09.2 4e i2c mw 0x50 0x0a.2 4c i2c mw 0x50 0x0b.2 54 // Set the Board version - only required for BeagleBone devices. i2c mw 0x50 0x0c.2 30 i2c mw 0x50 0x0d.2 41 i2c mw 0x50 0x0e.2 35 i2c mw 0x50 0x0f.2 43
You can then read the values back using the u-boot i2c read commands
=> i2c dev 0 Setting bus to 0 => i2c md 0x50 0x00.2 20 0000: aa 55 33 ee 41 33 33 35 42 4e 4c 54 30 41 35 43 .U3.A335BNLT0A5C 0010: 32 38 31 33 42 42 42 4b 33 32 37 36 ff ff ff ff 2813BBBK3276.... =>
Using a script to program the EEPROM
As part of the boot process, u-boot will look for a file called /boot/boot.scr and if it finds it, will run it.
Unfortunately, this is not a simple text file, but is a compiled file using the mkimage tool from u-boot. This tool is created as part of the u-boot build process. (There is an article on compiling u-boot here)
In order to create the /boot/boot.scr, first create a text file that contains the u-boot commands you want to run, such as the commands to program the EEPROM above.
You then compile the source into the /boot/boot.scr using the command:
mkimage -T script -C none -n 'Program EEPROM' -d SOURCE_FILE boot.scr
Copy the boot.scr to /boot/boot.scr and reboot. This should then set the values in your EEPROM.