From: Bruno Thomsen <bth@kamstrup.dk>
To: ptxdist@pengutronix.de
Cc: bth@kamstrup.dk, Martin Fisker <mfi@kamstrup.dk>
Subject: [ptxdist] [RFC] u-boot-tools: emmc support in fw_printenv/fw_setenv
Date: Mon, 4 Aug 2014 10:29:22 +0200 [thread overview]
Message-ID: <1407140962-2116-1-git-send-email-bth@kamstrup.dk> (raw)
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
next reply other threads:[~2014-08-04 8:29 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-04 8:29 Bruno Thomsen [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1407140962-2116-1-git-send-email-bth@kamstrup.dk \
--to=bth@kamstrup.dk \
--cc=mfi@kamstrup.dk \
--cc=ptxdist@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox