From mboxrd@z Thu Jan 1 00:00:00 1970 From: Fredrik Roubert Date: Tue, 21 Nov 2006 14:02:36 +0100 Subject: [U-Boot-Users] Reading out version_string from a binary Message-ID: <20061121130236.GC3803@igloo.df.lth.se> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi! I use U-Boot (1.1.4) on a custom PowerPC (MPC8347) based board, and from my application I need to read out the value of version_string from the U-Boot binary, for logging. I've written some code that does this (see attached sample program), but would like some comments if someone has suggestions on how to do it more robust. On MPC83XX, version_string is stored at the beginning of .rodata, so if only the offset for .rodata is found, reading out version_string is quite straightforward. The offset of .rodata changes, however, when code is added or removed from U-Boot. I've found that an offset is being written at the end of start.o, from which it is possible to calculate the offset of .rodata, and even though this works for my current needs, it's hardly what one would call a robust solutions. Does anyone have ideas about a better way to do this? Cheers // Fredrik Roubert -- Barco Medical Imaging | +32 56 233549 http://www.barco.com/medical/ | fredrik.roubert at barco.com -------------- next part -------------- #include #include #include #include #include #include #include #include #include #include static char * ubootver(const char *path) { /* This code assumes big-endian U-Boot binaries. */ enum /* Magic constants to find the .reloc segment. */ { START = 0x3748, MAGIC = 0x7ea8, }; static char buf[128]; /* Must be large enough. */ int fd, err; uint32_t tmp, offset, base; if (path == NULL) { errno = EINVAL; return NULL; } if ((fd = open(path, O_RDONLY)) == -1) return NULL; /* Get offset for .reloc segment. */ if ( lseek(fd, START, SEEK_SET) != START || read(fd, &tmp, sizeof tmp) != sizeof tmp ) goto error; offset = ntohl(tmp) - MAGIC; /* Get base for address space. */ if ( lseek(fd, offset, SEEK_SET) != offset || read(fd, &tmp, sizeof tmp) != sizeof tmp ) goto error; base = ntohl(tmp) - offset; /* Get offset for version_string. */ if (read(fd, &tmp, sizeof tmp) != sizeof tmp) goto error; offset = ntohl(tmp) - base; /* Read version_string. */ if ( lseek(fd, offset, SEEK_SET) != offset || read(fd, buf, sizeof buf) != sizeof buf ) goto error; if (close(fd) == -1) return NULL; return buf; error: err = errno; close(fd); errno = err; return NULL; } int main(int argc, char *argv[]) { char *ver; if (argc != 2) { fprintf(stderr, "Usage: %s [PATH]\n", argv[0]); return EXIT_FAILURE; } if ((ver = ubootver(argv[1])) == NULL) { perror("ubootver()"); return EXIT_FAILURE; } printf("\"%s\"\n", ver); return EXIT_SUCCESS; }