From 226e86ac8378bc9c5732b12bb2a907f87e11b1d7 Mon Sep 17 00:00:00 2001 From: Peter Gregus Date: Sat, 27 Apr 2013 10:49:09 +0200 Subject: [PATCH] Added support for boot and recovery partitions backup EMMC of MTK6589 is a large continuous block covering all partitions. Recovery and boot partitions definitions are somewhat hidden from MBR and /proc/emmc disabling CWM to determine correct sizes of these partitions automatically. This results in CWM using standard fseek/ftell method which returns the size of the whole EMMC which can be several Gigabytes. This commit enables to define sizes for boot and recovery partitions explicitly using BoardConfig flags - so the correct number of bytes can be copied from these devices during backup. Two pairs of config flags are available: CWM_EMMC_BOOT_DEVICE_NAME: defines the name of boot partition device (typically /dev/bootimg) CWM_EMMC_BOOT_DEVICE_SIZE: defines size of boot partition in bytes CWM_EMMC_RECOVERY_DEVICE_NAME: defines the name of recovery partition device (typically /dev/recovery) CWM_EMMC_RECOVERY_DEVICE_SIZE: defines size of recovery partition in bytes During backup, the name of partition being processed is checked against defined *DEVICE_NAME flag. If matches then size is set from the corresponding *DEVICE_SIZE flag. Change-Id: Ia5b8fbd50ff234301ce812e39a648c5cce87e284 --- mmcutils/Android.mk | 16 +++++++++++++++ mmcutils/mmcutils.c | 47 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/mmcutils/Android.mk b/mmcutils/Android.mk index e29bf41b6..72a43e34a 100644 --- a/mmcutils/Android.mk +++ b/mmcutils/Android.mk @@ -3,6 +3,22 @@ ifneq ($(TARGET_SIMULATOR),true) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +ifneq ($(CWM_EMMC_BOOT_DEVICE_NAME),) + LOCAL_CFLAGS += -DCWM_EMMC_BOOT_DEVICE_NAME="$(CWM_EMMC_BOOT_DEVICE_NAME)" +endif + +ifneq ($(CWM_EMMC_BOOT_DEVICE_SIZE),) + LOCAL_CFLAGS += -DCWM_EMMC_BOOT_DEVICE_SIZE=$(CWM_EMMC_BOOT_DEVICE_SIZE) +endif + +ifneq ($(CWM_EMMC_RECOVERY_DEVICE_NAME),) + LOCAL_CFLAGS += -DCWM_EMMC_RECOVERY_DEVICE_NAME="$(CWM_EMMC_RECOVERY_DEVICE_NAME)" +endif + +ifneq ($(CWM_EMMC_RECOVERY_DEVICE_SIZE),) + LOCAL_CFLAGS += -DCWM_EMMC_RECOVERY_DEVICE_SIZE=$(CWM_EMMC_RECOVERY_DEVICE_SIZE) +endif + LOCAL_SRC_FILES := \ mmcutils.c diff --git a/mmcutils/mmcutils.c b/mmcutils/mmcutils.c index f9c7b702a..2433e027e 100644 --- a/mmcutils/mmcutils.c +++ b/mmcutils/mmcutils.c @@ -41,6 +41,9 @@ #include "mmcutils.h" +#define XSTR(x) #x +#define STR(x) XSTR(x) + unsigned ext3_count = 0; char *ext3_partitions[] = {"system", "userdata", "cache", "NONE"}; @@ -471,13 +474,12 @@ mmc_raw_copy (const MmcPartition *partition, char *in_file) { int -mmc_raw_dump_internal (const char* in_file, const char *out_file) { +mmc_raw_dump_internal (const char* in_file, const char *out_file, unsigned size) { int ch; FILE *in; FILE *out; int val = 0; char buf[512]; - unsigned sz = 0; unsigned i; int ret = -1; @@ -489,18 +491,26 @@ mmc_raw_dump_internal (const char* in_file, const char *out_file) { if (out == NULL) goto ERROR2; - fseek(in, 0L, SEEK_END); - sz = ftell(in); - fseek(in, 0L, SEEK_SET); + if (size == 0) + { + fseek(in, 0L, SEEK_END); + size = ftell(in); + fseek(in, 0L, SEEK_SET); + } - if (sz % 512) + if (size % 512) { + unsigned counter = 0; while ( ( ch = fgetc ( in ) ) != EOF ) + { fputc ( ch, out ); + if (++counter == size) + break; + } } else { - for (i=0; i< (sz/512); i++) + for (i=0; i< (size/512); i++) { if ((fread(buf, 512, 1, in)) != 1) goto ERROR1; @@ -523,7 +533,7 @@ mmc_raw_dump_internal (const char* in_file, const char *out_file) { // TODO: refactor this to not be a giant copy paste mess int mmc_raw_dump (const MmcPartition *partition, char *out_file) { - return mmc_raw_dump_internal(partition->device_index, out_file); + return mmc_raw_dump_internal(partition->device_index, out_file, 0); } @@ -594,7 +604,7 @@ int cmd_mmc_restore_raw_partition(const char *partition, const char *filename) return mmc_raw_copy(p, filename); } else { - return mmc_raw_dump_internal(filename, partition); + return mmc_raw_dump_internal(filename, partition, 0); } } @@ -609,7 +619,24 @@ int cmd_mmc_backup_raw_partition(const char *partition, const char *filename) return mmc_raw_dump(p, filename); } else { - return mmc_raw_dump_internal(partition, filename); + unsigned size = 0; + + // take boot and recovery partition sizes into account if defined +#if defined(CWM_EMMC_BOOT_DEVICE_NAME) && defined(CWM_EMMC_BOOT_DEVICE_SIZE) + if (strcmp(partition, STR(CWM_EMMC_BOOT_DEVICE_NAME)) == 0) { + size = CWM_EMMC_BOOT_DEVICE_SIZE; + printf("CWM_EMMC_BOOT_DEVICE: %s; Size: 0x%x\n", partition, size); + } +#endif + +#if defined(CWM_EMMC_RECOVERY_DEVICE_NAME) && defined(CWM_EMMC_RECOVERY_DEVICE_SIZE) + if (strcmp(partition, STR(CWM_EMMC_RECOVERY_DEVICE_NAME)) == 0) { + size = CWM_EMMC_RECOVERY_DEVICE_SIZE; + printf("CWM_EMMC_RECOVERY_DEVICE: %s; Size: 0x%x\n", partition, size); + } +#endif + + return mmc_raw_dump_internal(partition, filename, size); } }