From patchwork Wed Sep 3 17:05:54 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Rae X-Patchwork-Id: 36627 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f70.google.com (mail-oa0-f70.google.com [209.85.219.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5B734202E4 for ; Wed, 3 Sep 2014 17:04:28 +0000 (UTC) Received: by mail-oa0-f70.google.com with SMTP id eb12sf46635769oac.5 for ; Wed, 03 Sep 2014 10:04:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:mime-version:cc:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:content-type :content-transfer-encoding; bh=sSq5O/GsI/kvL9GDbnniAyQyO23q4suUcuvgV5on9i4=; b=aXgk4d9bjpB6jwiALf9/92FypxGXoD22691AkhUxFeArI9MbyOjgOh3lfkwvqrr6Wd PlVI5nWvWdHoYsC2PofPc977kwJDewuulke6sIUTs2QbN/i7TPslwOz4ir8+bgsR3GiB iIxEkYgj3iRJ0F21YcQ4WFM7cNR82EkzNppkz7j0VHg3uLmKL8ct0SQxCeiuqb4+GfXy OjnwVOXTztBsmZOrfax6BCmVBynB8xZPzY0HsBMzBjTIOUCHSVhfP17GWSVYin0Grh1f epaGfUR/FAuqvnDNlddEhMCV7a6teLGYCPUwLZ5MXiStD5uQoe3uMmIogDbIzHEXsTDK lz1w== X-Gm-Message-State: ALoCoQnFlsMoxloKhh8e3BhYjI9adOUIOAOVUfoovUXWiJElTb3Ysi+gxRa7SHkqlB7ybk6C+DQ/ X-Received: by 10.183.10.133 with SMTP id ea5mr24812812obd.24.1409763868012; Wed, 03 Sep 2014 10:04:28 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.46.100 with SMTP id j91ls2858302qga.44.gmail; Wed, 03 Sep 2014 10:04:27 -0700 (PDT) X-Received: by 10.52.94.36 with SMTP id cz4mr1177216vdb.75.1409763867852; Wed, 03 Sep 2014 10:04:27 -0700 (PDT) Received: from mail-vc0-f180.google.com (mail-vc0-f180.google.com [209.85.220.180]) by mx.google.com with ESMTPS id vm1si1260454vdc.29.2014.09.03.10.04.27 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 03 Sep 2014 10:04:27 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.180 as permitted sender) client-ip=209.85.220.180; Received: by mail-vc0-f180.google.com with SMTP id lf12so8921826vcb.25 for ; Wed, 03 Sep 2014 10:04:27 -0700 (PDT) X-Received: by 10.220.175.17 with SMTP id v17mr6632847vcz.0.1409763867756; Wed, 03 Sep 2014 10:04:27 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.45.67 with SMTP id uj3csp711121vcb; Wed, 3 Sep 2014 10:04:27 -0700 (PDT) X-Received: by 10.180.89.66 with SMTP id bm2mr3221058wib.71.1409763866702; Wed, 03 Sep 2014 10:04:26 -0700 (PDT) Received: from theia.denx.de (theia.denx.de. [85.214.87.163]) by mx.google.com with ESMTP id pm5si11385032wjc.146.2014.09.03.10.04.26 for ; Wed, 03 Sep 2014 10:04:26 -0700 (PDT) Received-SPF: none (google.com: u-boot-bounces@lists.denx.de does not designate permitted sender hosts) client-ip=85.214.87.163; Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C4CE04B680; Wed, 3 Sep 2014 19:04:12 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UMvx5cOhXwKN; Wed, 3 Sep 2014 19:04:12 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C60E5A75C1; Wed, 3 Sep 2014 19:03:50 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 6A85BA767C for ; Wed, 3 Sep 2014 19:03:48 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id eZ9WV8HM6zqP for ; Wed, 3 Sep 2014 19:03:47 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-gw2-out.broadcom.com (mail-gw2-out.broadcom.com [216.31.210.63]) by theia.denx.de (Postfix) with ESMTP id 7B2E4A75C1 for ; Wed, 3 Sep 2014 19:03:36 +0200 (CEST) X-IronPort-AV: E=Sophos;i="5.04,458,1406617200"; d="scan'208";a="44506829" Received: from irvexchcas08.broadcom.com (HELO IRVEXCHCAS08.corp.ad.broadcom.com) ([10.9.208.57]) by mail-gw2-out.broadcom.com with ESMTP; 03 Sep 2014 10:19:38 -0700 Received: from IRVEXCHSMTP3.corp.ad.broadcom.com (10.9.207.53) by IRVEXCHCAS08.corp.ad.broadcom.com (10.9.208.57) with Microsoft SMTP Server (TLS) id 14.3.174.1; Wed, 3 Sep 2014 10:03:36 -0700 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP3.corp.ad.broadcom.com (10.9.207.53) with Microsoft SMTP Server id 14.3.174.1; Wed, 3 Sep 2014 10:03:35 -0700 Received: from mail.broadcom.com (lbrmn-vmlnx03.ric.broadcom.com [10.136.4.105]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 0FF369F9FB; Wed, 3 Sep 2014 10:03:34 -0700 (PDT) From: Steve Rae To: , Tom Rini Date: Wed, 3 Sep 2014 10:05:54 -0700 Message-ID: <1409763954-5494-5-git-send-email-srae@broadcom.com> X-Mailer: git-send-email 1.8.5 In-Reply-To: <1409763954-5494-1-git-send-email-srae@broadcom.com> References: <1409763954-5494-1-git-send-email-srae@broadcom.com> MIME-Version: 1.0 Cc: Steve Rae Subject: [U-Boot] [PATCH v3 4/4] implement the Android sparse image format X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: srae@broadcom.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.180 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 update to provide usable implementation to U-Boot Signed-off-by: Steve Rae --- Changes in v3: None Changes in v2: None common/aboot.c | 129 +++++++++++++++++++++++++++++--------------------- include/aboot.h | 28 +++++++++++ include/sparse_defs.h | 7 +++ 3 files changed, 111 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 3611feb..d5c464b 100644 --- a/common/aboot.c +++ b/common/aboot.c @@ -3,6 +3,7 @@ * All rights reserved. * * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. + * Portions Copyright 2014 Broadcom Corporation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,44 +34,32 @@ * to the "BSD-3-Clause", therefore, DO NOT MODIFY THIS LICENSE TEXT! */ -void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz) +#include +#include +#include +#include +#include +#include + +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)) @@ -92,17 +81,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; chunktotal_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)) { @@ -115,6 +118,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: @@ -126,14 +130,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; @@ -148,9 +163,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( @@ -160,27 +175,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; @@ -189,7 +211,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) { @@ -202,8 +224,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; } @@ -211,6 +233,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 +#include + +#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