autopart part partition playwave \
recwave repartition screendump
.endif
+
+.if ${MACHINE_ARCH} == "earm"
+SUBDIR+= eepromread
+.endif
+
.include <bsd.subdir.mk>
--- /dev/null
+PROG= eepromread
+SRCS= eepromread.c eepromread.h board_info.c
+MAN= eepromread.1
+
+.include <bsd.prog.mk>
--- /dev/null
+#include <minix/i2c.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "eepromread.h"
+
+/*
+ * Attempt to read the board info from an eeprom on this board.
+ * Currently only supports the BeagleBone and BeagleBone Black.
+ * In the future, this could be expanded to support cape EEPROMs.
+ */
+
+static int board_info_beaglebone(int fd, i2c_addr_t address);
+
+/* Memory Layout of the BeagleBone and BeagleBone Black EEPROM */
+typedef struct beaglebone_info
+{
+ uint8_t magic_number[4]; /* Should be 0xaa 0x55 0x33 0xee */
+ char board_name[8]; /* Warning: strings not NULL terminated */
+ char version[4];
+ char serial_number[12];
+ char config[32]; /* All 0x00 on BeagleBone White */
+ char mac_addrs[3][6]; /* Not set on BeagleBone White */
+} beaglebone_info_t;
+
+static int
+board_info_beaglebone(int fd, i2c_addr_t address)
+{
+ int r;
+ int i, j;
+ char s[33];
+ beaglebone_info_t boneinfo;
+
+ r = eeprom_read(fd, address, 0x0000, &boneinfo,
+ sizeof(beaglebone_info_t));
+ if (r == -1) {
+ fprintf(stderr, "Failed to read BeagleBone info r=%d\n", r);
+ return -1;
+ }
+
+ fprintf(stdout, "%-16s: 0x%x%x%x%x\n", "MAGIC_NUMBER",
+ boneinfo.magic_number[0], boneinfo.magic_number[1],
+ boneinfo.magic_number[2], boneinfo.magic_number[3]);
+
+ memset(s, '\0', 33);
+ memcpy(s, boneinfo.board_name, 8);
+ fprintf(stdout, "%-16s: %s\n", "BOARD_NAME", s);
+
+ memset(s, '\0', 33);
+ memcpy(s, boneinfo.version, 4);
+ fprintf(stdout, "%-16s: %s\n", "VERSION", s);
+
+ memcpy(s, boneinfo.serial_number, 12);
+ fprintf(stdout, "%-16s: %s\n", "SERIAL_NUMBER", s);
+
+ return 0;
+}
+
+int
+board_info(int fd, i2c_addr_t address)
+{
+ int r;
+ uint8_t magic_number[4];
+
+ r = eeprom_read(fd, address, 0x0000, &magic_number, 4);
+ if (r == -1) {
+ printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
+ return 0;
+ }
+
+ if (magic_number[0] == 0xaa && magic_number[1] == 0x55 &&
+ magic_number[2] == 0x33 && magic_number[3] == 0xee) {
+ board_info_beaglebone(fd, address);
+ } else {
+ printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
+ }
+
+ return 0;
+}
--- /dev/null
+.TH EEPROMREAD 1
+.SH NAME
+eepromread \- read data from an EEPROM
+.SH SYNOPSIS
+\fBeepromread\fR [\fB\-i\fR] [\fB\-f\fR \fIdev\fR] [\fB\-a\fR \fIslave_addr\fR]
+.br
+.de FL
+.TP
+\\fB\\$1\\fR
+\\$2
+..
+.de EX
+.TP 20
+\\fB\\$1\\fR
+# \\$2
+..
+.SH OPTIONS
+.TP 5
+.B \-i
+# interpret the data on the EEPROM and display it as a set of fields.
+.TP 5
+.B \-f
+# Use \fIdevice\fR instead of \fI/dev/i2c-1\fR.
+.TP 5
+.B \-a
+# Use \fIslave_address\fR instead of \fI0x50\fR.
+.SH EXAMPLES
+.TP 20
+.B eepromread -i
+# display the contents of the EEPROM as a list of label:value pairs.
+.TP 20
+.B eepromread
+# display the first 256 bytes of the EEPROM in HEX and ASCII.
+.TP 20
+.B eepromread -f /dev/i2c-3 -a 0x54
+# display the first 256 bytes of the EEPROM on I2C bus 3, slave address 0x54.
+.SH DESCRIPTION
+.PP
+\fIeepromread\fR is a simple tool for viewing the contents of an EEPROM.
+For EEPROM data that is in a specific format that this program knows how to
+detect, \fIeepromread\fR can properly format each of the fields and display
+the information via the \fI-i\fR command line option.
+.SH NOTES
+If the \fIcat24c256\fR driver has claimed the EEPROM device that this
+program is attempting to read from, then this program will fail. Once
+a driver claims an I2C device, the driver has exclusive access.
--- /dev/null
+#include <minix/i2c.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "eepromread.h"
+
+static int __eeprom_read32(int fd, i2c_addr_t addr, uint16_t memaddr,
+ void *buf, size_t buflen);
+static int eeprom_dump(int fd, i2c_addr_t addr);
+
+#define DEFAULT_I2C_DEVICE "/dev/i2c-1"
+#define DEFAULT_I2C_ADDRESS 0x50
+
+/*
+ * The /dev interface only supports 32 byte reads/writes and the EEPROM is
+ * larger, so to read the whole EEPROM, the task is broken down into 32 byte
+ * chunks in eeprom_read(). __eeprom_read32() does the actual ioctl() to do
+ * the read.
+ *
+ * A future enhancement might be to add support for the /dev/eeprom interface
+ * and if one way fails, fall back to the other. /dev/eeprom can fail if the
+ * eeprom driver isn't running and /dev/i2c can fail if the eeprom driver
+ * claimed the eeprom device.
+ */
+
+static int
+__eeprom_read32(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
+ size_t buflen)
+{
+ int r;
+ minix_i2c_ioctl_exec_t ioctl_exec;
+
+ if (buflen > I2C_EXEC_MAX_BUFLEN || buf == NULL
+ || ((memaddr + buflen) < memaddr)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
+
+ ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
+ ioctl_exec.iie_addr = addr;
+
+ /* set the address to read from */
+ ioctl_exec.iie_cmd[0] = ((memaddr >> 8) & 0xff);
+ ioctl_exec.iie_cmd[1] = (memaddr & 0xff);
+ ioctl_exec.iie_cmdlen = 2;
+
+ ioctl_exec.iie_buflen = buflen;
+
+ r = ioctl(fd, MINIX_I2C_IOCTL_EXEC, &ioctl_exec);
+ if (r == -1) {
+ return -1;
+ }
+
+ /* call was good, copy results to caller's buffer */
+ memcpy(buf, ioctl_exec.iie_buf, buflen);
+
+ return 0;
+}
+
+int
+eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
+ size_t buflen)
+{
+ int r;
+ uint16_t i;
+
+ if (buf == NULL || ((memaddr + buflen) < memaddr)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (i = 0; i < buflen; i += 32) {
+
+ r = __eeprom_read32(fd, addr, memaddr + i, buf + i,
+ ((buflen - i) < 32) ? (buflen - i) : 32);
+ if (r == -1) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Read 256 bytes and print it to the screen in HEX and ASCII.
+ */
+static int
+eeprom_dump(int fd, i2c_addr_t addr)
+{
+ int i, j, r;
+ uint8_t buf[256];
+
+ memset(buf, '\0', 256);
+
+ r = eeprom_read(fd, addr, 0x0000, buf, 256);
+ if (r == -1) {
+ return r;
+ }
+
+ /* print table header */
+ for (i = 0; i < 2; i++) {
+ printf(" ");
+ for (j = 0x0; j <= 0xf; j++) {
+ if (i == 0) {
+ printf(" ");
+ }
+ printf("%x", j);
+ }
+ }
+ printf("\n");
+
+ /* print table data */
+ for (i = 0x00; i < 0xff; i += 0x10) {
+
+ /* row label */
+ printf("%02x:", i);
+
+ /* row data (in hex) */
+ for (j = 0x0; j <= 0xf; j++) {
+ printf(" %02x", buf[i + j]);
+ }
+
+ printf(" ");
+
+ /* row data (in ASCII) */
+ for (j = 0x0; j <= 0xf; j++) {
+ if (isprint(buf[i + j])) {
+ printf("%c", buf[i + j]);
+ } else {
+ printf(".");
+ }
+ }
+
+ printf("\n");
+ }
+
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int r, fd;
+ int ch, iflag = 0;
+ char *device = DEFAULT_I2C_DEVICE;
+ i2c_addr_t address = DEFAULT_I2C_ADDRESS;
+
+ setprogname(*argv);
+
+ while ((ch = getopt(argc, argv, "a:f:i")) != -1) {
+ switch (ch) {
+ case 'a':
+ address = strtol(optarg, NULL, 0x10);
+ break;
+ case 'f':
+ device = optarg;
+ break;
+ case 'i':
+ iflag = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ fd = open(device, O_RDWR);
+ if (fd == -1) {
+ fprintf(stderr, "open(): %s\n", strerror(errno));
+ return 1;
+ }
+
+ if (iflag == 1) {
+ r = board_info(fd, address);
+ if (r == -1) {
+ fprintf(stderr, "board_info(): %s\n", strerror(errno));
+ return 1;
+ }
+ } else {
+ r = eeprom_dump(fd, address);
+ if (r == -1) {
+ fprintf(stderr, "eeprom_dump(): %s\n", strerror(errno));
+ return 1;
+ }
+ }
+
+ r = close(fd);
+ if (r == -1) {
+ fprintf(stderr, "close(): %s\n", strerror(errno));
+ return 1;
+ }
+
+ return 0;
+}
+
--- /dev/null
+#ifndef __EEPROMREAD_H
+#define __EEPROMREAD_H
+
+int eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
+ size_t buflen);
+int board_info(int fd, i2c_addr_t address);
+
+#endif /* __EEPROMREAD_H */
./multiboot/mod10_vm minix-sys
./multiboot/mod11_pfs minix-sys
./multiboot/mod12_init minix-sys
+./usr/bin/eepromread minix-sys
./usr/include/arm minix-sys
./usr/include/arm/aeabi.h minix-sys
./usr/include/arm/ansi.h minix-sys
./usr/lib/libi2cdriver_pic.a minix-sys
./usr/lib/libpadconf.a minix-sys
./usr/lib/libpadconf_pic.a minix-sys
+./usr/man/man1/eepromread.1 minix-sys
./usr/mdec minix-sys
./usr/sbin/cat24c256 minix-sys
./usr/sbin/fb minix-sys
-args instance=${bus}
done
echo .
+
+ BOARD_NAME=`eepromread -i | sed -n 's/^BOARD_NAME : \(.*\)$/\1/p'`
+ case "${BOARD_NAME}" in
+ A335BONE)
+ echo "Detected BeagleBone"
+ echo -n "Starting i2c device drivers: "
+ test -e /dev/eepromb1s50 || (cd /dev && MAKEDEV eepromb1s50)
+ up cat24c256 -dev /dev/eepromb1s50 \
+ -label cat24c256.1.50 -args 'bus=1 address=0x50'
+ ;;
+ A335BNLT)
+ echo "Detected BeagleBone Black"
+ echo -n "Starting i2c device drivers: "
+ test -e /dev/eepromb1s50 || (cd /dev && MAKEDEV eepromb1s50)
+ up cat24c256 -dev /dev/eepromb1s50 \
+ -label cat24c256.1.50 -args 'bus=1 address=0x50'
+ ;;
+ UNKNOWN)
+ echo "Unable to detect board -- assuming BeagleBoard-xM"
+ echo -n "Starting i2c device drivers: "
+ ;;
+ esac
+
+ echo .
fi
if [ "$net" ]