recovery: Autodetection of device flash type
Detect flash type at runtime rather than requiring this to be set in the
device configuration. The detection is based on the existence of /proc/mtd,
/proc/emmc, or /dev/block/bml1.
Change-Id: I464962a567022c5862c249f06d36c2d1cddeacba
diff --git a/flashutils/Android.mk b/flashutils/Android.mk
index 5742af3..5f6fea2 100644
--- a/flashutils/Android.mk
+++ b/flashutils/Android.mk
@@ -4,10 +4,18 @@
ifeq ($(TARGET_ARCH),arm)
include $(CLEAR_VARS)
+LOCAL_SRC_FILES := flashutils.c
+LOCAL_MODULE := libflashutils
+LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_STATIC_LIBRARIES := libmmcutils libmtdutils libbmlutils
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
LOCAL_SRC_FILES := flash_image.c
LOCAL_MODULE := flash_image
LOCAL_MODULE_TAGS := eng
-LOCAL_STATIC_LIBRARIES := $(BOARD_FLASH_LIBRARY)
+#LOCAL_STATIC_LIBRARIES += $(BOARD_FLASH_LIBRARY)
+LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
@@ -15,7 +23,7 @@
LOCAL_SRC_FILES := dump_image.c
LOCAL_MODULE := dump_image
LOCAL_MODULE_TAGS := eng
-LOCAL_STATIC_LIBRARIES := $(BOARD_FLASH_LIBRARY)
+LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
@@ -23,7 +31,7 @@
LOCAL_SRC_FILES := erase_image.c
LOCAL_MODULE := erase_image
LOCAL_MODULE_TAGS := eng
-LOCAL_STATIC_LIBRARIES := $(BOARD_FLASH_LIBRARY)
+LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
@@ -53,7 +61,7 @@
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
LOCAL_MODULE_STEM := dump_image
-LOCAL_STATIC_LIBRARIES := $(BOARD_FLASH_LIBRARY) libcutils libc
+LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils libcutils libc
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
@@ -64,7 +72,7 @@
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
LOCAL_MODULE_STEM := flash_image
-LOCAL_STATIC_LIBRARIES := $(BOARD_FLASH_LIBRARY) libcutils libc
+LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils libcutils libc
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
@@ -75,10 +83,9 @@
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
LOCAL_MODULE_STEM := erase_image
-LOCAL_STATIC_LIBRARIES := $(BOARD_FLASH_LIBRARY) libcutils libc
+LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils libcutils libc
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
-
endif # TARGET_ARCH == arm
endif # !TARGET_SIMULATOR
diff --git a/flashutils/flashutils.c b/flashutils/flashutils.c
new file mode 100644
index 0000000..5c57756
--- /dev/null
+++ b/flashutils/flashutils.c
@@ -0,0 +1,168 @@
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include "flashutils/flashutils.h"
+
+enum flash_type {
+ UNSUPPORTED = -1,
+ UNKNOWN = 0,
+ MTD = 1,
+ MMC = 2,
+ BML = 3
+};
+
+int the_flash_type = UNKNOWN;
+
+int device_flash_type()
+{
+ if (the_flash_type == UNKNOWN) {
+ if (access("/dev/block/bml1", F_OK) == 0) {
+ the_flash_type = BML;
+ } else if (access("/proc/emmc", F_OK) == 0) {
+ the_flash_type = MMC;
+ } else if (access("/proc/mtd", F_OK) == 0) {
+ the_flash_type = MTD;
+ } else {
+ the_flash_type = UNSUPPORTED;
+ }
+ }
+ return the_flash_type;
+}
+
+char* get_default_filesystem()
+{
+ return device_flash_type() == MMC ? "ext3" : "yaffs2";
+}
+
+// This was pulled from bionic: The default system command always looks
+// for shell in /system/bin/sh. This is bad.
+#define _PATH_BSHELL "/sbin/sh"
+
+extern char **environ;
+int
+__system(const char *command)
+{
+ pid_t pid;
+ sig_t intsave, quitsave;
+ sigset_t mask, omask;
+ int pstat;
+ char *argp[] = {"sh", "-c", NULL, NULL};
+
+ if (!command) /* just checking... */
+ return(1);
+
+ argp[2] = (char *)command;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &mask, &omask);
+ switch (pid = vfork()) {
+ case -1: /* error */
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+ return(-1);
+ case 0: /* child */
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+ execve(_PATH_BSHELL, argp, environ);
+ _exit(127);
+ }
+
+ intsave = (sig_t) bsd_signal(SIGINT, SIG_IGN);
+ quitsave = (sig_t) bsd_signal(SIGQUIT, SIG_IGN);
+ pid = waitpid(pid, (int *)&pstat, 0);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+ (void)bsd_signal(SIGINT, intsave);
+ (void)bsd_signal(SIGQUIT, quitsave);
+ return (pid == -1 ? -1 : pstat);
+}
+
+int restore_raw_partition(const char *partition, const char *filename)
+{
+ int type = device_flash_type();
+ switch (type) {
+ case MTD:
+ return cmd_mtd_restore_raw_partition(partition, filename);
+ case MMC:
+ return cmd_mmc_restore_raw_partition(partition, filename);
+ case BML:
+ return cmd_bml_restore_raw_partition(partition, filename);
+ default:
+ return -1;
+ }
+}
+
+int backup_raw_partition(const char *partition, const char *filename)
+{
+ int type = device_flash_type();
+ switch (type) {
+ case MTD:
+ return cmd_mtd_backup_raw_partition(partition, filename);
+ case MMC:
+ return cmd_mmc_backup_raw_partition(partition, filename);
+ case BML:
+ return cmd_bml_backup_raw_partition(partition, filename);
+ default:
+ return -1;
+ }
+}
+
+int erase_raw_partition(const char *partition)
+{
+ int type = device_flash_type();
+ switch (type) {
+ case MTD:
+ return cmd_mtd_erase_raw_partition(partition);
+ case MMC:
+ return cmd_mmc_erase_raw_partition(partition);
+ case BML:
+ return cmd_bml_erase_raw_partition(partition);
+ default:
+ return -1;
+ }
+}
+
+int erase_partition(const char *partition, const char *filesystem)
+{
+ int type = device_flash_type();
+ switch (type) {
+ case MTD:
+ return cmd_mtd_erase_partition(partition, filesystem);
+ case MMC:
+ return cmd_mmc_erase_partition(partition, filesystem);
+ case BML:
+ return cmd_bml_erase_partition(partition, filesystem);
+ default:
+ return -1;
+ }
+}
+
+int mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only)
+{
+ int type = device_flash_type();
+ switch (type) {
+ case MTD:
+ return cmd_mtd_mount_partition(partition, mount_point, filesystem, read_only);
+ case MMC:
+ return cmd_mmc_mount_partition(partition, mount_point, filesystem, read_only);
+ case BML:
+ return cmd_bml_mount_partition(partition, mount_point, filesystem, read_only);
+ default:
+ return -1;
+ }
+}
+
+int get_partition_device(const char *partition, char *device)
+{
+ int type = device_flash_type();
+ switch (type) {
+ case MTD:
+ return cmd_mtd_get_partition_device(partition, device);
+ case MMC:
+ return cmd_mmc_get_partition_device(partition, device);
+ case BML:
+ return cmd_bml_get_partition_device(partition, device);
+ default:
+ return -1;
+ }
+}
diff --git a/flashutils/flashutils.h b/flashutils/flashutils.h
index f4466f0..953dd00 100644
--- a/flashutils/flashutils.h
+++ b/flashutils/flashutils.h
@@ -3,4 +3,36 @@
int erase_raw_partition(const char *partition);
int erase_partition(const char *partition, const char *filesystem);
int mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only);
-int get_partition_device(const char *partition, char *device);
\ No newline at end of file
+int get_partition_device(const char *partition, char *device);
+
+#define FLASH_MTD 0
+#define FLASH_MMC 1
+#define FLASH_BML 2
+
+int is_mtd_device();
+char* get_default_filesystem();
+
+int __system(const char *command);
+
+extern int cmd_mtd_restore_raw_partition(const char *partition, const char *filename);
+extern int cmd_mtd_backup_raw_partition(const char *partition, const char *filename);
+extern int cmd_mtd_erase_raw_partition(const char *partition);
+extern int cmd_mtd_erase_partition(const char *partition, const char *filesystem);
+extern int cmd_mtd_mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only);
+extern int cmd_mtd_get_partition_device(const char *partition, char *device);
+
+extern int cmd_mmc_restore_raw_partition(const char *partition, const char *filename);
+extern int cmd_mmc_backup_raw_partition(const char *partition, const char *filename);
+extern int cmd_mmc_erase_raw_partition(const char *partition);
+extern int cmd_mmc_erase_partition(const char *partition, const char *filesystem);
+extern int cmd_mmc_mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only);
+extern int cmd_mmc_get_partition_device(const char *partition, char *device);
+
+extern int cmd_bml_restore_raw_partition(const char *partition, const char *filename);
+extern int cmd_bml_backup_raw_partition(const char *partition, const char *filename);
+extern int cmd_bml_erase_raw_partition(const char *partition);
+extern int cmd_bml_erase_partition(const char *partition, const char *filesystem);
+extern int cmd_bml_mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only);
+extern int cmd_bml_get_partition_device(const char *partition, char *device);
+
+