[U-Boot] [PATCH] Add imls utility command

Marco marco.stornelli at gmail.com
Mon Mar 30 19:17:08 CEST 2009


This patch adds, under tools folder, a new command called imls. Its
goal is the same of UBoot imls but it can be used as Linux shell
command. It reads from raw mtd partition and prints the list of the
stored images. I'd like to receive comments about the usefulness of this
command.

Signed-off-by: Marco Stornelli <marco.stornelli at gmail.com>
---

diff -uprN u-boot-2009.03-orig/tools/imls.c u-boot-2009.03/tools/imls.c
--- u-boot-2009.03-orig/tools/imls.c	1970-01-01 01:00:00.000000000 +0100
+++ u-boot-2009.03/tools/imls.c	2009-03-30 19:06:56.000000000 +0200
@@ -0,0 +1,218 @@
+/*
+ * (C) Copyright 2009 Marco Stornelli
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "imls.h"
+
+extern unsigned long crc32(unsigned long crc, const char *buf, unsigned int len);
+static void usage(void);
+static int image_verify_header(char *ptr, int fd);
+
+char	*cmdname;
+char	*devicefile;
+
+unsigned int sectorcount = 0;
+int sflag = 0;
+unsigned int sectoroffset = 0;
+unsigned int sectorsize = 0;
+int cflag = 0;
+
+int main (int argc, char **argv)
+{
+	int fd = -1, err = 0, readbyte = 0, j, len;
+	uint32_t mtdsize, dim;
+	struct mtd_info_user mtdinfo;
+	char *buf;
+	int found = 0;
+
+	cmdname = *argv;
+
+	while (--argc > 0 && **++argv == '-') {
+		while (*++*argv) {
+			switch (**argv) {
+			case 's':
+				if (--argc <= 0) 
+					usage ();
+				sectorcount = (unsigned int)atoi(*++argv);
+				sflag = 1;
+				goto NXTARG;
+			case 'o':
+				if (--argc <= 0)
+					usage ();
+				sectoroffset = (unsigned int)atoi(*++argv);
+				goto NXTARG;
+
+			case 'c':
+				if (--argc <= 0)
+					usage ();
+				sectorsize = (unsigned int)atoi(*++argv);
+				cflag = 1;
+				goto NXTARG;
+			default:
+				usage ();
+			}
+		}
+NXTARG:		;
+	}
+
+	if (argc != 1 || cflag == 0 || sflag == 0)
+		usage();
+
+	devicefile = *argv;
+
+	fd = open(devicefile, O_RDONLY);
+	if (fd < 0) {
+		fprintf (stderr, "%s: Can't open %s: %s\n",
+		cmdname, devicefile, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	err = ioctl(fd, MEMGETINFO, &mtdinfo);
+	if (err < 0) {
+		fprintf(stderr, "%s: Cannot get MTD information: %s\n",cmdname,strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	mtdsize = mtdinfo.size;
+
+	if (sectorsize * sectorcount != mtdsize) {
+		fprintf(stderr, "%s: Partition size (%d) incompatible with sector size and count\n", cmdname, mtdsize);
+		exit(EXIT_FAILURE);
+	}
+
+	if (sectorsize * sectoroffset >= mtdsize) {
+		fprintf(stderr, "%s: Partition size (%d) incompatible with sector offset given\n", cmdname, mtdsize);
+		exit(EXIT_FAILURE);
+	}
+
+	if (sectoroffset > sectorcount - 1) {
+		fprintf(stderr, "%s: Sector offset cannot be grater than sector count minus one\n", cmdname);
+		exit(EXIT_FAILURE);
+	}
+
+	dim = image_get_header_size();
+
+	buf = malloc(sizeof(char)*dim);
+	if (!buf) {
+		fprintf (stderr, "%s: Can't allocate memory: %s\n",
+		cmdname, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	if (sectoroffset != 0)
+		lseek(fd, sectoroffset*sectorsize, SEEK_SET);
+
+	printf("Searching....\n");
+
+	for (j = sectoroffset; j < sectorcount; ++j) {
+
+		readbyte = read(fd, buf, dim);
+		if (readbyte != dim) {
+			fprintf(stderr, "%s: Can't read from device: %s\n",
+			cmdname, strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+
+		if (fdt_check_header(buf)) {
+			/* old-style image */
+			if (image_verify_header(buf, fd)) {
+				found = 1;
+				image_print_contents((image_header_t *)buf);
+			}
+		} else {
+			/* FIT image */
+			fit_print_contents(buf);
+		}
+
+	}	
+
+	free(buf);
+
+	close(fd);
+
+	if(!found)
+		printf("No images found\n");
+
+	exit(EXIT_SUCCESS);
+}
+
+void usage()
+{
+	fprintf (stderr, "Usage:\n"
+			 "       %s [-o offset] -s count -c size \n"
+			 "          -o ==> number of sectors to use as offset\n"
+			 "          -s ==> number of sectors\n"
+			 "          -c ==> size of sectors\n",
+		cmdname);
+
+	exit (EXIT_FAILURE);
+}
+
+static int image_verify_header(char *ptr, int fd)
+{
+	int len, n;
+	char *data;
+	uint32_t checksum;
+	image_header_t *hdr = (image_header_t *)ptr;
+
+	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
+		return 0;
+	}
+
+	data = (char *)hdr;
+	len  = sizeof(image_header_t);
+
+	checksum = ntohl(hdr->ih_hcrc);
+	hdr->ih_hcrc = htonl(0);	/* clear for re-calculation */
+
+	if (crc32(0, data, len) != checksum) {
+		fprintf (stderr,
+			"%s: Maybe image found but it has bad header checksum!\n",
+			cmdname);
+		return 0;
+	}
+
+	len = ntohl(hdr->ih_size);
+	data = malloc(len * sizeof(char));
+	if (!data) {
+		fprintf (stderr, "%s: Can't allocate memory: %s\n",
+		cmdname, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+	
+	n = read(fd, data, len);
+	if (n != len) {
+		fprintf (stderr,
+			"%s: Error while reading: %s\n",
+			cmdname, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+	
+	if (crc32(0, data, len) != ntohl(hdr->ih_dcrc)) {
+		fprintf (stderr,
+			"%s: Maybe image found but it has corrupted data!\n",
+			cmdname);
+		free(data);
+		return 0;
+	}
+	
+	free(data);
+	
+	return 1;
+}
+
diff -uprN u-boot-2009.03-orig/tools/imls.h u-boot-2009.03/tools/imls.h
--- u-boot-2009.03-orig/tools/imls.h	1970-01-01 01:00:00.000000000 +0100
+++ u-boot-2009.03/tools/imls.h	2009-03-29 11:43:31.000000000 +0200
@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2009 Marco Stornelli
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifdef MTD_OLD
+# include <stdint.h>
+# include <linux/mtd/mtd.h>
+#else
+# define  __user	/* nothing */
+# include <mtd/mtd-user.h>
+#endif
+
+#include <sha1.h>
+#include "fdt_host.h"
+#include <image.h>
diff -uprN u-boot-2009.03-orig/tools/Makefile u-boot-2009.03/tools/Makefile
--- u-boot-2009.03-orig/tools/Makefile	2009-03-21 22:04:41.000000000 +0100
+++ u-boot-2009.03/tools/Makefile	2009-03-28 18:47:38.000000000 +0100
@@ -21,10 +21,10 @@
 # MA 02111-1307 USA
 #
 
-BIN_FILES	= img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) ubsha1$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX)
+BIN_FILES	= img2srec$(SFX) mkimage$(SFX) imls$(SFX) envcrc$(SFX) ubsha1$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX)
 
 OBJ_LINKS	= env_embedded.o crc32.o md5.o sha1.o image.o
-OBJ_FILES	= img2srec.o mkimage.o envcrc.o ubsha1.o gen_eth_addr.o bmp_logo.o
+OBJ_FILES	= img2srec.o mkimage.o imls.o envcrc.o ubsha1.o gen_eth_addr.o bmp_logo.o
 
 ifeq ($(ARCH),mips)
 BIN_FILES	+= inca-swap-bytes$(SFX)
@@ -151,6 +151,10 @@ $(obj)mkimage$(SFX):	$(obj)mkimage.o $(o
 		$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
 		$(STRIP) $@
 
+$(obj)imls$(SFX):	$(obj)imls.o $(obj)crc32.o $(obj)image.o $(obj)md5.o $(obj)sha1.o $(LIBFDT_OBJ_FILES)
+		$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
+		$(STRIP) $@
+
 $(obj)ncb$(SFX):	$(obj)ncb.o
 		$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
 		$(STRIP) $@
@@ -196,6 +200,9 @@ $(obj)image.o:	$(obj)image.c
 $(obj)mkimage.o:	$(src)mkimage.c
 		$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
 
+$(obj)imls.o:	$(src)imls.c
+		$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
+
 $(obj)ncb.o:		$(src)ncb.c
 		$(CC) -g $(CFLAGS) -c -o $@ $<
 



More information about the U-Boot mailing list