Refactor recovery's block device handling to work across variant hardware in a cleaner fashion.
Re add firmware update Change-Id: I699ad22390ed14e597d17a7bcb32ad1b1af00b4b support mmc misc Change-Id: Iff02f8d03db6835f501d052140cebeefee521305 fix compile errors Change-Id: I032edbd157a8a15f561bb83330c715ebaa008d18 fix compile errors Change-Id: Idff3449be3376f22fceefc2c35637527f8df8f3f Initial work to clean up the block devices. Change-Id: I4be20ac124864a281be9cd116e211a2618404a27 all done Change-Id: I0338f62f6a045556ebe90b0200685be113178319 fix up nandroid Change-Id: I886f00271183e6d2921c080b0939341f2cf12a4d
This commit is contained in:
parent
fef77c0253
commit
19447c0550
110
Android.mk
110
Android.mk
@ -8,6 +8,7 @@ commands_recovery_local_path := $(LOCAL_PATH)
|
||||
# LOCAL_CPP_EXTENSION := .c
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
mounts.c \
|
||||
extendedcommands.c \
|
||||
nandroid.c \
|
||||
legacy.c \
|
||||
@ -49,94 +50,13 @@ LOCAL_CFLAGS += -DRECOVERY_VERSION="$(RECOVERY_VERSION)"
|
||||
RECOVERY_API_VERSION := 2
|
||||
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
|
||||
|
||||
ifeq ($(BOARD_HAS_NO_SELECT_BUTTON),true)
|
||||
LOCAL_CFLAGS += -DKEY_POWER_IS_SELECT_ITEM
|
||||
endif
|
||||
BOARD_RECOVERY_DEFINES := BOARD_HAS_NO_SELECT_BUTTON BOARD_SDCARD_DEVICE_PRIMARY BOARD_SDCARD_DEVICE_SECONDARY BOARD_SDEXT_DEVICE BOARD_SDEXT_FILESYSTEM BOARD_DATA_DEVICE BOARD_DATA_FILESYSTEM BOARD_DATADATA_DEVICE BOARD_DATADATA_FILESYSTEM BOARD_CACHE_DEVICE BOARD_CACHE_FILESYSTEM BOARD_SYSTEM_DEVICE BOARD_SYSTEM_FILESYSTEM BOARD_HAS_DATADATA BOARD_DATA_FILESYSTEM_OPTIONS BOARD_DATADATA_FILESYSTEM_OPTIONS BOARD_CACHE_FILESYSTEM_OPTIONS BOARD_SYSTEM_FILESYSTEM_OPTIONS BOARD_HAS_MTD_CACHE BOARD_USES_BMLUTILS BOARD_USES_MMCUTILS BOARD_HAS_SMALL_RECOVERY
|
||||
|
||||
ifdef BOARD_SDCARD_DEVICE_PRIMARY
|
||||
LOCAL_CFLAGS += -DSDCARD_DEVICE_PRIMARY=\"$(BOARD_SDCARD_DEVICE_PRIMARY)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_SDCARD_DEVICE_SECONDARY
|
||||
LOCAL_CFLAGS += -DSDCARD_DEVICE_SECONDARY=\"$(BOARD_SDCARD_DEVICE_SECONDARY)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_SDEXT_DEVICE
|
||||
LOCAL_CFLAGS += -DSDEXT_DEVICE=\"$(BOARD_SDEXT_DEVICE)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_SDEXT_FILESYSTEM
|
||||
LOCAL_CFLAGS += -DSDEXT_FILESYSTEM=\"$(BOARD_SDEXT_FILESYSTEM)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_DATA_DEVICE
|
||||
LOCAL_CFLAGS += -DDATA_DEVICE=\"$(BOARD_DATA_DEVICE)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_DATA_FILESYSTEM
|
||||
LOCAL_CFLAGS += -DDATA_FILESYSTEM=\"$(BOARD_DATA_FILESYSTEM)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_DATADATA_DEVICE
|
||||
LOCAL_CFLAGS += -DDATADATA_DEVICE=\"$(BOARD_DATADATA_DEVICE)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_DATADATA_FILESYSTEM
|
||||
LOCAL_CFLAGS += -DDATADATA_FILESYSTEM=\"$(BOARD_DATADATA_FILESYSTEM)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_CACHE_DEVICE
|
||||
LOCAL_CFLAGS += -DCACHE_DEVICE=\"$(BOARD_CACHE_DEVICE)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_CACHE_FILESYSTEM
|
||||
LOCAL_CFLAGS += -DCACHE_FILESYSTEM=\"$(BOARD_CACHE_FILESYSTEM)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_SYSTEM_DEVICE
|
||||
LOCAL_CFLAGS += -DSYSTEM_DEVICE=\"$(BOARD_SYSTEM_DEVICE)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_SYSTEM_FILESYSTEM
|
||||
LOCAL_CFLAGS += -DSYSTEM_FILESYSTEM=\"$(BOARD_SYSTEM_FILESYSTEM)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_HAS_DATADATA
|
||||
LOCAL_CFLAGS += -DHAS_DATADATA
|
||||
endif
|
||||
|
||||
ifdef BOARD_DATA_FILESYSTEM_OPTIONS
|
||||
LOCAL_CFLAGS += -DDATA_FILESYSTEM_OPTIONS=\"$(BOARD_DATA_FILESYSTEM_OPTIONS)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_DATADATA_FILESYSTEM_OPTIONS
|
||||
LOCAL_CFLAGS += -DDATADATA_FILESYSTEM_OPTIONS=\"$(BOARD_DATADATA_FILESYSTEM_OPTIONS)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_CACHE_FILESYSTEM_OPTIONS
|
||||
LOCAL_CFLAGS += -DCACHE_FILESYSTEM_OPTIONS=\"$(BOARD_CACHE_FILESYSTEM_OPTIONS)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_SYSTEM_FILESYSTEM_OPTIONS
|
||||
LOCAL_CFLAGS += -DSYSTEM_FILESYSTEM_OPTIONS=\"$(BOARD_SYSTEM_FILESYSTEM_OPTIONS)\"
|
||||
endif
|
||||
|
||||
ifdef BOARD_HAS_MTD_CACHE
|
||||
LOCAL_CFLAGS += -DBOARD_HAS_MTD_CACHE
|
||||
endif
|
||||
|
||||
ifdef BOARD_USES_BMLUTILS
|
||||
LOCAL_CFLAGS += -DBOARD_USES_BMLUTILS
|
||||
LOCAL_STATIC_LIBRARIES += libbmlutils
|
||||
endif
|
||||
|
||||
ifdef BOARD_USES_MMCUTILS
|
||||
LOCAL_CFLAGS += -DBOARD_USES_MMCUTILS
|
||||
endif
|
||||
|
||||
ifdef BOARD_HAS_SMALL_RECOVERY
|
||||
LOCAL_CFLAGS += -DBOARD_HAS_SMALL_RECOVERY
|
||||
endif
|
||||
$(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
|
||||
$(if $($(board_define)), \
|
||||
$(eval LOCAL_CFLAGS += -D$(board_define)=\"$($(board_define))\") \
|
||||
) \
|
||||
)
|
||||
|
||||
# This binary is in the recovery ramdisk, which is otherwise a copy of root.
|
||||
# It gets copied there in config/Makefile. LOCAL_MODULE_TAGS suppresses
|
||||
@ -151,9 +71,20 @@ ifeq ($(BOARD_CUSTOM_RECOVERY_KEYMAPPING),)
|
||||
else
|
||||
LOCAL_SRC_FILES += $(BOARD_CUSTOM_RECOVERY_KEYMAPPING)
|
||||
endif
|
||||
LOCAL_STATIC_LIBRARIES += libbusybox libclearsilverregex libmkyaffs2image libunyaffs liberase_image libdump_image libflash_image libmtdutils
|
||||
LOCAL_STATIC_LIBRARIES += libbusybox libclearsilverregex libmkyaffs2image libunyaffs liberase_image libdump_image libflash_image
|
||||
|
||||
ifdef BOARD_USES_BMLUTILS
|
||||
BOARD_FLASH_LIBRARY := libbmlutils
|
||||
else ifdef BOARD_USES_MMCUTILS
|
||||
BOARD_FLASH_LIBRARY := libmmcutils
|
||||
else
|
||||
BOARD_FLASH_LIBRARY := libmtdutils
|
||||
endif
|
||||
|
||||
LOCAL_STATIC_LIBRARIES += $(BOARD_FLASH_LIBRARY)
|
||||
|
||||
LOCAL_STATIC_LIBRARIES += libamend
|
||||
LOCAL_STATIC_LIBRARIES += libminzip libunz libmtdutils libmmcutils libmincrypt
|
||||
LOCAL_STATIC_LIBRARIES += libminzip libunz libmincrypt
|
||||
LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libpng libcutils
|
||||
LOCAL_STATIC_LIBRARIES += libstdc++ libc
|
||||
|
||||
@ -217,6 +148,7 @@ include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(commands_recovery_local_path)/amend/Android.mk
|
||||
include $(commands_recovery_local_path)/bmlutils/Android.mk
|
||||
include $(commands_recovery_local_path)/flashutils/Android.mk
|
||||
include $(commands_recovery_local_path)/minui/Android.mk
|
||||
include $(commands_recovery_local_path)/minzip/Android.mk
|
||||
include $(commands_recovery_local_path)/mtdutils/Android.mk
|
||||
|
@ -145,7 +145,7 @@ cmd_format(const char *name, void *cookie, int argc, const char *argv[],
|
||||
LOGE("Can't format %s\n", root);
|
||||
return 1;
|
||||
}
|
||||
#ifdef HAS_DATADATA
|
||||
#ifdef BOARD_HAS_DATADATA
|
||||
if (0 == strcmp(root, "DATA:")) {
|
||||
ret = format_root_device("DATADATA:");
|
||||
if (ret != 0) {
|
||||
@ -653,6 +653,7 @@ static int
|
||||
cmd_write_raw_image(const char *name, void *cookie,
|
||||
int argc, const char *argv[], PermissionRequestList *permissions)
|
||||
{
|
||||
#ifdef BOARD_USES_MTDUTILS
|
||||
UNUSED(cookie);
|
||||
CHECK_WORDS();
|
||||
//xxx permissions
|
||||
@ -738,6 +739,10 @@ cmd_write_raw_image(const char *name, void *cookie,
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
LOGE("Board does not support mtd utils.");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* mark <resource> dirty|clean
|
||||
|
@ -33,9 +33,6 @@
|
||||
#include "commands.h"
|
||||
#include "amend/amend.h"
|
||||
|
||||
#include "mtdutils/mtdutils.h"
|
||||
#include "mmcutils/mmcutils.h"
|
||||
#include "mtdutils/dump_image.h"
|
||||
#include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h"
|
||||
#include "../../external/yaffs2/yaffs2/utils/unyaffs.h"
|
||||
|
||||
@ -395,7 +392,7 @@ void show_nandroid_restore_menu()
|
||||
void show_mount_usb_storage_menu()
|
||||
{
|
||||
char command[PATH_MAX];
|
||||
sprintf(command, "echo %s > /sys/devices/platform/usb_mass_storage/lun0/file", SDCARD_DEVICE_PRIMARY);
|
||||
sprintf(command, "echo %s > /sys/devices/platform/usb_mass_storage/lun0/file", BOARD_SDCARD_DEVICE_PRIMARY);
|
||||
__system(command);
|
||||
static char* headers[] = { "USB Mass Storage device",
|
||||
"Leaving this menu unmount",
|
||||
@ -441,13 +438,13 @@ int confirm_selection(const char* title, const char* confirm)
|
||||
return chosen_item == 7;
|
||||
}
|
||||
|
||||
int format_non_mtd_device(const char* root)
|
||||
int format_unknown_device(const char* root)
|
||||
{
|
||||
// if this is SDEXT:, don't worry about it.
|
||||
if (0 == strcmp(root, "SDEXT:"))
|
||||
{
|
||||
struct stat st;
|
||||
if (0 != stat(SDEXT_DEVICE, &st))
|
||||
if (0 != stat(BOARD_SDEXT_DEVICE, &st))
|
||||
{
|
||||
ui_print("No app2sd partition found. Skipping format of /sd-ext.\n");
|
||||
return 0;
|
||||
@ -569,7 +566,7 @@ void show_partition_menu()
|
||||
if (!confirm_selection(confirm_format, confirm))
|
||||
continue;
|
||||
ui_print("Formatting %s...\n", mmcs[chosen_item][1]);
|
||||
if (0 != format_non_mtd_device(mmcs[chosen_item][1]))
|
||||
if (0 != format_unknown_device(mmcs[chosen_item][1]))
|
||||
ui_print("Error formatting %s!\n", mmcs[chosen_item][1]);
|
||||
else
|
||||
ui_print("Done.\n");
|
||||
@ -918,22 +915,15 @@ void write_fstab_root(char *root_path, FILE *file)
|
||||
LOGW("Unable to get root info for %s during fstab generation!", root_path);
|
||||
return;
|
||||
}
|
||||
MtdPartition *mtd = get_root_mtd_partition(root_path);
|
||||
if (mtd != NULL)
|
||||
char device[PATH_MAX];
|
||||
int ret = get_root_partition_device(root_path, device);
|
||||
if (ret == 0)
|
||||
{
|
||||
fprintf(file, "/dev/block/mtdblock%d ", mtd->device_index);
|
||||
fprintf(file, "%s ", device);
|
||||
}
|
||||
else
|
||||
{
|
||||
MmcPartition *mmc = get_root_mmc_partition(root_path);
|
||||
if (mmc != NULL)
|
||||
{
|
||||
fprintf(file, "%s ", mmc->device_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "%s ", info->device);
|
||||
}
|
||||
fprintf(file, "%s ", info->device);
|
||||
}
|
||||
|
||||
fprintf(file, "%s ", info->mount_point);
|
||||
@ -950,7 +940,7 @@ void create_fstab()
|
||||
}
|
||||
write_fstab_root("CACHE:", file);
|
||||
write_fstab_root("DATA:", file);
|
||||
#ifdef HAS_DATADATA
|
||||
#ifdef BOARD_HAS_DATADATA
|
||||
write_fstab_root("DATADATA:", file);
|
||||
#endif
|
||||
write_fstab_root("SYSTEM:", file);
|
||||
|
@ -38,7 +38,7 @@ void
|
||||
show_advanced_menu();
|
||||
|
||||
int
|
||||
format_non_mtd_device(const char* root);
|
||||
format_unknown_device(const char* root);
|
||||
|
||||
void
|
||||
wipe_battery_stats();
|
||||
|
84
flashutils/Android.mk
Normal file
84
flashutils/Android.mk
Normal file
@ -0,0 +1,84 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
ifneq ($(TARGET_SIMULATOR),true)
|
||||
ifeq ($(TARGET_ARCH),arm)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := flash_image.c
|
||||
LOCAL_MODULE := flash_image
|
||||
LOCAL_MODULE_TAGS := eng
|
||||
LOCAL_STATIC_LIBRARIES := $(BOARD_FLASH_LIBRARY)
|
||||
LOCAL_SHARED_LIBRARIES := libcutils libc
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := dump_image.c
|
||||
LOCAL_MODULE := dump_image
|
||||
LOCAL_MODULE_TAGS := eng
|
||||
LOCAL_STATIC_LIBRARIES := $(BOARD_FLASH_LIBRARY)
|
||||
LOCAL_SHARED_LIBRARIES := libcutils libc
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := erase_image.c
|
||||
LOCAL_MODULE := erase_image
|
||||
LOCAL_MODULE_TAGS := eng
|
||||
LOCAL_STATIC_LIBRARIES := $(BOARD_FLASH_LIBRARY)
|
||||
LOCAL_SHARED_LIBRARIES := libcutils libc
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := flash_image.c
|
||||
LOCAL_MODULE := libflash_image
|
||||
LOCAL_CFLAGS += -Dmain=flash_image_main
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := dump_image.c
|
||||
LOCAL_MODULE := libdump_image
|
||||
LOCAL_CFLAGS += -Dmain=dump_image_main
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := erase_image.c
|
||||
LOCAL_MODULE := liberase_image
|
||||
LOCAL_CFLAGS += -Dmain=erase_image_main
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := dump_image.c
|
||||
LOCAL_MODULE := utility_dump_image
|
||||
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
|
||||
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_FORCE_STATIC_EXECUTABLE := true
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := flash_image.c
|
||||
LOCAL_MODULE := utility_flash_image
|
||||
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
|
||||
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_FORCE_STATIC_EXECUTABLE := true
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := erase_image.c
|
||||
LOCAL_MODULE := utility_erase_image
|
||||
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
|
||||
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_FORCE_STATIC_EXECUTABLE := true
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
|
||||
endif # TARGET_ARCH == arm
|
||||
endif # !TARGET_SIMULATOR
|
@ -23,13 +23,14 @@
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "cutils/log.h"
|
||||
#include "mtdutils.h"
|
||||
#include "dump_image.h"
|
||||
#include "flashutils.h"
|
||||
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
#define LOG_TAG "dump_image"
|
||||
|
||||
#define BLOCK_SIZE 2048
|
||||
@ -135,3 +136,15 @@ int main(int argc, char **argv)
|
||||
|
||||
return dump_image(argv[1], argv[2], NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: %s partition file.img\n", argv[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
return backup_raw_partition(argv[1], argv[2]);
|
||||
}
|
@ -23,15 +23,17 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
|
||||
#include "cutils/log.h"
|
||||
#include "mtdutils.h"
|
||||
#include "flashutils.h"
|
||||
|
||||
#if 0
|
||||
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#endif
|
||||
|
||||
|
||||
#define LOG_TAG "erase_image"
|
||||
|
||||
static int die(const char *msg, ...) {
|
||||
@ -86,3 +88,16 @@ int main(int argc, char **argv) {
|
||||
|
||||
return erase_image(argv[1]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s partition\n", argv[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
return erase_raw_partition(argv[1]);
|
||||
}
|
@ -22,8 +22,8 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cutils/log.h"
|
||||
#include "mtdutils.h"
|
||||
|
||||
#if 0
|
||||
#define LOG_TAG "flash_image"
|
||||
|
||||
#define HEADER_SIZE 2048 // size of header to compare for equality
|
||||
@ -138,3 +138,14 @@ int main(int argc, char **argv) {
|
||||
if (mtd_write_close(out)) die("error closing %s", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: %s partition file.img\n", argv[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
return restore_raw_partition(argv[1], argv[2]);
|
||||
}
|
6
flashutils/flashutils.h
Normal file
6
flashutils/flashutils.h
Normal file
@ -0,0 +1,6 @@
|
||||
int restore_raw_partition(const char *partition, const char *filename);
|
||||
int backup_raw_partition(const char *partition, const char *filename);
|
||||
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);
|
22
install.c
22
install.c
@ -28,7 +28,7 @@
|
||||
#include "minui/minui.h"
|
||||
#include "minzip/SysUtil.h"
|
||||
#include "minzip/Zip.h"
|
||||
#include "mtdutils/mounts.h"
|
||||
#include "mounts.h"
|
||||
#include "mtdutils/mtdutils.h"
|
||||
#include "roots.h"
|
||||
#include "verifier.h"
|
||||
@ -182,6 +182,9 @@ try_update_binary(const char *path, ZipArchive *zip) {
|
||||
}
|
||||
close(pipefd[1]);
|
||||
|
||||
char* firmware_type = NULL;
|
||||
char* firmware_filename = NULL;
|
||||
|
||||
char buffer[1024];
|
||||
FILE* from_child = fdopen(pipefd[0], "r");
|
||||
while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
|
||||
@ -201,6 +204,18 @@ try_update_binary(const char *path, ZipArchive *zip) {
|
||||
char* fraction_s = strtok(NULL, " \n");
|
||||
float fraction = strtof(fraction_s, NULL);
|
||||
ui_set_progress(fraction);
|
||||
} else if (strcmp(command, "firmware") == 0) {
|
||||
char* type = strtok(NULL, " \n");
|
||||
char* filename = strtok(NULL, " \n");
|
||||
|
||||
if (type != NULL && filename != NULL) {
|
||||
if (firmware_type != NULL) {
|
||||
LOGE("ignoring attempt to do multiple firmware updates");
|
||||
} else {
|
||||
firmware_type = strdup(type);
|
||||
firmware_filename = strdup(filename);
|
||||
}
|
||||
}
|
||||
} else if (strcmp(command, "ui_print") == 0) {
|
||||
char* str = strtok(NULL, "\n");
|
||||
if (str) {
|
||||
@ -221,6 +236,11 @@ try_update_binary(const char *path, ZipArchive *zip) {
|
||||
return INSTALL_ERROR;
|
||||
}
|
||||
|
||||
if (firmware_type != NULL) {
|
||||
return handle_firmware_update(firmware_type, firmware_filename, zip);
|
||||
} else {
|
||||
return INSTALL_SUCCESS;
|
||||
}
|
||||
return INSTALL_SUCCESS;
|
||||
}
|
||||
|
||||
|
3
legacy.c
3
legacy.c
@ -28,7 +28,6 @@
|
||||
#include "minui/minui.h"
|
||||
#include "minzip/SysUtil.h"
|
||||
#include "minzip/Zip.h"
|
||||
#include "mtdutils/mounts.h"
|
||||
#include "mtdutils/mtdutils.h"
|
||||
#include "roots.h"
|
||||
#include "verifier.h"
|
||||
@ -41,7 +40,7 @@
|
||||
#include "minui/minui.h"
|
||||
#include "minzip/SysUtil.h"
|
||||
#include "minzip/Zip.h"
|
||||
#include "mtdutils/mounts.h"
|
||||
#include "mounts.h"
|
||||
#include "mtdutils/mtdutils.h"
|
||||
#include "roots.h"
|
||||
#include "verifier.h"
|
||||
|
@ -47,6 +47,16 @@ char *ext3_partitions[] = {"system", "userdata", "cache", "NONE"};
|
||||
unsigned vfat_count = 0;
|
||||
char *vfat_partitions[] = {"modem", "NONE"};
|
||||
|
||||
struct MmcPartition {
|
||||
char *device_index;
|
||||
char *filesystem;
|
||||
char *name;
|
||||
unsigned dstatus;
|
||||
unsigned dtype ;
|
||||
unsigned dfirstsec;
|
||||
unsigned dsize;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
MmcPartition *partitions;
|
||||
int partitions_allocd;
|
||||
@ -408,6 +418,7 @@ ERROR3:
|
||||
}
|
||||
|
||||
|
||||
// TODO: refactor this to not be a giant copy paste mess
|
||||
int
|
||||
mmc_raw_dump (const MmcPartition *partition, char *out_file) {
|
||||
int ch;
|
||||
@ -459,3 +470,121 @@ ERROR3:
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mmc_raw_read (const MmcPartition *partition, char *data, int data_size) {
|
||||
int ch;
|
||||
FILE *in;
|
||||
int val = 0;
|
||||
char buf[512];
|
||||
unsigned sz = 0;
|
||||
unsigned i;
|
||||
int ret = -1;
|
||||
char *in_file = partition->device_index;
|
||||
|
||||
in = fopen ( in_file, "r" );
|
||||
if (in == NULL)
|
||||
goto ERROR3;
|
||||
|
||||
fseek(in, 0L, SEEK_END);
|
||||
sz = ftell(in);
|
||||
fseek(in, 0L, SEEK_SET);
|
||||
|
||||
fread(data, data_size, 1, in);
|
||||
|
||||
ret = 0;
|
||||
ERROR1:
|
||||
ERROR2:
|
||||
fclose ( in );
|
||||
ERROR3:
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
mmc_raw_write (const MmcPartition *partition, char *data, int data_size) {
|
||||
int ch;
|
||||
FILE *out;
|
||||
int val = 0;
|
||||
char buf[512];
|
||||
unsigned sz = 0;
|
||||
unsigned i;
|
||||
int ret = -1;
|
||||
char *out_file = partition->device_index;
|
||||
|
||||
out = fopen ( out_file, "w" );
|
||||
if (out == NULL)
|
||||
goto ERROR3;
|
||||
|
||||
fwrite(data, data_size, 1, out);
|
||||
|
||||
ret = 0;
|
||||
ERROR1:
|
||||
ERROR2:
|
||||
fclose ( out );
|
||||
ERROR3:
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int restore_raw_partition(const char *partition, const char *filename)
|
||||
{
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *p;
|
||||
p = mmc_find_partition_by_name(partition);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
return mmc_raw_copy(p, filename);
|
||||
}
|
||||
|
||||
int backup_raw_partition(const char *partition, const char *filename)
|
||||
{
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *p;
|
||||
p = mmc_find_partition_by_name(partition);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
return mmc_raw_dump(p, filename);
|
||||
}
|
||||
|
||||
int erase_raw_partition(const char *partition)
|
||||
{
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *p;
|
||||
p = mmc_find_partition_by_name(partition);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
|
||||
// TODO: implement raw wipe
|
||||
return 0;
|
||||
}
|
||||
|
||||
int erase_partition(const char *partition, const char *filesystem)
|
||||
{
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *p;
|
||||
p = mmc_find_partition_by_name(partition);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
return mmc_format_ext3 (p);
|
||||
}
|
||||
|
||||
int mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only)
|
||||
{
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *p;
|
||||
p = mmc_find_partition_by_name(partition);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
return mmc_mount_partition(p, mount_point, read_only);
|
||||
}
|
||||
|
||||
const char* get_partition_device(const char *partition)
|
||||
{
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *p;
|
||||
p = mmc_find_partition_by_name(partition);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
return p->device_index;
|
||||
}
|
||||
|
@ -71,15 +71,7 @@
|
||||
#define MMC_BOOT_TYPE 0x48
|
||||
#define MMC_EXT3_TYPE 0x83
|
||||
#define MMC_VFAT_TYPE 0xC
|
||||
typedef struct MmcPartition {
|
||||
char *device_index;
|
||||
char *filesystem;
|
||||
char *name;
|
||||
unsigned dstatus;
|
||||
unsigned dtype ;
|
||||
unsigned dfirstsec;
|
||||
unsigned dsize;
|
||||
} MmcPartition;
|
||||
typedef struct MmcPartition MmcPartition;
|
||||
|
||||
/* Functions */
|
||||
int mmc_scan_partitions();
|
||||
@ -88,7 +80,8 @@ int mmc_format_ext3 (MmcPartition *partition);
|
||||
int mmc_mount_partition(const MmcPartition *partition, const char *mount_point, \
|
||||
int read_only);
|
||||
int mmc_raw_copy (const MmcPartition *partition, char *in_file);
|
||||
int mmc_raw_dump (const MmcPartition *partition, char *out_file);
|
||||
int mmc_raw_read (const MmcPartition *partition, char *data, int data_size);
|
||||
int mmc_raw_write (const MmcPartition *partition, char *data, int data_size);
|
||||
|
||||
#endif // MMCUTILS_H_
|
||||
|
||||
|
@ -5,88 +5,12 @@ LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
mtdutils.c \
|
||||
mounts.c
|
||||
mtdutils.c
|
||||
|
||||
LOCAL_MODULE := libmtdutils
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := flash_image.c
|
||||
LOCAL_MODULE := flash_image
|
||||
LOCAL_MODULE_TAGS := eng
|
||||
LOCAL_STATIC_LIBRARIES := libmtdutils
|
||||
LOCAL_SHARED_LIBRARIES := libcutils libc
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := dump_image.c
|
||||
LOCAL_MODULE := dump_image
|
||||
LOCAL_MODULE_TAGS := eng
|
||||
LOCAL_STATIC_LIBRARIES := libmtdutils
|
||||
LOCAL_SHARED_LIBRARIES := libcutils libc
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := erase_image.c
|
||||
LOCAL_MODULE := erase_image
|
||||
LOCAL_MODULE_TAGS := eng
|
||||
LOCAL_STATIC_LIBRARIES := libmtdutils
|
||||
LOCAL_SHARED_LIBRARIES := libcutils libc
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := flash_image.c
|
||||
LOCAL_MODULE := libflash_image
|
||||
LOCAL_CFLAGS += -Dmain=flash_image_main
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := dump_image.c
|
||||
LOCAL_MODULE := libdump_image
|
||||
LOCAL_CFLAGS += -Dmain=dump_image_main
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := erase_image.c
|
||||
LOCAL_MODULE := liberase_image
|
||||
LOCAL_CFLAGS += -Dmain=erase_image_main
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := dump_image.c
|
||||
LOCAL_MODULE := utility_dump_image
|
||||
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
|
||||
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
|
||||
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
|
||||
LOCAL_MODULE_STEM := dump_image
|
||||
LOCAL_STATIC_LIBRARIES := libmtdutils libcutils libc
|
||||
LOCAL_FORCE_STATIC_EXECUTABLE := true
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := flash_image.c
|
||||
LOCAL_MODULE := utility_flash_image
|
||||
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
|
||||
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
|
||||
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
|
||||
LOCAL_MODULE_STEM := flash_image
|
||||
LOCAL_STATIC_LIBRARIES := libmtdutils libcutils libc
|
||||
LOCAL_FORCE_STATIC_EXECUTABLE := true
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := erase_image.c
|
||||
LOCAL_MODULE := utility_erase_image
|
||||
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
|
||||
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
|
||||
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
|
||||
LOCAL_MODULE_STEM := erase_image
|
||||
LOCAL_STATIC_LIBRARIES := libmtdutils libcutils libc
|
||||
LOCAL_FORCE_STATIC_EXECUTABLE := true
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
endif # TARGET_ARCH == arm
|
||||
endif # !TARGET_SIMULATOR
|
||||
|
@ -1,17 +0,0 @@
|
||||
#undef main
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (strstr(argv[0], "flash_image") != NULL)
|
||||
return flash_image_main(argc, argv);
|
||||
if (strstr(argv[0], "dump_image") != NULL)
|
||||
return dump_image_main(argc, argv);
|
||||
if (strstr(argv[0], "mkyaffs2image") != NULL)
|
||||
return mkyaffs2image_main(argc, argv);
|
||||
if (strstr(argv[0], "unyaffs") != NULL)
|
||||
return unyaffs_main(argc, argv);
|
||||
return 0;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#ifndef DUMP_IMAGE_H
|
||||
#define DUMP_IMAGE_H
|
||||
|
||||
typedef void (*dump_image_callback) (int partition_dumped, int partition_size);
|
||||
|
||||
int dump_image(char* partition_name, char* filename, dump_image_callback callback);
|
||||
|
||||
#endif
|
@ -557,3 +557,295 @@ off_t mtd_find_write_start(MtdWriteContext *ctx, off_t pos) {
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
#define BLOCK_SIZE 2048
|
||||
#define SPARE_SIZE (BLOCK_SIZE >> 5)
|
||||
#define HEADER_SIZE 2048
|
||||
|
||||
int restore_raw_partition(const char *partition_name, const char *filename)
|
||||
{
|
||||
const MtdPartition *ptn;
|
||||
MtdWriteContext *write;
|
||||
void *data;
|
||||
unsigned sz;
|
||||
|
||||
if (mtd_scan_partitions() <= 0)
|
||||
{
|
||||
printf("error scanning partitions");
|
||||
return -1;
|
||||
}
|
||||
const MtdPartition *partition = mtd_find_partition_by_name(partition_name);
|
||||
if (partition == NULL)
|
||||
{
|
||||
printf("can't find %s partition", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If the first part of the file matches the partition, skip writing
|
||||
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("error opening %s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char header[HEADER_SIZE];
|
||||
int headerlen = read(fd, header, sizeof(header));
|
||||
if (headerlen <= 0)
|
||||
{
|
||||
printf("error reading %s header", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
MtdReadContext *in = mtd_read_partition(partition);
|
||||
if (in == NULL) {
|
||||
printf("error opening %s: %s\n", partition, strerror(errno));
|
||||
// just assume it needs re-writing
|
||||
} else {
|
||||
char check[HEADER_SIZE];
|
||||
int checklen = mtd_read_data(in, check, sizeof(check));
|
||||
if (checklen <= 0) {
|
||||
printf("error reading %s: %s\n", partition_name, strerror(errno));
|
||||
// just assume it needs re-writing
|
||||
} else if (checklen == headerlen && !memcmp(header, check, headerlen)) {
|
||||
printf("header is the same, not flashing %s\n", partition_name);
|
||||
return 0;
|
||||
}
|
||||
mtd_read_close(in);
|
||||
}
|
||||
|
||||
// Skip the header (we'll come back to it), write everything else
|
||||
printf("flashing %s from %s\n", partition_name, filename);
|
||||
|
||||
MtdWriteContext *out = mtd_write_partition(partition);
|
||||
if (out == NULL)
|
||||
{
|
||||
printf("error writing %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buf[HEADER_SIZE];
|
||||
memset(buf, 0, headerlen);
|
||||
int wrote = mtd_write_data(out, buf, headerlen);
|
||||
if (wrote != headerlen)
|
||||
{
|
||||
printf("error writing %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int len;
|
||||
while ((len = read(fd, buf, sizeof(buf))) > 0) {
|
||||
wrote = mtd_write_data(out, buf, len);
|
||||
if (wrote != len)
|
||||
{
|
||||
printf("error writing %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (len < 0)
|
||||
{
|
||||
printf("error reading %s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mtd_write_close(out))
|
||||
{
|
||||
printf("error closing %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now come back and write the header last
|
||||
|
||||
out = mtd_write_partition(partition);
|
||||
if (out == NULL)
|
||||
{
|
||||
printf("error re-opening %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wrote = mtd_write_data(out, header, headerlen);
|
||||
if (wrote != headerlen)
|
||||
{
|
||||
printf("error re-writing %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Need to write a complete block, so write the rest of the first block
|
||||
size_t block_size;
|
||||
if (mtd_partition_info(partition, NULL, &block_size, NULL))
|
||||
{
|
||||
printf("error getting %s block size", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lseek(fd, headerlen, SEEK_SET) != headerlen)
|
||||
{
|
||||
printf("error rewinding %s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int left = block_size - headerlen;
|
||||
while (left < 0) left += block_size;
|
||||
while (left > 0) {
|
||||
len = read(fd, buf, left > (int)sizeof(buf) ? (int)sizeof(buf) : left);
|
||||
if (len <= 0){
|
||||
printf("error reading %s", filename);
|
||||
return -1;
|
||||
}
|
||||
if (mtd_write_data(out, buf, len) != len)
|
||||
{
|
||||
printf("error writing %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
left -= len;
|
||||
}
|
||||
|
||||
if (mtd_write_close(out))
|
||||
{
|
||||
printf("error closing %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int backup_raw_partition(const char *partition_name, const char *filename)
|
||||
{
|
||||
MtdReadContext *in;
|
||||
const MtdPartition *partition;
|
||||
char buf[BLOCK_SIZE + SPARE_SIZE];
|
||||
size_t partition_size;
|
||||
size_t read_size;
|
||||
size_t total;
|
||||
int fd;
|
||||
int wrote;
|
||||
int len;
|
||||
|
||||
if (mtd_scan_partitions() <= 0)
|
||||
{
|
||||
printf("error scanning partitions");
|
||||
return -1;
|
||||
}
|
||||
|
||||
partition = mtd_find_partition_by_name(partition_name);
|
||||
if (partition == NULL)
|
||||
{
|
||||
printf("can't find %s partition", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mtd_partition_info(partition, &partition_size, NULL, NULL)) {
|
||||
printf("can't get info of partition %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcmp(filename, "-")) {
|
||||
fd = fileno(stdout);
|
||||
}
|
||||
else {
|
||||
fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
||||
}
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("error opening %s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
in = mtd_read_partition(partition);
|
||||
if (in == NULL) {
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
printf("error opening %s: %s\n", partition_name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
while ((len = mtd_read_data(in, buf, BLOCK_SIZE)) > 0) {
|
||||
wrote = write(fd, buf, len);
|
||||
if (wrote != len) {
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
printf("error writing %s", filename);
|
||||
return -1;
|
||||
}
|
||||
total += BLOCK_SIZE;
|
||||
}
|
||||
|
||||
mtd_read_close(in);
|
||||
|
||||
if (close(fd)) {
|
||||
unlink(filename);
|
||||
printf("error closing %s", filename);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int erase_raw_partition(const char *partition_name)
|
||||
{
|
||||
MtdWriteContext *out;
|
||||
size_t erased;
|
||||
size_t total_size;
|
||||
size_t erase_size;
|
||||
|
||||
if (mtd_scan_partitions() <= 0)
|
||||
{
|
||||
printf("error scanning partitions");
|
||||
return -1;
|
||||
}
|
||||
const MtdPartition *p = mtd_find_partition_by_name(partition_name);
|
||||
if (p == NULL)
|
||||
{
|
||||
printf("can't find %s partition", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
out = mtd_write_partition(p);
|
||||
if (out == NULL)
|
||||
{
|
||||
printf("could not estabilish write context for %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// do the actual erase, -1 = full partition erase
|
||||
erased = mtd_erase_blocks(out, -1);
|
||||
|
||||
// erased = bytes erased, if zero, something borked
|
||||
if (!erased)
|
||||
{
|
||||
printf("error erasing %s", partition_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int erase_partition(const char *partition, const char *filesystem)
|
||||
{
|
||||
return erase_raw_partition(partition);
|
||||
}
|
||||
|
||||
|
||||
int mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only)
|
||||
{
|
||||
mtd_scan_partitions();
|
||||
const MtdPartition *p;
|
||||
p = mtd_find_partition_by_name(partition);
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return mtd_mount_partition(p, mount_point, filesystem, read_only);
|
||||
}
|
||||
|
||||
int get_partition_device(const char *partition, char *device)
|
||||
{
|
||||
mtd_scan_partitions();
|
||||
MtdPartition *p = mtd_find_partition_by_name(partition);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
sprintf(device, "/dev/block/mtdblock%d", p->device_index);
|
||||
return 0;
|
||||
}
|
||||
|
41
nandroid.c
41
nandroid.c
@ -33,8 +33,6 @@
|
||||
#include "commands.h"
|
||||
#include "amend/amend.h"
|
||||
|
||||
#include "mtdutils/dump_image.h"
|
||||
#include "mmcutils/mmcutils.h"
|
||||
#include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h"
|
||||
#include "../../external/yaffs2/yaffs2/utils/unyaffs.h"
|
||||
|
||||
@ -43,33 +41,6 @@
|
||||
#include "extendedcommands.h"
|
||||
#include "nandroid.h"
|
||||
|
||||
#ifdef BOARD_USES_BMLUTILS
|
||||
#elif BOARD_USES_MMCUTILS
|
||||
int write_raw_image(const char* partition, const char* filename) {
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *p;
|
||||
p = mmc_find_partition_by_name(partition);
|
||||
return mmc_raw_copy (p, filename);
|
||||
}
|
||||
|
||||
int read_raw_image(const char* partition, const char* filename) {
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *p;
|
||||
p = mmc_find_partition_by_name(partition);
|
||||
return mmc_raw_dump (p, filename);
|
||||
}
|
||||
#else
|
||||
int write_raw_image(const char* partition, const char* filename) {
|
||||
char tmp[PATH_MAX];
|
||||
sprintf(tmp, "flash_image boot %s", filename);
|
||||
return __system(tmp);
|
||||
}
|
||||
|
||||
int read_raw_image(const char* partition, const char* filename) {
|
||||
return dump_image(partition, filename, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
int print_and_error(char* message) {
|
||||
ui_print(message);
|
||||
return 1;
|
||||
@ -164,13 +135,13 @@ int nandroid_backup(const char* backup_path)
|
||||
#ifndef BOARD_RECOVERY_IGNORE_BOOTABLES
|
||||
ui_print("Backing up boot...\n");
|
||||
sprintf(tmp, "%s/%s", backup_path, "boot.img");
|
||||
ret = read_raw_image("boot", tmp);
|
||||
ret = backup_raw_partition("boot", tmp);
|
||||
if (0 != ret)
|
||||
return print_and_error("Error while dumping boot image!\n");
|
||||
|
||||
ui_print("Backing up recovery...\n");
|
||||
sprintf(tmp, "%s/%s", backup_path, "recovery.img");
|
||||
ret = read_raw_image("recovery", tmp);
|
||||
ret = backup_raw_partition("recovery", tmp);
|
||||
if (0 != ret)
|
||||
return print_and_error("Error while dumping recovery image!\n");
|
||||
#endif
|
||||
@ -181,7 +152,7 @@ int nandroid_backup(const char* backup_path)
|
||||
if (0 != (ret = nandroid_backup_partition(backup_path, "DATA:")))
|
||||
return ret;
|
||||
|
||||
#ifdef HAS_DATADATA
|
||||
#ifdef BOARD_HAS_DATADATA
|
||||
if (0 != (ret = nandroid_backup_partition(backup_path, "DATADATA:")))
|
||||
return ret;
|
||||
#endif
|
||||
@ -200,7 +171,7 @@ int nandroid_backup(const char* backup_path)
|
||||
if (0 != (ret = nandroid_backup_partition_extended(backup_path, "CACHE:", 0)))
|
||||
return ret;
|
||||
|
||||
if (0 != stat(SDEXT_DEVICE, &st))
|
||||
if (0 != stat(BOARD_SDEXT_DEVICE, &st))
|
||||
{
|
||||
ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
|
||||
}
|
||||
@ -313,7 +284,7 @@ int nandroid_restore(const char* backup_path, int restore_boot, int restore_syst
|
||||
return print_and_error("Error while formatting BOOT:!\n");
|
||||
sprintf(tmp, "%s/boot.img", backup_path);
|
||||
ui_print("Restoring boot image...\n");
|
||||
if (0 != (ret = write_raw_image("boot", tmp))) {
|
||||
if (0 != (ret = restore_raw_partition("boot", tmp))) {
|
||||
ui_print("Error while flashing boot image!");
|
||||
return ret;
|
||||
}
|
||||
@ -326,7 +297,7 @@ int nandroid_restore(const char* backup_path, int restore_boot, int restore_syst
|
||||
if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATA:")))
|
||||
return ret;
|
||||
|
||||
#ifdef HAS_DATADATA
|
||||
#ifdef BOARD_HAS_DATADATA
|
||||
if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATADATA:")))
|
||||
return ret;
|
||||
#endif
|
||||
|
@ -444,7 +444,7 @@ wipe_data(int confirm) {
|
||||
ui_print("\n-- Wiping data...\n");
|
||||
device_wipe_data();
|
||||
erase_root("DATA:");
|
||||
#ifdef HAS_DATADATA
|
||||
#ifdef BOARD_HAS_DATADATA
|
||||
erase_root("DATADATA:");
|
||||
#endif
|
||||
erase_root("CACHE:");
|
||||
|
155
roots.c
155
roots.c
@ -24,37 +24,35 @@
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "mtdutils/mtdutils.h"
|
||||
#include "mtdutils/mounts.h"
|
||||
#include "mmcutils/mmcutils.h"
|
||||
#include "flashutils/flashutils.h"
|
||||
#include "minzip/Zip.h"
|
||||
#include "roots.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "mounts.h"
|
||||
#include "extendedcommands.h"
|
||||
|
||||
/* Canonical pointers.
|
||||
xxx may just want to use enums
|
||||
*/
|
||||
static const char g_mtd_device[] = "@\0g_mtd_device";
|
||||
static const char g_mmc_device[] = "@\0g_mmc_device";
|
||||
static const char g_default_device[] = "@\0g_default_device";
|
||||
static const char g_raw[] = "@\0g_raw";
|
||||
static const char g_package_file[] = "@\0g_package_file";
|
||||
|
||||
static RootInfo g_roots[] = {
|
||||
{ "BOOT:", DEFAULT_DEVICE, NULL, "boot", NULL, g_raw, NULL },
|
||||
{ "CACHE:", CACHE_DEVICE, NULL, "cache", "/cache", CACHE_FILESYSTEM, CACHE_FILESYSTEM_OPTIONS },
|
||||
{ "DATA:", DATA_DEVICE, NULL, "userdata", "/data", DATA_FILESYSTEM, DATA_FILESYSTEM_OPTIONS },
|
||||
#ifdef HAS_DATADATA
|
||||
{ "DATADATA:", DATADATA_DEVICE, NULL, "datadata", "/datadata", DATADATA_FILESYSTEM, DATADATA_FILESYSTEM_OPTIONS },
|
||||
{ "BOOT:", g_default_device, NULL, "boot", NULL, g_raw, NULL },
|
||||
{ "CACHE:", BOARD_CACHE_DEVICE, NULL, "cache", "/cache", BOARD_CACHE_FILESYSTEM, BOARD_CACHE_FILESYSTEM_OPTIONS },
|
||||
{ "DATA:", BOARD_DATA_DEVICE, NULL, "userdata", "/data", BOARD_DATA_FILESYSTEM, BOARD_DATA_FILESYSTEM_OPTIONS },
|
||||
#ifdef BOARD_HAS_DATADATA
|
||||
{ "DATADATA:", BOARD_DATADATA_DEVICE, NULL, "datadata", "/datadata", BOARD_DATADATA_FILESYSTEM, BOARD_DATADATA_FILESYSTEM_OPTIONS },
|
||||
#endif
|
||||
{ "MISC:", DEFAULT_DEVICE, NULL, "misc", NULL, g_raw, NULL },
|
||||
{ "MISC:", g_default_device, NULL, "misc", NULL, g_raw, NULL },
|
||||
{ "PACKAGE:", NULL, NULL, NULL, NULL, g_package_file, NULL },
|
||||
{ "RECOVERY:", DEFAULT_DEVICE, NULL, "recovery", "/", g_raw, NULL },
|
||||
{ "SDCARD:", SDCARD_DEVICE_PRIMARY, SDCARD_DEVICE_SECONDARY, NULL, "/sdcard", "vfat", NULL },
|
||||
{ "SDEXT:", SDEXT_DEVICE, NULL, NULL, "/sd-ext", SDEXT_FILESYSTEM, NULL },
|
||||
{ "SYSTEM:", SYSTEM_DEVICE, NULL, "system", "/system", SYSTEM_FILESYSTEM, SYSTEM_FILESYSTEM_OPTIONS },
|
||||
{ "MBM:", DEFAULT_DEVICE, NULL, "mbm", NULL, g_raw, NULL },
|
||||
{ "RECOVERY:", g_default_device, NULL, "recovery", "/", g_raw, NULL },
|
||||
{ "SDCARD:", BOARD_SDCARD_DEVICE_PRIMARY, BOARD_SDCARD_DEVICE_SECONDARY, NULL, "/sdcard", "vfat", NULL },
|
||||
{ "SDEXT:", BOARD_SDEXT_DEVICE, NULL, NULL, "/sd-ext", BOARD_SDEXT_FILESYSTEM, NULL },
|
||||
{ "SYSTEM:", BOARD_SYSTEM_DEVICE, NULL, "system", "/system", BOARD_SYSTEM_FILESYSTEM, BOARD_SYSTEM_FILESYSTEM_OPTIONS },
|
||||
{ "MBM:", g_default_device, NULL, "mbm", NULL, g_raw, NULL },
|
||||
{ "TMP:", NULL, NULL, NULL, "/tmp", NULL, NULL },
|
||||
};
|
||||
#define NUM_ROOTS (sizeof(g_roots) / sizeof(g_roots[0]))
|
||||
@ -240,35 +238,6 @@ ensure_root_path_mounted(const char *root_path)
|
||||
|
||||
/* It's not mounted.
|
||||
*/
|
||||
if (info->device == g_mtd_device) {
|
||||
if (info->partition_name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
//TODO: make the mtd stuff scan once when it needs to
|
||||
mtd_scan_partitions();
|
||||
const MtdPartition *partition;
|
||||
partition = mtd_find_partition_by_name(info->partition_name);
|
||||
if (partition == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return mtd_mount_partition(partition, info->mount_point,
|
||||
info->filesystem, 0);
|
||||
}
|
||||
|
||||
if (info->device == g_mmc_device) {
|
||||
if (info->partition_name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
//TODO: make the mtd stuff scan once when it needs to
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *partition;
|
||||
partition = mmc_find_partition_by_name(info->partition_name);
|
||||
if (partition == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return mmc_mount_partition(partition, info->mount_point, 0);
|
||||
}
|
||||
|
||||
if (info->device == NULL || info->mount_point == NULL ||
|
||||
info->filesystem == NULL ||
|
||||
info->filesystem == g_raw ||
|
||||
@ -276,6 +245,13 @@ ensure_root_path_mounted(const char *root_path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (info->device == g_default_device) {
|
||||
if (info->partition_name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return mount_partition(info->partition_name, info->mount_point, info->filesystem, 0);
|
||||
}
|
||||
|
||||
mkdir(info->mount_point, 0755); // in case it doesn't already exist
|
||||
if (mount_internal(info->device, info->mount_point, info->filesystem, info->filesystem_options)) {
|
||||
if (info->device2 == NULL) {
|
||||
@ -322,11 +298,24 @@ ensure_root_path_unmounted(const char *root_path)
|
||||
return unmount_mounted_volume(volume);
|
||||
}
|
||||
|
||||
int
|
||||
get_root_partition_device(const char *root_path, char *device)
|
||||
{
|
||||
const RootInfo *info = get_root_info_for_path(root_path);
|
||||
if (info == NULL || info->device != g_default_device ||
|
||||
info->partition_name == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return get_partition_device(info->partition_name, device);
|
||||
}
|
||||
|
||||
#ifndef BOARD_HAS_NO_MISC_PARTITION
|
||||
const MtdPartition *
|
||||
get_root_mtd_partition(const char *root_path)
|
||||
{
|
||||
const RootInfo *info = get_root_info_for_path(root_path);
|
||||
if (info == NULL || info->device != g_mtd_device ||
|
||||
if (info == NULL || info->device != g_default_device ||
|
||||
info->partition_name == NULL)
|
||||
{
|
||||
#ifdef BOARD_HAS_MTD_CACHE
|
||||
@ -339,19 +328,7 @@ get_root_mtd_partition(const char *root_path)
|
||||
mtd_scan_partitions();
|
||||
return mtd_find_partition_by_name(info->partition_name);
|
||||
}
|
||||
|
||||
const MmcPartition *
|
||||
get_root_mmc_partition(const char *root_path)
|
||||
{
|
||||
const RootInfo *info = get_root_info_for_path(root_path);
|
||||
if (info == NULL || info->device != g_mmc_device ||
|
||||
info->partition_name == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
mmc_scan_partitions();
|
||||
return mmc_find_partition_by_name(info->partition_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
format_root_device(const char *root)
|
||||
@ -375,7 +352,8 @@ format_root_device(const char *root)
|
||||
LOGW("format_root_device: can't resolve \"%s\"\n", root);
|
||||
return -1;
|
||||
}
|
||||
if (info->mount_point != NULL && (info->device == g_mtd_device || info->device == g_mmc_device)) {
|
||||
|
||||
if (info->mount_point != NULL && info->device == g_default_device) {
|
||||
/* Don't try to format a mounted device.
|
||||
*/
|
||||
int ret = ensure_root_path_unmounted(root);
|
||||
@ -387,52 +365,17 @@ format_root_device(const char *root)
|
||||
|
||||
/* Format the device.
|
||||
*/
|
||||
if (info->device == g_mtd_device) {
|
||||
mtd_scan_partitions();
|
||||
const MtdPartition *partition;
|
||||
partition = mtd_find_partition_by_name(info->partition_name);
|
||||
if (partition == NULL) {
|
||||
LOGW("format_root_device: can't find mtd partition \"%s\"\n",
|
||||
info->partition_name);
|
||||
return -1;
|
||||
}
|
||||
if (info->filesystem == g_raw || !strcmp(info->filesystem, "yaffs2")) {
|
||||
MtdWriteContext *write = mtd_write_partition(partition);
|
||||
if (write == NULL) {
|
||||
LOGW("format_root_device: can't open \"%s\"\n", root);
|
||||
return -1;
|
||||
} else if (mtd_erase_blocks(write, -1) == (off_t) -1) {
|
||||
LOGW("format_root_device: can't erase \"%s\"\n", root);
|
||||
mtd_write_close(write);
|
||||
return -1;
|
||||
} else if (mtd_write_close(write)) {
|
||||
LOGW("format_root_device: can't close \"%s\"\n", root);
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (info->device == g_default_device) {
|
||||
int ret = 0;
|
||||
if (info->filesystem == g_raw)
|
||||
ret = erase_raw_partition(info->partition_name);
|
||||
else
|
||||
ret = erase_partition(info->partition_name, info->filesystem);
|
||||
|
||||
if (ret != 0)
|
||||
LOGE("Error erasing device %s\n", info->device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Handle MMC device types
|
||||
if(info->device == g_mmc_device) {
|
||||
mmc_scan_partitions();
|
||||
const MmcPartition *partition;
|
||||
partition = mmc_find_partition_by_name(info->partition_name);
|
||||
if (partition == NULL) {
|
||||
LOGE("format_root_device: can't find mmc partition \"%s\"\n",
|
||||
info->partition_name);
|
||||
return -1;
|
||||
}
|
||||
if (!strcmp(info->filesystem, "ext3")) {
|
||||
if(0 == mmc_format_ext3(partition))
|
||||
return 0;
|
||||
LOGE("\n\"%s\" wipe failed!\n", info->partition_name);
|
||||
return -1;
|
||||
}
|
||||
LOGW("\n\"%s\" wipe skipped!\n", info->partition_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return format_non_mtd_device(root);
|
||||
return format_unknown_device(root);
|
||||
}
|
||||
|
68
roots.h
68
roots.h
@ -23,75 +23,73 @@
|
||||
#include "mmcutils/mmcutils.h"
|
||||
|
||||
#ifndef BOARD_USES_MMCUTILS
|
||||
#define DEFAULT_DEVICE g_mtd_device
|
||||
#define DEFAULT_FILESYSTEM "yaffs2"
|
||||
#else
|
||||
#define DEFAULT_DEVICE g_mmc_device
|
||||
#define DEFAULT_FILESYSTEM "ext3"
|
||||
#endif
|
||||
|
||||
#ifndef SDCARD_DEVICE_PRIMARY
|
||||
#define SDCARD_DEVICE_PRIMARY "/dev/block/mmcblk0p1"
|
||||
#ifndef BOARD_SDCARD_DEVICE_PRIMARY
|
||||
#define BOARD_SDCARD_DEVICE_PRIMARY "/dev/block/mmcblk0p1"
|
||||
#endif
|
||||
|
||||
#ifndef SDCARD_DEVICE_SECONDARY
|
||||
#define SDCARD_DEVICE_SECONDARY "/dev/block/mmcblk0"
|
||||
#ifndef BOARD_SDCARD_DEVICE_SECONDARY
|
||||
#define BOARD_SDCARD_DEVICE_SECONDARY "/dev/block/mmcblk0"
|
||||
#endif
|
||||
|
||||
#ifndef SDEXT_DEVICE
|
||||
#define SDEXT_DEVICE "/dev/block/mmcblk0p2"
|
||||
#ifndef BOARD_SDEXT_DEVICE
|
||||
#define BOARD_SDEXT_DEVICE "/dev/block/mmcblk0p2"
|
||||
#endif
|
||||
|
||||
#ifndef SDEXT_FILESYSTEM
|
||||
#define SDEXT_FILESYSTEM "auto"
|
||||
#ifndef BOARD_SDEXT_FILESYSTEM
|
||||
#define BOARD_SDEXT_FILESYSTEM "auto"
|
||||
#endif
|
||||
|
||||
#ifndef DATA_DEVICE
|
||||
#define DATA_DEVICE DEFAULT_DEVICE
|
||||
#ifndef BOARD_DATA_DEVICE
|
||||
#define BOARD_DATA_DEVICE g_default_device
|
||||
#endif
|
||||
|
||||
#ifndef DATA_FILESYSTEM
|
||||
#define DATA_FILESYSTEM DEFAULT_FILESYSTEM
|
||||
#ifndef BOARD_DATA_FILESYSTEM
|
||||
#define BOARD_DATA_FILESYSTEM DEFAULT_FILESYSTEM
|
||||
#endif
|
||||
|
||||
#ifndef DATADATA_DEVICE
|
||||
#define DATADATA_DEVICE DEFAULT_DEVICE
|
||||
#ifndef BOARD_DATADATA_DEVICE
|
||||
#define BOARD_DATADATA_DEVICE g_default_device
|
||||
#endif
|
||||
|
||||
#ifndef DATADATA_FILESYSTEM
|
||||
#define DATADATA_FILESYSTEM DEFAULT_FILESYSTEM
|
||||
#ifndef BOARD_DATADATA_FILESYSTEM
|
||||
#define BOARD_DATADATA_FILESYSTEM DEFAULT_FILESYSTEM
|
||||
#endif
|
||||
|
||||
#ifndef CACHE_DEVICE
|
||||
#define CACHE_DEVICE DEFAULT_DEVICE
|
||||
#ifndef BOARD_CACHE_DEVICE
|
||||
#define BOARD_CACHE_DEVICE g_default_device
|
||||
#endif
|
||||
|
||||
#ifndef CACHE_FILESYSTEM
|
||||
#define CACHE_FILESYSTEM DEFAULT_FILESYSTEM
|
||||
#ifndef BOARD_CACHE_FILESYSTEM
|
||||
#define BOARD_CACHE_FILESYSTEM DEFAULT_FILESYSTEM
|
||||
#endif
|
||||
|
||||
#ifndef SYSTEM_DEVICE
|
||||
#define SYSTEM_DEVICE DEFAULT_DEVICE
|
||||
#ifndef BOARD_SYSTEM_DEVICE
|
||||
#define BOARD_SYSTEM_DEVICE g_default_device
|
||||
#endif
|
||||
|
||||
#ifndef SYSTEM_FILESYSTEM
|
||||
#define SYSTEM_FILESYSTEM DEFAULT_FILESYSTEM
|
||||
#ifndef BOARD_SYSTEM_FILESYSTEM
|
||||
#define BOARD_SYSTEM_FILESYSTEM DEFAULT_FILESYSTEM
|
||||
#endif
|
||||
|
||||
#ifndef DATA_FILESYSTEM_OPTIONS
|
||||
#define DATA_FILESYSTEM_OPTIONS NULL
|
||||
#ifndef BOARD_DATA_FILESYSTEM_OPTIONS
|
||||
#define BOARD_DATA_FILESYSTEM_OPTIONS NULL
|
||||
#endif
|
||||
|
||||
#ifndef CACHE_FILESYSTEM_OPTIONS
|
||||
#define CACHE_FILESYSTEM_OPTIONS NULL
|
||||
#ifndef BOARD_CACHE_FILESYSTEM_OPTIONS
|
||||
#define BOARD_CACHE_FILESYSTEM_OPTIONS NULL
|
||||
#endif
|
||||
|
||||
#ifndef DATADATA_FILESYSTEM_OPTIONS
|
||||
#define DATADATA_FILESYSTEM_OPTIONS NULL
|
||||
#ifndef BOARD_DATADATA_FILESYSTEM_OPTIONS
|
||||
#define BOARD_DATADATA_FILESYSTEM_OPTIONS NULL
|
||||
#endif
|
||||
|
||||
#ifndef SYSTEM_FILESYSTEM_OPTIONS
|
||||
#define SYSTEM_FILESYSTEM_OPTIONS NULL
|
||||
#ifndef BOARD_SYSTEM_FILESYSTEM_OPTIONS
|
||||
#define BOARD_SYSTEM_FILESYSTEM_OPTIONS NULL
|
||||
#endif
|
||||
|
||||
|
||||
@ -129,7 +127,7 @@ int ensure_root_path_mounted(const char *root_path);
|
||||
int ensure_root_path_unmounted(const char *root_path);
|
||||
|
||||
const MtdPartition *get_root_mtd_partition(const char *root_path);
|
||||
const MmcPartition *get_root_mmc_partition(const char *root_path);
|
||||
int get_root_partition_device(const char *root_path, char *device);
|
||||
|
||||
/* "root" must be the exact name of the root; no relative path is permitted.
|
||||
* If the named root is mounted, this will attempt to unmount it first.
|
||||
|
@ -660,8 +660,6 @@ static bool write_raw_image_cb(const unsigned char* data,
|
||||
return false;
|
||||
}
|
||||
|
||||
int write_raw_image(const char* partition, const char* filename);
|
||||
|
||||
// write_raw_image(file, partition)
|
||||
Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) {
|
||||
char* result = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user