All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steve Rae <srae@broadcom.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 4/4] implement the Android sparse image format
Date: Thu, 28 Aug 2014 10:53:54 -0700	[thread overview]
Message-ID: <1409248434-25762-5-git-send-email-srae@broadcom.com> (raw)
In-Reply-To: <1409248434-25762-1-git-send-email-srae@broadcom.com>

update to provide usable implementation to U-Boot

Signed-off-by: Steve Rae <srae@broadcom.com>
---

Changes in v2: None

 common/aboot.c        | 128 +++++++++++++++++++++++++++++---------------------
 include/aboot.h       |  28 +++++++++++
 include/sparse_defs.h |   7 +++
 3 files changed, 110 insertions(+), 53 deletions(-)
 create mode 100644 include/aboot.h
 create mode 100644 include/sparse_defs.h

diff --git a/common/aboot.c b/common/aboot.c
index 351199e..efeeece 100644
--- a/common/aboot.c
+++ b/common/aboot.c
@@ -8,44 +8,32 @@
  * SPDX-License-Identifier:	BSD-3-Clause
  */
 
-void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
+#include <config.h>
+#include <common.h>
+#include <aboot.h>
+#include <malloc.h>
+#include <part.h>
+#include <sparse_format.h>
+
+void write_sparse_image(block_dev_desc_t *dev_desc,
+		disk_partition_t *info, const char *part_name,
+		void *data, unsigned sz)
 {
+	lbaint_t blk;
+	lbaint_t blkcnt;
+	lbaint_t blks;
+	uint32_t bytes_written = 0;
 	unsigned int chunk;
 	unsigned int chunk_data_sz;
 	uint32_t *fill_buf = NULL;
 	uint32_t fill_val;
-	uint32_t chunk_blk_cnt = 0;
 	sparse_header_t *sparse_header;
 	chunk_header_t *chunk_header;
 	uint32_t total_blocks = 0;
-	unsigned long long ptn = 0;
-	unsigned long long size = 0;
-	int index = INVALID_PTN;
 	int i;
-	uint8_t lun = 0;
-
-	index = partition_get_index(arg);
-	ptn = partition_get_offset(index);
-	if(ptn == 0) {
-		fastboot_fail("partition table doesn't exist");
-		return;
-	}
-
-	size = partition_get_size(index);
-	if (ROUND_TO_PAGE(sz,511) > size) {
-		fastboot_fail("size too large");
-		return;
-	}
-
-	lun = partition_get_lun(index);
-	mmc_set_lun(lun);
 
 	/* Read and skip over sparse image header */
 	sparse_header = (sparse_header_t *) data;
-	if ((sparse_header->total_blks * sparse_header->blk_sz) > size) {
-		fastboot_fail("size too large");
-		return;
-	}
 
 	data += sparse_header->file_hdr_sz;
 	if (sparse_header->file_hdr_sz > sizeof(sparse_header_t))
@@ -67,17 +55,31 @@ void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
 	debug("total_blks: %d\n", sparse_header->total_blks);
 	debug("total_chunks: %d\n", sparse_header->total_chunks);
 
+	/* verify sparse_header->blk_sz is an exact multiple of info->blksz */
+	if (sparse_header->blk_sz !=
+	    (sparse_header->blk_sz & ~(info->blksz - 1))) {
+		printf("%s: Sparse image block size issue [%u]\n",
+		       __func__, sparse_header->blk_sz);
+		fastboot_fail("sparse image block size issue");
+		return;
+	}
+
+	puts("Flashing Sparse Image\n");
+
 	/* Start processing chunks */
+	blk = info->start;
 	for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
 	{
 		/* Read and skip over chunk header */
 		chunk_header = (chunk_header_t *) data;
 		data += sizeof(chunk_header_t);
 
-		debug("=== Chunk Header ===\n");
-		debug("chunk_type: 0x%x\n", chunk_header->chunk_type);
-		debug("chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
-		debug("total_size: 0x%x\n", chunk_header->total_sz);
+		if (chunk_header->chunk_type != CHUNK_TYPE_RAW) {
+			debug("=== Chunk Header ===\n");
+			debug("chunk_type: 0x%x\n", chunk_header->chunk_type);
+			debug("chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
+			debug("total_size: 0x%x\n", chunk_header->total_sz);
+		}
 
 		if (sparse_header->chunk_hdr_sz > sizeof(chunk_header_t))
 		{
@@ -90,6 +92,7 @@ void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
 		}
 
 		chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
+		blkcnt = chunk_data_sz / info->blksz;
 		switch (chunk_header->chunk_type)
 		{
 			case CHUNK_TYPE_RAW:
@@ -101,14 +104,25 @@ void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
 				return;
 			}
 
-			if (mmc_write(ptn +
-				      ((uint64_t)total_blocks *
-						 sparse_header->blk_sz),
-				      chunk_data_sz, (unsigned int *)data))
-			{
+			if (blk + blkcnt > info->start + info->size) {
+				printf(
+				    "%s: Request would exceed partition size!\n",
+				    __func__);
+				fastboot_fail(
+				    "Request would exceed partition size!");
+				return;
+			}
+
+			blks = dev_desc->block_write(dev_desc->dev, blk, blkcnt,
+						     data);
+			if (blks != blkcnt) {
+				printf("%s: Write failed " LBAFU "\n",
+				       __func__, blks);
 				fastboot_fail("flash write failure");
 				return;
 			}
+			blk += blkcnt;
+			bytes_written += blkcnt * info->blksz;
 			total_blocks += chunk_header->chunk_sz;
 			data += chunk_data_sz;
 			break;
@@ -123,9 +137,9 @@ void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
 			}
 
 			fill_buf = (uint32_t *)
-				   memalign(CACHE_LINE,
-					    ROUNDUP(sparse_header->blk_sz,
-						    CACHE_LINE));
+				   memalign(ARCH_DMA_MINALIGN,
+					    ROUNDUP(info->blksz,
+						    ARCH_DMA_MINALIGN));
 			if (!fill_buf)
 			{
 				fastboot_fail(
@@ -135,27 +149,34 @@ void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
 
 			fill_val = *(uint32_t *)data;
 			data = (char *) data + sizeof(uint32_t);
-			chunk_blk_cnt = chunk_data_sz / sparse_header->blk_sz;
 
-			for (i = 0; i < (sparse_header->blk_sz / sizeof(fill_val)); i++)
-			{
+			for (i = 0; i < (info->blksz / sizeof(fill_val)); i++)
 				fill_buf[i] = fill_val;
+
+			if (blk + blkcnt > info->start + info->size) {
+				printf(
+				    "%s: Request would exceed partition size!\n",
+				    __func__);
+				fastboot_fail(
+				    "Request would exceed partition size!");
+				return;
 			}
 
-			for (i = 0; i < chunk_blk_cnt; i++)
-			{
-				if (mmc_write(ptn +
-					      ((uint64_t)total_blocks *
-							 sparse_header->blk_sz),
-					      sparse_header->blk_sz, fill_buf))
-				{
+			for (i = 0; i < blkcnt; i++) {
+				blks = dev_desc->block_write(dev_desc->dev,
+							     blk, 1, fill_buf);
+				if (blks != 1) {
+					printf(
+					    "%s: Write failed, block # " LBAFU "\n",
+					    __func__, blkcnt);
 					fastboot_fail("flash write failure");
 					free(fill_buf);
 					return;
 				}
-
-				total_blocks++;
+				blk++;
 			}
+			bytes_written += blkcnt * info->blksz;
+			total_blocks += chunk_data_sz / sparse_header->blk_sz;
 
 			free(fill_buf);
 			break;
@@ -164,7 +185,7 @@ void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
 			total_blocks += chunk_header->chunk_sz;
 			break;
 
-			case CHUNK_TYPE_CRC:
+			case CHUNK_TYPE_CRC32:
 			if (chunk_header->total_sz !=
 			    sparse_header->chunk_hdr_sz)
 			{
@@ -177,8 +198,8 @@ void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
 			break;
 
 			default:
-			debug("Unkown chunk type: %x\n",
-			      chunk_header->chunk_type);
+			printf("%s: Unknown chunk type: %x\n", __func__,
+			       chunk_header->chunk_type);
 			fastboot_fail("Unknown chunk type");
 			return;
 		}
@@ -186,6 +207,7 @@ void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
 
 	debug("Wrote %d blocks, expected to write %d blocks\n",
 	      total_blocks, sparse_header->total_blks);
+	printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name);
 
 	if (total_blocks != sparse_header->total_blks)
 		fastboot_fail("sparse image write failure");
diff --git a/include/aboot.h b/include/aboot.h
new file mode 100644
index 0000000..30e4d36
--- /dev/null
+++ b/include/aboot.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2014 Broadcom Corporation.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <part.h>
+#include <sparse_format.h>
+
+#define ROUNDUP(x, y)	(((x) + ((y) - 1)) & ~((y) - 1))
+
+void fastboot_fail(const char *s);
+void fastboot_okay(const char *s);
+
+static inline int is_sparse_image(void *buf)
+{
+	sparse_header_t *s_header = (sparse_header_t *)buf;
+
+	if ((le32_to_cpu(s_header->magic) == SPARSE_HEADER_MAGIC) &&
+	    (le16_to_cpu(s_header->major_version) == 1))
+		return 1;
+
+	return 0;
+}
+
+void write_sparse_image(block_dev_desc_t *dev_desc,
+		disk_partition_t *info, const char *part_name,
+		void *data, unsigned sz);
diff --git a/include/sparse_defs.h b/include/sparse_defs.h
new file mode 100644
index 0000000..d0612c9
--- /dev/null
+++ b/include/sparse_defs.h
@@ -0,0 +1,7 @@
+/*
+ * Copyright 2014 Broadcom Corporation.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <linux/types.h>
-- 
1.8.5

      parent reply	other threads:[~2014-08-28 17:53 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-28 17:53 [U-Boot] [PATCH v2 0/4] Implement "sparse format" for fastboot Steve Rae
2014-08-28 17:53 ` [U-Boot] [PATCH v2 1/4] add code to handle Android sparse image format Steve Rae
2014-08-28 21:16   ` Tom Rini
2014-08-28 21:31     ` Steve Rae
2014-08-28 21:52       ` Steve Rae
2014-08-29  8:20         ` Marek Vasut
2014-08-29 15:11         ` Tom Rini
2014-08-29 17:38           ` Steve Rae
2014-08-29 20:54             ` Marek Vasut
2014-08-29 23:13               ` Steve Rae
2014-09-03  0:03                 ` Steve Rae
2014-09-03  0:33                   ` Tom Rini
2014-08-28 17:53 ` [U-Boot] [PATCH v2 2/4] update code which handles " Steve Rae
2014-08-28 17:53 ` [U-Boot] [PATCH v2 3/4] cleanup code which handles the " Steve Rae
2014-08-28 19:43   ` Tom Rini
2014-08-28 20:33     ` Steve Rae
2014-08-28 17:53 ` Steve Rae [this message]

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=1409248434-25762-5-git-send-email-srae@broadcom.com \
    --to=srae@broadcom.com \
    --cc=u-boot@lists.denx.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.