From 96edf3b9d7fd38d6059e158392eadca521ecb4d2 Mon Sep 17 00:00:00 2001 From: "guoyin.chen" Date: Fri, 22 May 2015 17:37:48 +0800 Subject: MA-6732 Add sparse image flash support for uboot's fastboot Add aboot.o based on CONFIG_FASTBOOT Add partition index for fastboot ptn table Add return value for write_sparse_image to know the sparse write status Add path to write_sparse_image based on the image received and partition to be flashed Signed-off-by: guoyin.chen --- common/Makefile | 3 ++ common/aboot.c | 47 ++++++++--------------- common/cmd_fastboot.c | 90 ++++++++++++++++++++++++++++++++++----------- drivers/fastboot/fastboot.c | 11 +++--- include/aboot.h | 2 +- include/fastboot.h | 9 ++++- 6 files changed, 103 insertions(+), 59 deletions(-) diff --git a/common/Makefile b/common/Makefile index 436ca39..9c1f18d 100644 --- a/common/Makefile +++ b/common/Makefile @@ -182,6 +182,9 @@ obj-y += usb.o usb_hub.o obj-$(CONFIG_USB_STORAGE) += usb_storage.o endif obj-$(CONFIG_CMD_FASTBOOT) += cmd_fastboot.o +ifndef CONFIG_FASTBOOT_FLASH_MMC_DEV +obj-$(CONFIG_CMD_FASTBOOT) += aboot.o +endif obj-$(CONFIG_CMD_FS_UUID) += cmd_fs_uuid.o obj-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o diff --git a/common/aboot.c b/common/aboot.c index fba8e3e..64be532 100644 --- a/common/aboot.c +++ b/common/aboot.c @@ -41,7 +41,7 @@ #include #include -void write_sparse_image(block_dev_desc_t *dev_desc, +int write_sparse_image(block_dev_desc_t *dev_desc, disk_partition_t *info, const char *part_name, void *data, unsigned sz) { @@ -86,8 +86,7 @@ void write_sparse_image(block_dev_desc_t *dev_desc, (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; + return 1; } puts("Flashing Sparse Image\n"); @@ -125,18 +124,14 @@ void write_sparse_image(block_dev_desc_t *dev_desc, if (chunk_header->total_sz != (sparse_header->chunk_hdr_sz + chunk_data_sz)) { - fastboot_fail( - "Bogus chunk size for chunk type Raw"); - return; + return 1; } if (blk + blkcnt > info->start + info->size) { printf( "%s: Request would exceed partition size!\n", __func__); - fastboot_fail( - "Request would exceed partition size!"); - return; + return 1; } blks = dev_desc->block_write(dev_desc->dev, blk, blkcnt, @@ -144,8 +139,7 @@ void write_sparse_image(block_dev_desc_t *dev_desc, if (blks != blkcnt) { printf("%s: Write failed " LBAFU "\n", __func__, blks); - fastboot_fail("flash write failure"); - return; + return 1; } blk += blkcnt; bytes_written += blkcnt * info->blksz; @@ -157,9 +151,7 @@ void write_sparse_image(block_dev_desc_t *dev_desc, if (chunk_header->total_sz != (sparse_header->chunk_hdr_sz + sizeof(uint32_t))) { - fastboot_fail( - "Bogus chunk size for chunk type FILL"); - return; + return 1; } fill_buf = (uint32_t *) @@ -168,9 +160,7 @@ void write_sparse_image(block_dev_desc_t *dev_desc, ARCH_DMA_MINALIGN)); if (!fill_buf) { - fastboot_fail( - "Malloc failed for: CHUNK_TYPE_FILL"); - return; + return 1; } fill_val = *(uint32_t *)data; @@ -183,9 +173,7 @@ void write_sparse_image(block_dev_desc_t *dev_desc, printf( "%s: Request would exceed partition size!\n", __func__); - fastboot_fail( - "Request would exceed partition size!"); - return; + return 1; } for (i = 0; i < blkcnt; i++) { @@ -195,9 +183,8 @@ void write_sparse_image(block_dev_desc_t *dev_desc, printf( "%s: Write failed, block # " LBAFU "\n", __func__, blkcnt); - fastboot_fail("flash write failure"); free(fill_buf); - return; + return 1; } blk++; } @@ -216,9 +203,7 @@ void write_sparse_image(block_dev_desc_t *dev_desc, if (chunk_header->total_sz != sparse_header->chunk_hdr_sz) { - fastboot_fail( - "Bogus chunk size for chunk type Dont Care"); - return; + return 1; } total_blocks += chunk_header->chunk_sz; data += chunk_data_sz; @@ -227,8 +212,7 @@ void write_sparse_image(block_dev_desc_t *dev_desc, default: printf("%s: Unknown chunk type: %x\n", __func__, chunk_header->chunk_type); - fastboot_fail("Unknown chunk type"); - return; + return 1; } } @@ -236,9 +220,10 @@ void write_sparse_image(block_dev_desc_t *dev_desc, 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"); + if (total_blocks != sparse_header->total_blks) { + printf("sparse image write failure"); + return 1; + } - fastboot_okay(""); - return; + return 0; } diff --git a/common/cmd_fastboot.c b/common/cmd_fastboot.c index b41b8ee..b741ecd 100644 --- a/common/cmd_fastboot.c +++ b/common/cmd_fastboot.c @@ -62,6 +62,7 @@ #include #include #include +#include #if defined(CONFIG_OF_LIBFDT) #include @@ -720,6 +721,16 @@ static void process_flash_sata(const char *cmdbuf, char *response) #endif #if defined(CONFIG_FASTBOOT_STORAGE_MMC) +static int is_sparse_partition(struct fastboot_ptentry *ptn) +{ + if (ptn && !strncmp(ptn->name, + FASTBOOT_PARTITION_SYSTEM, strlen(FASTBOOT_PARTITION_SYSTEM))) { + printf("support sparse flash partition for %s\n", ptn->name); + return 1; + } else + return 0; +} + static void process_flash_mmc(const char *cmdbuf, char *response) { if (download_bytes) { @@ -763,31 +774,68 @@ static void process_flash_mmc(const char *cmdbuf, char *response) sprintf(mmc_dev, "mmc dev %x", fastboot_devinfo.dev_id /*slot no*/); - /* block count */ - temp = (download_bytes + - MMC_SATA_BLOCK_SIZE - 1) / - MMC_SATA_BLOCK_SIZE; + if (is_sparse_partition(ptn) && + is_sparse_image(interface.transfer_buffer)) { + int mmc_no = 0; + struct mmc *mmc; + block_dev_desc_t *dev_desc; + disk_partition_t info; + mmc_no = fastboot_devinfo.dev_id; + + printf("sparse flash target is MMC:%d\n", mmc_no); + mmc = find_mmc_device(mmc_no); + if (mmc && mmc_init(mmc)) + printf("MMC card init failed!\n"); + + dev_desc = get_dev("mmc", mmc_no); + if (NULL == dev_desc) { + printf("** Block device MMC %d not supported\n", + mmc_no); + return; + } + + if (get_partition_info(dev_desc, + ptn->partition_index, &info)) { + printf("Bad partition index:%d for partition:%s\n", + ptn->partition_index, ptn->name); + return; + } + + printf("writing to partition '%s' for sparse, buffer size %d\n", + ptn->name, download_bytes); + mmcret = write_sparse_image(dev_desc, &info, ptn->name, + interface.transfer_buffer, download_bytes); + if (mmcret) + sprintf(response, "FAIL: Write partition"); + else + sprintf(response, "OKAY"); + } else { + /* block count */ + temp = (download_bytes + + MMC_SATA_BLOCK_SIZE - 1) / + MMC_SATA_BLOCK_SIZE; - sprintf(mmc_write, "mmc write 0x%x 0x%x 0x%x", - (unsigned int)interface.transfer_buffer, /*source*/ - ptn->start, /*dest*/ - temp /*length*/); + sprintf(mmc_write, "mmc write 0x%x 0x%x 0x%x", + (unsigned int)interface.transfer_buffer, /*source*/ + ptn->start, /*dest*/ + temp /*length*/); - printf("Initializing '%s'\n", ptn->name); + printf("Initializing '%s'\n", ptn->name); - mmcret = run_command(mmc_dev, 0); - if (mmcret) - sprintf(response, "FAIL:Init of MMC card"); - else - sprintf(response, "OKAY"); + mmcret = run_command(mmc_dev, 0); + if (mmcret) + sprintf(response, "FAIL:Init of MMC card"); + else + sprintf(response, "OKAY"); - printf("Writing '%s'\n", ptn->name); - if (run_command(mmc_write, 0)) { - printf("Writing '%s' FAILED!\n", ptn->name); - sprintf(response, "FAIL: Write partition"); - } else { - printf("Writing '%s' DONE!\n", ptn->name); - sprintf(response, "OKAY"); + printf("Writing '%s'\n", ptn->name); + if (run_command(mmc_write, 0)) { + printf("Writing '%s' FAILED!\n", ptn->name); + sprintf(response, "FAIL: Write partition"); + } else { + printf("Writing '%s' DONE!\n", ptn->name); + sprintf(response, "OKAY"); + } } } } else { diff --git a/drivers/fastboot/fastboot.c b/drivers/fastboot/fastboot.c index 0b5bebb..8fce951 100644 --- a/drivers/fastboot/fastboot.c +++ b/drivers/fastboot/fastboot.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. All Rights Reserved. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -804,6 +804,7 @@ static int _fastboot_parts_add_ptable_entry(int ptable_index, ptable[ptable_index].start = info.start; ptable[ptable_index].length = info.size; ptable[ptable_index].partition_id = mmc_partition_index; + ptable[ptable_index].partition_index = mmc_dos_partition_index; } return 0; } @@ -876,7 +877,7 @@ static int _fastboot_parts_load_from_ptable(void) ptable[PTN_MBR_INDEX].length = ANDROID_MBR_SIZE / dev_desc->blksz; ptable[PTN_MBR_INDEX].partition_id = user_partition; /* Bootloader */ - strcpy(ptable[PTN_BOOTLOADER_INDEX].name, "bootloader"); + strcpy(ptable[PTN_BOOTLOADER_INDEX].name, FASTBOOT_PARTITION_BOOTLOADER); ptable[PTN_BOOTLOADER_INDEX].start = ANDROID_BOOTLOADER_OFFSET / dev_desc->blksz; ptable[PTN_BOOTLOADER_INDEX].length = @@ -885,15 +886,15 @@ static int _fastboot_parts_load_from_ptable(void) _fastboot_parts_add_ptable_entry(PTN_KERNEL_INDEX, CONFIG_ANDROID_BOOT_PARTITION_MMC, - user_partition, "boot", dev_desc, ptable); + user_partition, FASTBOOT_PARTITION_BOOT , dev_desc, ptable); _fastboot_parts_add_ptable_entry(PTN_RECOVERY_INDEX, CONFIG_ANDROID_RECOVERY_PARTITION_MMC, user_partition, - "recovery", dev_desc, ptable); + FASTBOOT_PARTITION_RECOVERY, dev_desc, ptable); _fastboot_parts_add_ptable_entry(PTN_SYSTEM_INDEX, CONFIG_ANDROID_SYSTEM_PARTITION_MMC, user_partition, - "system", dev_desc, ptable); + FASTBOOT_PARTITION_SYSTEM, dev_desc, ptable); for (i = 0; i <= PTN_RECOVERY_INDEX; i++) fastboot_flash_add_ptn(&ptable[i]); diff --git a/include/aboot.h b/include/aboot.h index 30e4d36..383729d 100644 --- a/include/aboot.h +++ b/include/aboot.h @@ -23,6 +23,6 @@ static inline int is_sparse_image(void *buf) return 0; } -void write_sparse_image(block_dev_desc_t *dev_desc, +int 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/fastboot.h b/include/fastboot.h index c81abcf..ad7bb29 100644 --- a/include/fastboot.h +++ b/include/fastboot.h @@ -3,7 +3,7 @@ * Windriver, * Tom Rix * - * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. + * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -134,6 +134,11 @@ #define FASTBOOT_MMC_USER_PARTITION_ID 0 #define FASTBOOT_MMC_NONE_PARTITION_ID -1 +#define FASTBOOT_PARTITION_BOOT "boot" +#define FASTBOOT_PARTITION_RECOVERY "recovery" +#define FASTBOOT_PARTITION_SYSTEM "system" +#define FASTBOOT_PARTITION_BOOTLOADER "bootloader" + enum { DEV_SATA, DEV_MMC, @@ -213,6 +218,8 @@ struct fastboot_ptentry { unsigned int flags; /* partition id: 0 - normal partition; 1 - boot partition */ unsigned int partition_id; + /* partition number in block device */ + unsigned int partition_index; }; struct fastboot_device_info { -- cgit v1.1