mailarchive of the ptxdist mailing list
 help / color / mirror / Atom feed
* [ptxdist] [RFC] u-boot-tools: emmc support in fw_printenv/fw_setenv
@ 2014-08-04  8:29 Bruno Thomsen
  2014-08-05 11:37 ` Markus Niebel
  2014-08-05 12:29 ` Markus Niebel
  0 siblings, 2 replies; 6+ messages in thread
From: Bruno Thomsen @ 2014-08-04  8:29 UTC (permalink / raw)
  To: ptxdist; +Cc: bth, Martin Fisker

Provide read/write access to U-Boot environment stored in eMMC flash from Linux.

Access to U-Boot environment can be very useful; dual kernel/rootfs images, production default values, change kernel bootargs, etc.

Tested with U-Boot 2009.08 and 2013.04 on TQMa28.

Warning! This is not ready for ptxdist mainline inclusion.

Signed-off-by: Martin Fisker <mfi@kamstrup.dk>
Signed-off-by: Bruno Thomsen <bth@kamstrup.dk>
---
 ...oot-emmc-support-in-fw_printenv-fw_setenv.patch | 182 +++++++++++++++++++++
 patches/u-boot-2011.12/series                      |   3 +-
 2 files changed, 184 insertions(+), 1 deletion(-)
 create mode 100644 patches/u-boot-2011.12/0002-u-boot-emmc-support-in-fw_printenv-fw_setenv.patch

diff --git a/patches/u-boot-2011.12/0002-u-boot-emmc-support-in-fw_printenv-fw_setenv.patch b/patches/u-boot-2011.12/0002-u-boot-emmc-support-in-fw_printenv-fw_setenv.patch
new file mode 100644
index 0000000..95916ca
--- /dev/null
+++ b/patches/u-boot-2011.12/0002-u-boot-emmc-support-in-fw_printenv-fw_setenv.patch
@@ -0,0 +1,182 @@
+From: Bruno Thomsen <bth@kamstrup.dk>
+Date: Fri, 1 Aug 2014 10:00:16 +0200
+Subject: [RFC] u-boot: emmc support in fw_printenv/fw_setenv
+
+Provide read/write access to U-Boot environment stored in eMMC flash from Linux.
+
+Signed-off-by: Martin Fisker <mfi@kamstrup.dk>
+Signed-off-by: Bruno Thomsen <bth@kamstrup.dk>
+---
+ tools/env/fw_env.c      | 77 +++++++++++++++++++++++++++++++++----------------
+ tools/env/fw_env.config |  4 +++
+ 2 files changed, 56 insertions(+), 25 deletions(-)
+
+diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
+index 996682e..631a26f 100644
+--- a/tools/env/fw_env.c
++++ b/tools/env/fw_env.c
+@@ -45,6 +45,8 @@
+ 
+ #include "fw_env.h"
+ 
++#define CONFIG_ENV_IS_IN_MMC
++
+ #define WHITESPACE(c) ((c == '\t') || (c == ' '))
+ 
+ #define min(x, y) ({				\
+@@ -773,10 +775,10 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+ 
+ 	blocklen = DEVESIZE (dev);
+ 
+-	top_of_range = ((DEVOFFSET(dev) / blocklen) +
+-					ENVSECTORS (dev)) * blocklen;
++	top_of_range = (DEVOFFSET(dev) & ~(blocklen - 1)) +
++					ENVSECTORS (dev) * blocklen;
+ 
+-	erase_offset = (offset / blocklen) * blocklen;
++	erase_offset = offset & ~(blocklen - 1);
+ 
+ 	/* Maximum area we may use */
+ 	erase_len = top_of_range - erase_offset;
+@@ -790,8 +792,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+ 	 * to the start of the data, then count bytes of data, and to the
+ 	 * end of the block
+ 	 */
+-	write_total = ((block_seek + count + blocklen - 1) /
+-						blocklen) * blocklen;
++	write_total = (block_seek + count + blocklen - 1) & ~(blocklen - 1);
+ 
+ 	/*
+ 	 * Support data anywhere within erase sectors: read out the complete
+@@ -807,9 +808,9 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+ 			return -1;
+ 		}
+ 
+-		rc = flash_read_buf (dev, fd, data, write_total, erase_offset,
+-				     mtd_type);
+-		if (write_total != rc)
++		rc = flash_read_buf (dev, fd, data, CONFIG_ENV_SIZE,
++					DEVOFFSET(dev_current), mtd_type);
++		if (CONFIG_ENV_SIZE != rc)
+ 			return -1;
+ 
+ 		/* Overwrite the old environment */
+@@ -835,22 +836,27 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+ 	erase.length = erasesize;
+ 
+ 	/* This only runs once on NOR flash and SPI-dataflash */
++	int loopcount = 0;
+ 	while (processed < write_total) {
+-		rc = flash_bad_block (fd, mtd_type, &blockstart);
+-		if (rc < 0)		/* block test failed */
+-			return rc;
+-
+-		if (blockstart + erasesize > top_of_range) {
+-			fprintf (stderr, "End of range reached, aborting\n");
+-			return -1;
+-		}
++		loopcount++;
++		if(mtd_type != MTD_ABSENT)
++		{
++			rc = flash_bad_block (fd, mtd_type, &blockstart);
++			if (rc < 0)		/* block test failed */
++				return rc;
++
++			if (blockstart + erasesize > top_of_range) {
++				fprintf (stderr, "End of range reached, aborting\n");
++				return -1;
++			}
+ 
+-		if (rc) {		/* block is bad */
+-			blockstart += blocklen;
+-			continue;
++			if (rc) {		/* block is bad */
++				blockstart += blocklen;
++				continue;
++			}
+ 		}
+-
+ 		erase.start = blockstart;
++#ifndef CONFIG_ENV_IS_IN_MMC
+ 		ioctl (fd, MEMUNLOCK, &erase);
+ 
+ 		/* Dataflash does not need an explicit erase cycle */
+@@ -861,7 +867,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+ 					 strerror (errno));
+ 				return -1;
+ 			}
+-
++#endif
+ 		if (lseek (fd, blockstart, SEEK_SET) == -1) {
+ 			fprintf (stderr,
+ 				 "Seek error on %s: %s\n",
+@@ -870,17 +876,34 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+ 		}
+ 
+ #ifdef DEBUG
+-		printf ("Write 0x%x bytes at 0x%llx\n", erasesize, blockstart);
++		printf ("Write 0x%x bytes at 0x%llx\n", write_total, blockstart);
++		printf("erasesize %d\n", erasesize);
++		printf("count %d\n", count);
++		printf("writeTotal %d\n", write_total);
++		printf("processed %d\n", processed);
++		printf("loopcount %d\n", loopcount);
++		printf("blocklen %d\n", blocklen);
++#endif
++#ifdef CONFIG_ENV_IS_IN_MMC
++		size_t bytesWritten = write (fd, data + processed, write_total);
++		if (bytesWritten != write_total) {
++#else
++		size_t bytesWritten = write (fd, data + processed, erasesize);
++		if (bytesWritten != erasesize) {
+ #endif
+-		if (write (fd, data + processed, erasesize) != erasesize) {
+ 			fprintf (stderr, "Write error on %s: %s\n",
+ 				 DEVNAME (dev), strerror (errno));
+ 			return -1;
+ 		}
+ 
++#ifndef CONFIG_ENV_IS_IN_MMC
+ 		ioctl (fd, MEMLOCK, &erase);
+-
++#endif
++#ifdef CONFIG_ENV_IS_IN_MMC
++		processed  += bytesWritten;
++#else
+ 		processed  += blocklen;
++#endif
+ 		block_seek = 0;
+ 		blockstart += blocklen;
+ 	}
+@@ -964,7 +987,7 @@ static int flash_read (int fd)
+ {
+ 	struct mtd_info_user mtdinfo;
+ 	int rc;
+-
++#ifndef CONFIG_ENV_IS_IN_MMC
+ 	rc = ioctl (fd, MEMGETINFO, &mtdinfo);
+ 	if (rc < 0) {
+ 		perror ("Cannot get MTD information");
+@@ -982,6 +1005,10 @@ static int flash_read (int fd)
+ 
+ 	rc = flash_read_buf (dev_current, fd, environment.image, CONFIG_ENV_SIZE,
+ 			     DEVOFFSET (dev_current), mtdinfo.type);
++#else
++	rc = flash_read_buf (dev_current, fd, environment.image, CONFIG_ENV_SIZE,
++			     DEVOFFSET (dev_current), 0);
++#endif
+ 
+ 	return (rc != CONFIG_ENV_SIZE) ? -1 : 0;
+ }
+diff --git a/tools/env/fw_env.config b/tools/env/fw_env.config
+index 8e21d5a..6b45687 100644
+--- a/tools/env/fw_env.config
++++ b/tools/env/fw_env.config
+@@ -17,3 +17,7 @@
+ 
+ # NAND example
+ #/dev/mtd0		0x4000		0x4000		0x20000			2
++
++# eMMC example
++# MMC device name       Device offset   Env. size
++#/dev/mmcblk0		0x400		0x1FC00		0x1FC00			1
diff --git a/patches/u-boot-2011.12/series b/patches/u-boot-2011.12/series
index eea4611..20733b1 100644
--- a/patches/u-boot-2011.12/series
+++ b/patches/u-boot-2011.12/series
@@ -1,4 +1,5 @@
 # generated by git-ptx-patches
 #tag:base --start-number 1
 0001-tools-Prefer-u-boot-includes-to-system-include-direc.patch
-# 944f1726d2ab9856a3d9b36c7af8e95b  - git-ptx-patches magic
+0002-u-boot-emmc-support-in-fw_printenv-fw_setenv.patch
+# 856c73a788cbb5e251c4dbadfbbf3785  - git-ptx-patches magic
-- 
1.9.1


-- 
ptxdist mailing list
ptxdist@pengutronix.de

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-08-25  9:57 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-04  8:29 [ptxdist] [RFC] u-boot-tools: emmc support in fw_printenv/fw_setenv Bruno Thomsen
2014-08-05 11:37 ` Markus Niebel
2014-08-05 12:29 ` Markus Niebel
2014-08-08 10:16   ` Michael Olbrich
2014-08-20  9:02     ` Bruno Thomsen
2014-08-25 10:09       ` Markus Niebel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox