The BeagleBone Black is a handy little board. It has a 1GHz ARM processor and 4GB of on-board Flash storage, and runs Linux very easily. In particular, the Debian distribution is available ready-made to just copy on to the board from an SD card. I’ve been using them in various embedded applications recently.
One of the applications I’m working on at the moment will be deploying BeagleBone Black boards in hundreds of locations, and we have to manage them sensibly. When managing all these boards, it will make our lives much easier to know their identities. Happily, the BeagleBone Black is fitted with an EEPROM which contains various useful information about it, including its serial number and a copy of the barcode stuck to the board.
The EEPROM is accessible via the I2C bus. The bus itself is accessible via /dev/i2c-0 at address 0x50. As standard, Debian Linux is set up so that the group i2c has access to this device. However, the kernel device tree is one step ahead of us. A special at24 driver takes over access to the EEPROM, so any attempt to access it directly via /dev/i2c-0 just gets denied with ‘Device or resource busy’. The contents of the EEPROM are available, however, in sysfs under /sys/bus/i2c/0-0050/eeprom.
There is also a bone-capemgr driver which presents some of the EEPROM contents in a more convenient way, as a series of files elsewhere in sysfs, under /sys/devices/bone_capemgr.9/baseboard/
This is all very handy, but all the files in sysfs are only readable by root. That’s not helpful for my applications. I don’t want to be running things as root if I can possibly help it. I wanted to find a reasonably legitimate way to make the relevant sysfs files available to a group of users. We can’t just change the permissions on those files because sysfs is created dynamically, so any changes would be lost after a reboot.
The obvious way to do this would be via a udev rule so that the permissions are set up when the relevant devices are found. However, udev rules don’t seem to have a direct way to change the permissions and ownership of files in sysfs. After some experimentation I came up with a couple of rules which did what I wanted. They match on the narrowest set of keys I could work out, and run chmod and chown to set the permissions the way I’d like them:
DRIVER=="bone-capemgr", RUN+="/bin/chown root:i2c /sys$env{DEVPATH}/baseboard/serial-number" SUBSYSTEM=="i2c", DEVPATH=="*0-0050", RUN+="/bin/chown root:i2c /sys$env{DEVPATH}/eeprom", RUN+="/bin/chmod 0640 /sys$env{DEVPATH}/eeprom"
Put those lines in a suitable rules file. I used /etc/udev/rules.d/30-bone-capemgr.rules. Then, running
udevadm trigger
Should trigger the rules and set the permissions. Because sysfs is recreated at boot time when the various devices are found and added, the rules will trigger each time and leave the permissions the way we want them.
The board serial number is to be found in bytes 16-28 of the EEPROM, and the barcode is in bytes 80-103. The hexdump utility is handy for extracting the data. For example,
hexdump -e '8/1 "%c"' /sys/bus/i2c/devices/0-0050/eeprom -s 80 -n 23
should show the barcode. Wrap that up in a script and we have a programmatic way of finding the board’s identity.