summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--recovery/Android.mk1
-rw-r--r--recovery/miniui/Android.mk19
-rw-r--r--recovery/miniui/msm_recovery_ui.cpp56
-rw-r--r--recovery/oem-recovery/Android.mk12
-rw-r--r--recovery/oem-recovery/dec.cpp401
-rw-r--r--recovery/oem-recovery/dec.h33
-rw-r--r--recovery/oem-recovery/gpt-utils.cpp782
-rw-r--r--recovery/oem-recovery/gpt-utils.h56
-rw-r--r--recovery/oem-recovery/oem-updater.cpp89
-rwxr-xr-xreleasetools.py382
10 files changed, 0 insertions, 1831 deletions
diff --git a/recovery/Android.mk b/recovery/Android.mk
deleted file mode 100644
index 6571161..0000000
--- a/recovery/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(all-subdir-makefiles)
diff --git a/recovery/miniui/Android.mk b/recovery/miniui/Android.mk
deleted file mode 100644
index 8754add..0000000
--- a/recovery/miniui/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-ifeq ($(TARGET_RECOVERY_UI_LIB),librecovery_ui_msm)
-ifneq ($(TARGET_SIMULATOR),true)
-ifneq ($(filter arm arm64, $(TARGET_ARCH)),)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := librecovery_ui_msm
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_C_INCLUDES += $(call project-path-for,recovery)
-
-LOCAL_SRC_FILES += msm_recovery_ui.cpp
-
-include $(BUILD_STATIC_LIBRARY)
-endif # TARGET_ARCH == arm
-endif # !TARGET_SIMULATOR
-endif
diff --git a/recovery/miniui/msm_recovery_ui.cpp b/recovery/miniui/msm_recovery_ui.cpp
deleted file mode 100644
index 8f29050..0000000
--- a/recovery/miniui/msm_recovery_ui.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- Copyright (c) 2015, The Linux Foundation. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "device.h"
-#include "screen_ui.h"
-
-
-class MSM_Device : public Device
-{
-public:
- MSM_Device(ScreenRecoveryUI* ui) : Device(ui) {}
-
- bool PostWipeDevice() {
- clear_keys_required = true;
- return true;
- }
-
- char const* GetRebootReason() {
- if (clear_keys_required)
- return "keys clear";
- return "";
- }
-
-private:
- bool clear_keys_required = false;
-};
-
-Device* make_device() {
- return new MSM_Device(new ScreenRecoveryUI);
-}
diff --git a/recovery/oem-recovery/Android.mk b/recovery/oem-recovery/Android.mk
deleted file mode 100644
index 033ac82..0000000
--- a/recovery/oem-recovery/Android.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-ifneq ($(filter librecovery_updater_msm,$(TARGET_RECOVERY_UPDATER_LIBS)),)
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := optional
-LOCAL_C_INCLUDES := $(call project-path-for,recovery) \
- system/core/libsparse \
- $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_SRC_FILES := gpt-utils.cpp dec.cpp oem-updater.cpp
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-LOCAL_MODULE := librecovery_updater_msm
-include $(BUILD_STATIC_LIBRARY)
-endif
diff --git a/recovery/oem-recovery/dec.cpp b/recovery/oem-recovery/dec.cpp
deleted file mode 100644
index a8b1d2c..0000000
--- a/recovery/oem-recovery/dec.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <linux/qseecom.h>
-#include <linux/msm_ion.h>
-
-/* Service IDs */
-#define SCM_SVC_SSD 0x07
-
-/* Service specific command IDs */
-#define SSD_PARSE_MD_ID 0x06
-#define SSD_DECRYPT_IMG_FRAG_ID 0x07
-
-/* SSD parsing status messages from TZ */
-#define SSD_PMD_ENCRYPTED 0
-#define SSD_PMD_NOT_ENCRYPTED 1
-#define SSD_PMD_PARSING_INCOMPLETE 6
-
-#define SSD_HEADER_MIN_SIZE 128
-#define MULTIPLICATION_FACTOR 2
-
-#define SMCMOD_DECRYPT_REQ_OP_METADATA 1
-#define SMCMOD_DECRYPT_REQ_OP_IMG_FRAG 2
-
-struct smcmod_decrypt_req {
- uint32_t service_id; /* in */
- uint32_t command_id; /* in */
- uint32_t operation; /* in */
-
- union {
- struct {
- uint32_t len;
- uint32_t ion_fd;
- } metadata;
- struct {
- uint32_t ctx_id;
- uint32_t last_frag;
- uint32_t frag_len;
- uint32_t ion_fd;
- uint32_t offset;
- } img_frag;
- } request;
-
- union {
- struct {
- uint32_t status;
- uint32_t ctx_id;
- uint32_t end_offset;
- } metadata;
- struct {
- uint32_t status;
- } img_frag;
- } response;
-};
-
-#define SMCMOD_IOC_MAGIC 0x97
-#define SMCMOD_IOCTL_DECRYPT_CMD \
- _IOWR(SMCMOD_IOC_MAGIC, 37, struct smcmod_decrypt_req)
-
-struct ion_buf_handle {
- unsigned char *buffer;
- uint32_t buffer_len;
- int ion_fd;
- int ifd_data_fd;
- struct ion_handle_data ion_alloc_handle;
-};
-
-static int
-ion_memalloc(struct ion_buf_handle *buf, uint32_t size, uint32_t heap)
-{
- struct ion_allocation_data alloc_data;
- struct ion_fd_data fd_data;
- unsigned char *va;
- struct ion_handle_data handle_data;
- int ion_fd;
- int rc;
-
- ion_fd = open("/dev/ion", O_RDONLY);
- if (ion_fd < 0) {
- fprintf(stderr, "Cannot open ION device (%s)\n", strerror(errno));
- return -1;
- }
-
- alloc_data.len = (size + 4095) & ~4095;
- alloc_data.align = 4096;
-
- alloc_data.flags = 0;
- alloc_data.heap_id_mask = ION_HEAP(heap);
-
- /* Set the buffers to be uncached */
- alloc_data.flags = 0;
-
- rc = ioctl(ion_fd, ION_IOC_ALLOC, &alloc_data);
- if (rc) {
- fprintf(stderr, "ION buffer allocation failed (%s)\n",
- strerror(errno));
- goto alloc_fail;
- }
-
- if (alloc_data.handle) {
- fd_data.handle = alloc_data.handle;
- } else {
- fprintf(stderr, "ION alloc data returned NULL\n");
- rc = -1;
- goto alloc_fail;
- }
-
- rc = ioctl(ion_fd, ION_IOC_MAP, &fd_data);
- if (rc) {
- fprintf(stderr, "ION map call failed(%s)\n", strerror(errno));
- goto ioctl_fail;
- }
-
- va = (unsigned char*)mmap(NULL, alloc_data.len, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd_data.fd, 0);
- if (va == MAP_FAILED) {
- fprintf(stderr, "ION memory map failed (%s)\n", strerror(errno));
- rc = -1;
- goto map_fail;
- }
-
- buf->ion_fd = ion_fd;
- buf->ifd_data_fd = fd_data.fd;
- buf->buffer = va;
- buf->ion_alloc_handle.handle = alloc_data.handle;
- buf->buffer_len = alloc_data.len;
-
- memset(buf->buffer, 0, buf->buffer_len);
- return 0;
-
-map_fail:
-ioctl_fail:
- handle_data.handle = alloc_data.handle;
- if (buf->ifd_data_fd)
- close(buf->ifd_data_fd);
- rc = ioctl(ion_fd, ION_IOC_FREE, &handle_data);
- if (rc)
- fprintf(stderr, "ION free failed (%s)\n", strerror(errno));
-alloc_fail:
- if (ion_fd >= 0)
- close(ion_fd);
- buf->ion_fd = -1;
- return rc;
-}
-
-static int ion_memfree(struct ion_buf_handle *handle)
-{
- struct ion_handle_data handle_data;
- int ret;
-
- ret = munmap(handle->buffer, (handle->buffer_len + 4095) & ~4095);
- if (ret)
- fprintf(stderr, "munmap failed (%s)\n", strerror(errno));
-
- handle_data.handle = handle->ion_alloc_handle.handle;
- close(handle->ifd_data_fd);
- ret = ioctl(handle->ion_fd, ION_IOC_FREE, &handle_data);
- if (ret)
- fprintf(stderr, "ION free failed (%s)\n", strerror(errno));
- close(handle->ion_fd);
-
- return ret;
-}
-
-static int ion_buffer_clean_inval(struct ion_buf_handle *buf, uint32_t cmd)
-{
- struct ion_flush_data data;
- int rc;
-
- data.fd = buf->ifd_data_fd;
- data.vaddr = buf->buffer;
- data.length = buf->buffer_len;
- data.offset = 0;
- data.handle = buf->ion_alloc_handle.handle;
-
- rc = ioctl(buf->ion_fd, cmd, &data);
- if (rc < 0)
- fprintf(stderr, "clean_inval cache failed (%s)\n", strerror(errno));
-
- return rc;
-}
-
-static int is_encrypted(int smcmod_fd, struct ion_buf_handle *buf,
- uint32_t len, uint32_t *ctx_id, uint32_t *end_offset)
-{
- struct smcmod_decrypt_req req;
- uint32_t status;
- int ret;
-
- req.service_id = SCM_SVC_SSD;
- req.command_id = SSD_PARSE_MD_ID;
- req.operation = SMCMOD_DECRYPT_REQ_OP_METADATA;
- req.request.metadata.len =
- (len >= SSD_HEADER_MIN_SIZE) ? SSD_HEADER_MIN_SIZE : len;
- req.request.metadata.ion_fd = buf->ifd_data_fd;
-
- do {
- ret = ioctl(smcmod_fd, SMCMOD_IOCTL_DECRYPT_CMD, &req);
- if (ret < 0)
- fprintf(stderr, "%s: ioctl ret=%d, %s\n", __func__, ret,
- strerror(errno));
-
- status = req.response.metadata.status;
-
- if (!ret && (status == SSD_PMD_PARSING_INCOMPLETE)) {
- req.request.metadata.len *= MULTIPLICATION_FACTOR;
- continue;
- } else {
- break;
- }
- } while (1);
-
- if (!ret) {
- if (status == SSD_PMD_ENCRYPTED) {
- *ctx_id = req.response.metadata.ctx_id;
- *end_offset = req.response.metadata.end_offset;
- ret = 1;
- } else {
- fprintf(stderr, "Image is not encrypted (response status %d)\n",
- status);
- }
- } else {
- fprintf(stderr, "%s: call failed\n", __func__);
- }
-
- return ret;
-}
-
-static int decrypt(int smcmod_fd, struct ion_buf_handle *buf, uint32_t len,
- uint32_t md_ctx, uint32_t offset)
-{
- struct smcmod_decrypt_req req;
- int ret;
-
- req.service_id = SCM_SVC_SSD;
- req.command_id = SSD_DECRYPT_IMG_FRAG_ID;
- req.operation = SMCMOD_DECRYPT_REQ_OP_IMG_FRAG;
- req.request.img_frag.ctx_id = md_ctx;
- req.request.img_frag.last_frag = 1;
- req.request.img_frag.ion_fd = buf->ifd_data_fd;
- req.request.img_frag.frag_len = len - offset;
- req.request.img_frag.offset = offset;
-
- ret = ioctl(smcmod_fd, SMCMOD_IOCTL_DECRYPT_CMD, &req);
- if (ret < 0) {
- fprintf(stderr, "decrypt ioctl failed (%s)\n", strerror(errno));
- return ret;
- }
-
- return 0;
-}
-
-static int save_file(const char *fname, unsigned char *buf, size_t len)
-{
- FILE *file;
- size_t written;
-
- file = fopen(fname, "wb");
- if (!file) {
- fprintf(stderr, "Failed to open %s (%s)\n", fname, strerror(errno));
- return -errno;
- }
-
- written = fwrite(buf, len, 1, file);
- if (written != 1) {
- fclose(file);
- fprintf(stderr, "Failed to write %s (%s)\n", fname, strerror(errno));
- return -errno;
- }
- fflush(file);
- fclose(file);
- fprintf(stdout, "%s written %d bytes\n", fname, len);
- return 0;
-}
-
-int decrypt_image(const char *src_file, const char *dst_file)
-{
- int ret = -1;
- uint32_t md_ctx = 0, offset = 0;
- uint32_t fsize = 0;
- FILE *file = NULL;
- struct ion_buf_handle ionbuf;
- int smcmod_fd = -1;
- int qseecom_fd = -1;
- size_t read;
-
- memset(&ionbuf, 0, sizeof(ionbuf));
- ionbuf.ion_fd = -1;
-
- qseecom_fd = open("/dev/qseecom", O_RDWR);
- if (qseecom_fd < 0) {
- fprintf(stderr, "Failed to open /dev/qseecom device (%s)\n",
- strerror(errno));
- goto exit;
- }
-
- smcmod_fd = open("/dev/smcmod", O_RDWR);
- if (smcmod_fd < 0) {
- fprintf(stderr, "Failed to open /dev/smcmod device (%s)\n",
- strerror(errno));
- goto exit;
- }
-
- file = fopen(src_file, "rb");
- if (!file) {
- fprintf(stderr, "Failed to open %s (%s)\n", src_file, strerror(errno));
- goto exit;
- }
-
- fseek(file, 0, SEEK_END);
- fsize = ftell(file);
- fseek(file, 0, SEEK_SET);
-
- ret = ion_memalloc(&ionbuf, fsize, ION_PIL1_HEAP_ID);
- if (ret)
- goto exit;
-
- read = fread(ionbuf.buffer, fsize, 1, file);
- if (read != 1) {
- fprintf(stderr, "Failed to read %s (%s)\n", src_file, strerror(errno));
- ret = -errno;
- goto exit;
- }
-
- ret = ion_buffer_clean_inval(&ionbuf, ION_IOC_CLEAN_INV_CACHES);
- if (ret < 0)
- goto exit;
-
- ret = ioctl(qseecom_fd, QSEECOM_IOCTL_PERF_ENABLE_REQ);
- if (ret < 0)
- goto exit;
-
- ret = is_encrypted(smcmod_fd, &ionbuf, fsize, &md_ctx, &offset);
- if (ret < 0)
- goto exit;
-
- if (ret == 1) {
- fprintf(stdout, "decrypting %s ...\n", src_file);
- ret = decrypt(smcmod_fd, &ionbuf, fsize, md_ctx, offset);
- if (ret < 0)
- goto exit;
-
- ion_buffer_clean_inval(&ionbuf, ION_IOC_INV_CACHES);
-
- ret = save_file(dst_file, ionbuf.buffer + offset, fsize - offset);
- if (ret < 0)
- goto exit;
-
- fprintf(stdout, "decrypting done!\n");
- }
-
-exit:
- if (ionbuf.ion_fd >= 0)
- ion_memfree(&ionbuf);
-
- if (qseecom_fd >= 0) {
- ioctl(qseecom_fd, QSEECOM_IOCTL_PERF_DISABLE_REQ);
- close(qseecom_fd);
- }
-
- if (smcmod_fd >= 0)
- close(smcmod_fd);
-
- if (file)
- fclose(file);
-
- return ret;
-}
diff --git a/recovery/oem-recovery/dec.h b/recovery/oem-recovery/dec.h
deleted file mode 100644
index b08f5b2..0000000
--- a/recovery/oem-recovery/dec.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __DEC_H__
-#define __DEC_H__
-int decrypt_image(const char *src_file, const char *dst_file);
-#endif
diff --git a/recovery/oem-recovery/gpt-utils.cpp b/recovery/oem-recovery/gpt-utils.cpp
deleted file mode 100644
index a62f54e..0000000
--- a/recovery/oem-recovery/gpt-utils.cpp
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define _LARGEFILE64_SOURCE /* enable lseek64() */
-
-/******************************************************************************
- * INCLUDE SECTION
- ******************************************************************************/
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <linux/fs.h>
-#include "gpt-utils.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "sparse_crc32.h"
-#ifdef __cplusplus
-}
-#endif
-
-
-/******************************************************************************
- * DEFINE SECTION
- ******************************************************************************/
-#define BLK_DEV_FILE "/dev/block/mmcblk0"
-#define UFS_DEV_DIR "/dev/block/sda"
-#define BOOT_DEV_DIR "/dev/block/bootdevice/by-name"
-/* list the names of the backed-up partitions to be swapped */
-#define PTN_SWAP_LIST "sbl1", "rpm", "tz", "aboot", "hyp", "lksecapp", "keymaster", "cmnlib", "cmnlib64", "pmic"
-/* extension used for the backup partitions - tzbak, abootbak, etc. */
-#define BAK_PTN_NAME_EXT "bak"
-
-/* GPT defines */
-#define GPT_SIGNATURE "EFI PART"
-#define HEADER_SIZE_OFFSET 12
-#define HEADER_CRC_OFFSET 16
-#define PRIMARY_HEADER_OFFSET 24
-#define BACKUP_HEADER_OFFSET 32
-#define FIRST_USABLE_LBA_OFFSET 40
-#define LAST_USABLE_LBA_OFFSET 48
-#define PENTRIES_OFFSET 72
-#define PARTITION_COUNT_OFFSET 80
-#define PENTRY_SIZE_OFFSET 84
-#define PARTITION_CRC_OFFSET 88
-
-#define TYPE_GUID_OFFSET 0
-#define TYPE_GUID_SIZE 16
-#define PTN_ENTRY_SIZE 128
-#define UNIQUE_GUID_OFFSET 16
-#define FIRST_LBA_OFFSET 32
-#define LAST_LBA_OFFSET 40
-#define ATTRIBUTE_FLAG_OFFSET 48
-#define PARTITION_NAME_OFFSET 56
-
-#define MAX_GPT_NAME_SIZE 72
-#define MAX_PATH_LEN 255
-#define MAX_LUNS 26
-//This will allow us to get the root lun path from the path to the partition.
-//i.e: from /dev/block/sdaXXX get /dev/block/sda. The assumption here is that
-//the boot critical luns lie between sda to sdz which is acceptable because
-//only user added external disks,etc would lie beyond that limit which do not
-//contain partitions that interest us here.
-#define PATH_TRUNCATE_LOC 14
-
-/******************************************************************************
- * MACROS
- ******************************************************************************/
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-#define GET_4_BYTES(ptr) ((uint32_t) *((uint8_t *)(ptr)) | \
- ((uint32_t) *((uint8_t *)(ptr) + 1) << 8) | \
- ((uint32_t) *((uint8_t *)(ptr) + 2) << 16) | \
- ((uint32_t) *((uint8_t *)(ptr) + 3) << 24))
-
-#define GET_8_BYTES(ptr) ((uint64_t) *((uint8_t *)(ptr)) | \
- ((uint64_t) *((uint8_t *)(ptr) + 1) << 8) | \
- ((uint64_t) *((uint8_t *)(ptr) + 2) << 16) | \
- ((uint64_t) *((uint8_t *)(ptr) + 3) << 24) | \
- ((uint64_t) *((uint8_t *)(ptr) + 4) << 32) | \
- ((uint64_t) *((uint8_t *)(ptr) + 5) << 40) | \
- ((uint64_t) *((uint8_t *)(ptr) + 6) << 48) | \
- ((uint64_t) *((uint8_t *)(ptr) + 7) << 56))
-
-#define PUT_4_BYTES(ptr, y) *((uint8_t *)(ptr)) = (y) & 0xff; \
- *((uint8_t *)(ptr) + 1) = ((y) >> 8) & 0xff; \
- *((uint8_t *)(ptr) + 2) = ((y) >> 16) & 0xff; \
- *((uint8_t *)(ptr) + 3) = ((y) >> 24) & 0xff;
-
-
-
-/******************************************************************************
- * TYPES
- ******************************************************************************/
-enum gpt_instance {
- PRIMARY_GPT = 0,
- SECONDARY_GPT
-};
-
-enum boot_chain {
- NORMAL_BOOT = 0,
- BACKUP_BOOT
-};
-
-enum gpt_state {
- GPT_OK = 0,
- GPT_BAD_SIGNATURE,
- GPT_BAD_CRC
-};
-//List of LUN's containing boot critical images.
-//Required in the case of UFS devices
-struct update_data {
- char lun_list[MAX_LUNS][MAX_PATH_LEN];
- int num_valid_entries;
-};
-
-/******************************************************************************
- * FUNCTIONS
- ******************************************************************************/
-/**
- * ==========================================================================
- *
- * \brief Read/Write len bytes from/to block dev
- *
- * \param [in] fd block dev file descriptor (returned from open)
- * \param [in] rw RW flag: 0 - read, != 0 - write
- * \param [in] offset block dev offset [bytes] - RW start position
- * \param [in] buf Pointer to the buffer containing the data
- * \param [in] len RW size in bytes. Buf must be at least that big
- *
- * \return 0 on success
- *
- * ==========================================================================
- */
-static int blk_rw(int fd, int rw, int64_t offset, uint8_t *buf, unsigned len)
-{
- int r;
-
- if (lseek64(fd, offset, SEEK_SET) < 0) {
- fprintf(stderr, "block dev lseek64 %lld failed: %s\n", offset,
- strerror(errno));
- return -1;
- }
-
- if (rw)
- r = write(fd, buf, len);
- else
- r = read(fd, buf, len);
-
- if (r < 0)
- fprintf(stderr, "block dev %s failed: %s\n", rw ? "write" : "read",
- strerror(errno));
- else
- r = 0;
-
- return r;
-}
-
-
-
-/**
- * ==========================================================================
- *
- * \brief Search within GPT for partition entry with the given name
- * or it's backup twin (name-bak).
- *
- * \param [in] ptn_name Partition name to seek
- * \param [in] pentries_start Partition entries array start pointer
- * \param [in] pentries_end Partition entries array end pointer
- * \param [in] pentry_size Single partition entry size [bytes]
- *
- * \return First partition entry pointer that matches the name or NULL
- *
- * ==========================================================================
- */
-static uint8_t *gpt_pentry_seek(const char *ptn_name,
- const uint8_t *pentries_start,
- const uint8_t *pentries_end,
- uint32_t pentry_size)
-{
- char *pentry_name;
- unsigned len = strlen(ptn_name);
-
- for (pentry_name = (char *) (pentries_start + PARTITION_NAME_OFFSET);
- pentry_name < (char *) pentries_end; pentry_name += pentry_size) {
- char name8[MAX_GPT_NAME_SIZE / 2];
- unsigned i;
-
- /* Partition names in GPT are UTF-16 - ignoring UTF-16 2nd byte */
- for (i = 0; i < sizeof(name8); i++)
- name8[i] = pentry_name[i * 2];
- if (!strncmp(ptn_name, name8, len))
- if (name8[len] == 0 || !strcmp(&name8[len], BAK_PTN_NAME_EXT))
- return (uint8_t *) (pentry_name - PARTITION_NAME_OFFSET);
- }
-
- return NULL;
-}
-
-
-
-/**
- * ==========================================================================
- *
- * \brief Swaps boot chain in GPT partition entries array
- *
- * \param [in] pentries_start Partition entries array start
- * \param [in] pentries_end Partition entries array end
- * \param [in] pentry_size Single partition entry size
- *
- * \return 0 on success, 1 if no backup partitions found
- *
- * ==========================================================================
- */
-static int gpt_boot_chain_swap(const uint8_t *pentries_start,
- const uint8_t *pentries_end,
- uint32_t pentry_size)
-{
- const char ptn_swap_list[][MAX_GPT_NAME_SIZE] = { PTN_SWAP_LIST };
-
- int backup_not_found = 1;
- unsigned i;
-
- for (i = 0; i < ARRAY_SIZE(ptn_swap_list); i++) {
- uint8_t *ptn_entry;
- uint8_t *ptn_bak_entry;
- uint8_t ptn_swap[PTN_ENTRY_SIZE];
-
- ptn_entry = gpt_pentry_seek(ptn_swap_list[i], pentries_start,
- pentries_end, pentry_size);
- if (ptn_entry == NULL)
- continue;
-
- ptn_bak_entry = gpt_pentry_seek(ptn_swap_list[i],
- ptn_entry + pentry_size, pentries_end, pentry_size);
- if (ptn_bak_entry == NULL) {
- fprintf(stderr, "'%s' partition not backup - skip safe update\n",
- ptn_swap_list[i]);
- continue;
- }
-
- /* swap primary <-> backup partition entries */
- memcpy(ptn_swap, ptn_entry, PTN_ENTRY_SIZE);
- memcpy(ptn_entry, ptn_bak_entry, PTN_ENTRY_SIZE);
- memcpy(ptn_bak_entry, ptn_swap, PTN_ENTRY_SIZE);
- backup_not_found = 0;
- }
-
- return backup_not_found;
-}
-
-
-
-/**
- * ==========================================================================
- *
- * \brief Sets secondary GPT boot chain
- *
- * \param [in] fd block dev file descriptor
- * \param [in] boot Boot chain to switch to
- *
- * \return 0 on success
- *
- * ==========================================================================
- */
-static int gpt2_set_boot_chain(int fd, enum boot_chain boot)
-{
- int64_t gpt2_header_offset;
- uint64_t pentries_start_offset;
- uint32_t gpt_header_size;
- uint32_t pentry_size;
- uint32_t pentries_array_size;
-
- uint8_t *gpt_header = NULL;
- uint8_t *pentries = NULL;
- uint32_t crc;
- uint32_t blk_size = 0;
- int r;
-
- if (ioctl(fd, BLKSSZGET, &blk_size) != 0) {
- fprintf(stderr, "Failed to get GPT device block size: %s\n",
- strerror(errno));
- r = -1;
- goto EXIT;
- }
- gpt_header = (uint8_t*)malloc(blk_size);
- if (!gpt_header) {
- fprintf(stderr, "Failed to allocate memory to hold GPT block\n");
- r = -1;
- goto EXIT;
- }
- gpt2_header_offset = lseek64(fd, 0, SEEK_END) - blk_size;
- if (gpt2_header_offset < 0) {
- fprintf(stderr, "Getting secondary GPT header offset failed: %s\n",
- strerror(errno));
- r = -1;
- goto EXIT;
- }
-
- /* Read primary GPT header from block dev */
- r = blk_rw(fd, 0, blk_size, gpt_header, blk_size);
-
- if (r) {
- fprintf(stderr, "Failed to read primary GPT header from blk dev\n");
- goto EXIT;
- }
- pentries_start_offset =
- GET_8_BYTES(gpt_header + PENTRIES_OFFSET) * blk_size;
- pentry_size = GET_4_BYTES(gpt_header + PENTRY_SIZE_OFFSET);
- pentries_array_size =
- GET_4_BYTES(gpt_header + PARTITION_COUNT_OFFSET) * pentry_size;
-
- pentries = (uint8_t *) calloc(1, pentries_array_size);
- if (pentries == NULL) {
- fprintf(stderr,
- "Failed to alloc memory for GPT partition entries array\n");
- r = -1;
- goto EXIT;
- }
- /* Read primary GPT partititon entries array from block dev */
- r = blk_rw(fd, 0, pentries_start_offset, pentries, pentries_array_size);
- if (r)
- goto EXIT;
-
- crc = sparse_crc32(0, pentries, pentries_array_size);
- if (GET_4_BYTES(gpt_header + PARTITION_CRC_OFFSET) != crc) {
- fprintf(stderr, "Primary GPT partition entries array CRC invalid\n");
- r = -1;
- goto EXIT;
- }
-
- /* Read secondary GPT header from block dev */
- r = blk_rw(fd, 0, gpt2_header_offset, gpt_header, blk_size);
- if (r)
- goto EXIT;
-
- gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET);
- pentries_start_offset =
- GET_8_BYTES(gpt_header + PENTRIES_OFFSET) * blk_size;
-
- if (boot == BACKUP_BOOT) {
- r = gpt_boot_chain_swap(pentries, pentries + pentries_array_size,
- pentry_size);
- if (r)
- goto EXIT;
- }
-
- crc = sparse_crc32(0, pentries, pentries_array_size);
- PUT_4_BYTES(gpt_header + PARTITION_CRC_OFFSET, crc);
-
- /* header CRC is calculated with this field cleared */
- PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0);
- crc = sparse_crc32(0, gpt_header, gpt_header_size);
- PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, crc);
-
- /* Write the modified GPT header back to block dev */
- r = blk_rw(fd, 1, gpt2_header_offset, gpt_header, blk_size);
- if (!r)
- /* Write the modified GPT partititon entries array back to block dev */
- r = blk_rw(fd, 1, pentries_start_offset, pentries,
- pentries_array_size);
-
-EXIT:
- if(gpt_header)
- free(gpt_header);
- if (pentries)
- free(pentries);
- return r;
-}
-
-
-
-/**
- * ==========================================================================
- *
- * \brief Checks GPT state (header signature and CRC)
- *
- * \param [in] fd block dev file descriptor
- * \param [in] gpt GPT header to be checked
- * \param [out] state GPT header state
- *
- * \return 0 on success
- *
- * ==========================================================================
- */
-static int gpt_get_state(int fd, enum gpt_instance gpt, enum gpt_state *state)
-{
- int64_t gpt_header_offset;
- uint32_t gpt_header_size;
- uint8_t *gpt_header = NULL;
- uint32_t crc;
- uint32_t blk_size = 0;
-
- *state = GPT_OK;
-
- if (ioctl(fd, BLKSSZGET, &blk_size) != 0) {
- fprintf(stderr, "Failed to get GPT device block size: %s\n",
- strerror(errno));
- goto error;
- }
- fprintf(stderr, "gpt_get_state: Block size is %d\n",
- blk_size);
- gpt_header = (uint8_t*)malloc(blk_size);
- if (!gpt_header) {
- fprintf(stderr, "gpt_get_state:Failed to alloc memory for header\n");
- goto error;
- }
- if (gpt == PRIMARY_GPT)
- gpt_header_offset = blk_size;
- else {
- gpt_header_offset = lseek64(fd, 0, SEEK_END) - blk_size;
- if (gpt_header_offset < 0) {
- fprintf(stderr, "gpt_get_state:Seek to end of GPT part fail\n");
- goto error;
- }
- }
-
- if (blk_rw(fd, 0, gpt_header_offset, gpt_header, blk_size)) {
- fprintf(stderr, "gpt_get_state: blk_rw failed\n");
- goto error;
- }
- if (memcmp(gpt_header, GPT_SIGNATURE, sizeof(GPT_SIGNATURE)))
- *state = GPT_BAD_SIGNATURE;
- gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET);
-
- crc = GET_4_BYTES(gpt_header + HEADER_CRC_OFFSET);
- /* header CRC is calculated with this field cleared */
- PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0);
- if (sparse_crc32(0, gpt_header, gpt_header_size) != crc)
- *state = GPT_BAD_CRC;
- free(gpt_header);
- return 0;
-error:
- if (gpt_header)
- free(gpt_header);
- return -1;
-}
-
-
-
-/**
- * ==========================================================================
- *
- * \brief Sets GPT header state (used to corrupt and fix GPT signature)
- *
- * \param [in] fd block dev file descriptor
- * \param [in] gpt GPT header to be checked
- * \param [in] state GPT header state to set (GPT_OK or GPT_BAD_SIGNATURE)
- *
- * \return 0 on success
- *
- * ==========================================================================
- */
-static int gpt_set_state(int fd, enum gpt_instance gpt, enum gpt_state state)
-{
- int64_t gpt_header_offset;
- uint32_t gpt_header_size;
- uint8_t *gpt_header = NULL;
- uint32_t crc;
- uint32_t blk_size = 0;
-
- if (ioctl(fd, BLKSSZGET, &blk_size) != 0) {
- fprintf(stderr, "Failed to get GPT device block size: %s\n",
- strerror(errno));
- goto error;
- }
- gpt_header = (uint8_t*)malloc(blk_size);
- if (!gpt_header) {
- fprintf(stderr, "Failed to alloc memory for gpt header\n");
- goto error;
- }
- if (gpt == PRIMARY_GPT)
- gpt_header_offset = blk_size;
- else {
- gpt_header_offset = lseek64(fd, 0, SEEK_END) - blk_size;
- if (gpt_header_offset < 0) {
- fprintf(stderr, "Failed to seek to end of GPT device\n");
- goto error;
- }
- }
- if (blk_rw(fd, 0, gpt_header_offset, gpt_header, blk_size)) {
- fprintf(stderr, "Failed to r/w gpt header\n");
- goto error;
- }
- if (state == GPT_OK)
- memcpy(gpt_header, GPT_SIGNATURE, sizeof(GPT_SIGNATURE));
- else if (state == GPT_BAD_SIGNATURE)
- *gpt_header = 0;
- else {
- fprintf(stderr, "gpt_set_state: Invalid state\n");
- goto error;
- }
-
- gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET);
-
- /* header CRC is calculated with this field cleared */
- PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0);
- crc = sparse_crc32(0, gpt_header, gpt_header_size);
- PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, crc);
-
- if (blk_rw(fd, 1, gpt_header_offset, gpt_header, blk_size)) {
- fprintf(stderr, "gpt_set_state: blk write failed\n");
- goto error;
- }
- return 0;
-error:
- if(gpt_header)
- free(gpt_header);
- return -1;
-}
-
-//dev_path is the path to the block device that contains the GPT image that
-//needs to be updated. This would be the device which holds one or more critical
-//boot partitions and their backups. In the case of EMMC this function would
-//be invoked only once on /dev/block/mmcblk1 since it holds the GPT image
-//containing all the partitions For UFS devices it could potentially be
-//invoked multiple times, once for each LUN containing critical image(s) and
-//their backups
-int prepare_partitions(enum boot_update_stage stage, const char *dev_path)
-{
- int r;
- int fd = -1;
- enum gpt_state gpt_prim, gpt_second;
- enum boot_update_stage internal_stage;
-
- if (!dev_path) {
- fprintf(stderr, "Invalid dev_path passed to prepare_partitions\n");
- r = -1;
- goto EXIT;
- }
- fd = open(dev_path, O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "Opening '%s' failed: %s\n", BLK_DEV_FILE,
- strerror(errno));
- r = -1;
- goto EXIT;
- }
- r = gpt_get_state(fd, PRIMARY_GPT, &gpt_prim) ||
- gpt_get_state(fd, SECONDARY_GPT, &gpt_second);
- if (r) {
- fprintf(stderr, "Getting GPT headers state failed\n");
- goto EXIT;
- }
-
- /* These 2 combinations are unexpected and unacceptable */
- if (gpt_prim == GPT_BAD_CRC || gpt_second == GPT_BAD_CRC) {
- fprintf(stderr, "GPT headers CRC corruption detected, aborting\n");
- r = -1;
- goto EXIT;
- }
- if (gpt_prim == GPT_BAD_SIGNATURE && gpt_second == GPT_BAD_SIGNATURE) {
- fprintf(stderr, "Both GPT headers corrupted, aborting\n");
- r = -1;
- goto EXIT;
- }
-
- /* Check internal update stage according GPT headers' state */
- if (gpt_prim == GPT_OK && gpt_second == GPT_OK)
- internal_stage = UPDATE_MAIN;
- else if (gpt_prim == GPT_BAD_SIGNATURE)
- internal_stage = UPDATE_BACKUP;
- else if (gpt_second == GPT_BAD_SIGNATURE)
- internal_stage = UPDATE_FINALIZE;
- else {
- fprintf(stderr, "Abnormal GPTs state: primary (%d), secondary (%d), "
- "aborting\n", gpt_prim, gpt_second);
- r = -1;
- goto EXIT;
- }
-
- /* Stage already set - ready for update, exitting */
- if ((int) stage == (int) internal_stage - 1)
- goto EXIT;
- /* Unexpected stage given */
- if (stage != internal_stage) {
- r = -1;
- goto EXIT;
- }
-
- switch (stage) {
- case UPDATE_MAIN:
- r = gpt2_set_boot_chain(fd, BACKUP_BOOT);
- if (r) {
- if (r < 0)
- fprintf(stderr,
- "Setting secondary GPT to backup boot failed\n");
- /* No backup partitions - do not corrupt GPT, do not flag error */
- else
- r = 0;
- goto EXIT;
- }
-
- r = gpt_set_state(fd, PRIMARY_GPT, GPT_BAD_SIGNATURE);
- if (r) {
- fprintf(stderr, "Corrupting primary GPT header failed\n");
- goto EXIT;
- }
-
- break;
- case UPDATE_BACKUP:
- r = gpt_set_state(fd, PRIMARY_GPT, GPT_OK);
- if (r) {
- fprintf(stderr, "Fixing primary GPT header failed\n");
- goto EXIT;
- }
-
- r = gpt_set_state(fd, SECONDARY_GPT, GPT_BAD_SIGNATURE);
- if (r) {
- fprintf(stderr, "Corrupting secondary GPT header failed\n");
- goto EXIT;
- }
-
- break;
- case UPDATE_FINALIZE:
- r = gpt2_set_boot_chain(fd, NORMAL_BOOT);
- if (r < 0) {
- fprintf(stderr, "Setting secondary GPT to normal boot failed\n");
- goto EXIT;
- }
-
- r = gpt_set_state(fd, SECONDARY_GPT, GPT_OK);
- if (r) {
- fprintf(stderr, "Fixing secondary GPT header failed\n");
- goto EXIT;
- }
-
- break;
- default:;
- }
-
-EXIT:
- if (fd >= 0) {
- fsync(fd);
- close(fd);
- }
- return r;
-}
-
-int add_lun_to_update_list(char *lun_path, struct update_data *dat)
-{
- int i = 0;
- struct stat st;
- if (!lun_path || !dat){
- fprintf(stderr, "Invalid data passed to add_lun_to_update_list");
- return -1;
- }
- if (stat(lun_path, &st)) {
- fprintf(stderr, "Unable to access %s. Skipping adding to list",
- lun_path);
- return -1;
- }
- if (dat->num_valid_entries == 0) {
- fprintf(stderr, "Copying %s into lun_list[%d]\n",
- lun_path,
- i);
- strlcpy(dat->lun_list[0], lun_path,
- MAX_PATH_LEN * sizeof(char));
- dat->num_valid_entries = 1;
- } else {
- for (i = 0; (i < dat->num_valid_entries) &&
- (dat->num_valid_entries < MAX_LUNS - 1); i++) {
- //Check if the current LUN is not already part
- //of the lun list
- if (!strncmp(lun_path,dat->lun_list[i],
- strlen(dat->lun_list[i]))) {
- //LUN already in list..Return
- return 0;
- }
- }
- fprintf(stderr, "Copying %s into lun_list[%d]\n",
- lun_path,
- dat->num_valid_entries);
- //Add LUN path lun list
- strlcpy(dat->lun_list[dat->num_valid_entries], lun_path,
- MAX_PATH_LEN * sizeof(char));
- dat->num_valid_entries++;
- }
- return 0;
-}
-
-int prepare_boot_update(enum boot_update_stage stage)
-{
- int r, fd;
- int is_ufs = 0;
- struct stat ufs_dir_stat;
- struct update_data data;
- int rcode = 0;
- int i = 0;
- int is_error = 0;
- const char ptn_swap_list[][MAX_GPT_NAME_SIZE] = { PTN_SWAP_LIST };
- //Holds /dev/block/bootdevice/by-name/*bak entry
- char buf[MAX_PATH_LEN] = {0};
- //Holds the resolved path of the symlink stored in buf
- char real_path[MAX_PATH_LEN] = {0};
-
- if(stat(UFS_DEV_DIR, &ufs_dir_stat)) {
- is_ufs = 0;
- } else {
- fprintf(stderr, "UFS device detected\n");
- is_ufs = 1;
- }
- if (!is_ufs) {
- //emmc device. Just pass in path to mmcblk0
- return prepare_partitions(stage, BLK_DEV_FILE);
- } else {
- //Now we need to find the list of LUNs over
- //which the boot critical images are spread
- //and set them up for failsafe updates.To do
- //this we find out where the symlinks for the
- //each of the paths under
- ///dev/block/bootdevice/by-name/PTN_SWAP_LIST
- //actually point to.
- memset(&data, '\0', sizeof(struct update_data));
- for (i=0; i < ARRAY_SIZE(ptn_swap_list); i++) {
- snprintf(buf, sizeof(buf),
- "%s/%sbak",
- BOOT_DEV_DIR,
- ptn_swap_list[i]);
- fprintf(stderr, "Attempting to process %s\n", buf);
- if (stat(buf, &ufs_dir_stat)) {
- fprintf(stderr, "%s not present. Skipping\n",
- buf);
- continue;
- }
- if (readlink(buf, real_path, sizeof(real_path)) < 0)
- {
- fprintf(stderr, "readlink error. Skipping %s",
- strerror(errno));
- } else {
- real_path[PATH_TRUNCATE_LOC] = '\0';
- add_lun_to_update_list(real_path, &data);
- }
- memset(buf, '\0', sizeof(buf));
- memset(real_path, '\0', sizeof(real_path));
- }
- for (i=0; i < data.num_valid_entries; i++) {
- fprintf(stderr, "Preparing %s for update stage %d\n",
- data.lun_list[i],
- stage);
- rcode = prepare_partitions(stage, data.lun_list[i]);
- if (rcode != 0)
- {
- fprintf(stderr, "Failed to prepare %s.Continuing..\n",
- data.lun_list[i]);
- is_error = 1;
- }
- }
- }
- if (is_error)
- return -1;
- return 0;
-}
diff --git a/recovery/oem-recovery/gpt-utils.h b/recovery/oem-recovery/gpt-utils.h
deleted file mode 100644
index 93a7c94..0000000
--- a/recovery/oem-recovery/gpt-utils.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __GPT_UTILS_H__
-#define __GPT_UTILS_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include <unistd.h>
-#include <stdlib.h>
-/******************************************************************************
- * TYPES
- ******************************************************************************/
-enum boot_update_stage {
- UPDATE_MAIN = 1,
- UPDATE_BACKUP,
- UPDATE_FINALIZE
-};
-
-
-
-/******************************************************************************
- * FUNCTION PROTOTYPES
- ******************************************************************************/
-int prepare_boot_update(enum boot_update_stage stage);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* __GPT_UTILS_H__ */
diff --git a/recovery/oem-recovery/oem-updater.cpp b/recovery/oem-recovery/oem-updater.cpp
deleted file mode 100644
index 4a6c8b4..0000000
--- a/recovery/oem-recovery/oem-updater.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "edify/expr.h"
-#include "dec.h"
-#include "gpt-utils.h"
-
-Value* DecryptFn(const char* name, State* state, int argc, Expr* argv[]) {
- int rc = -1;
- char *src_file, *dst_file;
-
- if (argc != 2)
- return ErrorAbort(state, "%s expects 2 args, got %d", name, argc);
-
- if (ReadArgs(state, argv, 2, &src_file, &dst_file))
- return NULL;
-
- rc = decrypt_image(src_file, dst_file);
-
- free(src_file);
- free(dst_file);
-
- return StringValue(strdup(rc >= 0 ? "t" : ""));
-}
-
-Value* BootUpdateFn(const char* name, State* state, int argc, Expr* argv[])
-{
- int rc = 0;
- char *stageStr;
- enum boot_update_stage stage;
-
- if (argc != 1)
- return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
-
- if (ReadArgs(state, argv, 1, &stageStr))
- return NULL;
-
- if (!strcmp(stageStr, "main"))
- stage = UPDATE_MAIN;
- else if (!strcmp(stageStr, "backup"))
- stage = UPDATE_BACKUP;
- else if (!strcmp(stageStr, "finalize"))
- stage = UPDATE_FINALIZE;
- else {
- fprintf(stderr, "Unrecognized boot update stage, exitting\n");
- rc = -1;
- }
-
- free(stageStr);
-
- if (!rc)
- rc = prepare_boot_update(stage);
-
- return StringValue(strdup(rc ? "" : "t"));
-}
-
-void Register_librecovery_updater_msm() {
- RegisterFunction("msm.decrypt", DecryptFn);
- RegisterFunction("msm.boot_update", BootUpdateFn);
-}
diff --git a/releasetools.py b/releasetools.py
deleted file mode 100755
index 4dc95d8..0000000
--- a/releasetools.py
+++ /dev/null
@@ -1,382 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-# Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Emit commands needed for QCOM devices during OTA installation
-(installing the radio image)."""
-
-import common
-import re
-
-
-bootImages = {}
-binImages = {}
-fwImages = {}
-imgImages = {}
-
-# Parse filesmap file containing firmware residing places
-def LoadFilesMap(zip, name="RADIO/filesmap"):
- try:
- data = zip.read(name)
- except KeyError:
- print "Warning: could not find %s in %s." % (name, zip)
- data = ""
- d = {}
- for line in data.split("\n"):
- line = line.strip()
- if not line or line.startswith("#"):
- continue
- pieces = line.split()
- if not (len(pieces) == 2):
- raise ValueError("malformed filesmap line: \"%s\"" % (line,))
- d[pieces[0]] = pieces[1]
- return d
-
-
-# Read firmware images from target files zip
-def GetRadioFiles(z):
- out = {}
- for info in z.infolist():
- f = info.filename
- if f.startswith("RADIO/") and (f.__len__() > len("RADIO/")):
- fn = f[6:]
- if fn.startswith("filesmap"):
- continue
- data = z.read(f)
- out[fn] = common.File(f, data)
- return out
-
-
-# Get firmware residing place from filesmap
-def GetFileDestination(fn, filesmap):
- # if file is encoded disregard the .enc extention
- if fn.endswith('.enc'):
- fn = fn[:-4]
-
- # get backup destination as well if present
- backup = None
- if fn + ".bak" in filesmap:
- backup = filesmap[fn + ".bak"]
-
- # If full filename is not specified in filesmap get only the name part
- # and look for this token
- if fn not in filesmap:
- fn = fn.split(".")[0] + ".*"
- if fn not in filesmap:
- print "warning radio-update: '%s' not found in filesmap" % (fn)
- return None, backup
- return filesmap[fn], backup
-
-
-# Separate image types as each type needs different handling
-def SplitFwTypes(files):
- boot = {}
- bin = {}
- fw = {}
- img = {}
-
- for f in files:
- extIdx = -1
- dotSeparated = f.split(".")
- while True:
- if dotSeparated[extIdx] != 'p' and dotSeparated[extIdx] != 'enc':
- break
- extIdx -= 1
-
- if dotSeparated[extIdx] == 'mbn' or dotSeparated[extIdx] == 'elf':
- boot[f] = files[f]
- elif dotSeparated[extIdx] == 'bin':
- bin[f] = files[f]
- elif dotSeparated[extIdx] == 'img':
- img[f] = files[f]
- else:
- fw[f] = files[f]
- return boot, bin, fw, img
-
-
-# Prepare radio-update files and verify them
-def OTA_VerifyEnd(info, api_version, target_zip, source_zip=None):
- if api_version < 3:
- print "warning radio-update: no support for api_version less than 3"
- return False
-
- print "Loading radio filesmap..."
- filesmap = LoadFilesMap(target_zip)
- if filesmap == {}:
- print "warning radio-update: no or invalid filesmap file found"
- return False
-
- print "Loading radio target..."
- tgt_files = GetRadioFiles(target_zip)
- if tgt_files == {}:
- print "warning radio-update: no radio images in input target_files"
- return False
-
- src_files = None
- if source_zip is not None:
- print "Loading radio source..."
- src_files = GetRadioFiles(source_zip)
-
- update_list = {}
- largest_source_size = 0
-
- print "Preparing radio-update files..."
- for fn in tgt_files:
- dest, destBak = GetFileDestination(fn, filesmap)
- if dest is None:
- continue
-
- tf = tgt_files[fn]
- sf = None
- if src_files is not None:
- sf = src_files.get(fn, None)
-
- full = sf is None or fn.endswith('.enc')
- if not full:
- # no difference - skip this file
- if tf.sha1 == sf.sha1:
- continue
- d = common.Difference(tf, sf)
- _, _, d = d.ComputePatch()
- # no difference - skip this file
- if d is None:
- continue
- # if patch is almost as big as the file - don't bother patching
- full = len(d) > tf.size * common.OPTIONS.patch_threshold
- if not full:
- f = "patch/firmware-update/" + fn + ".p"
- common.ZipWriteStr(info.output_zip, f, d)
- update_list[f] = (dest, destBak, tf, sf)
- largest_source_size = max(largest_source_size, sf.size)
- if full:
- f = "firmware-update/" + fn
- common.ZipWriteStr(info.output_zip, f, tf.data)
- update_list[f] = (dest, destBak, None, None)
-
- global bootImages
- global binImages
- global fwImages
- global imgImages
- bootImages, binImages, fwImages, imgImages = SplitFwTypes(update_list)
-
- # If there are incremental patches verify them
- if largest_source_size != 0:
- info.script.Comment("---- radio update verification ----")
- info.script.Print("Verifying radio-update...")
-
- for f in bootImages:
- dest, destBak, tf, sf = bootImages[f]
- # Not incremental
- if sf is None:
- continue
- info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" %
- (dest, sf.size, sf.sha1, tf.size, tf.sha1))
- if destBak is not None:
- info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" %
- (destBak, sf.size, sf.sha1, tf.size, tf.sha1))
- for f in binImages:
- dest, destBak, tf, sf = binImages[f]
- # Not incremental
- if sf is None:
- continue
- info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" %
- (dest, sf.size, sf.sha1, tf.size, tf.sha1))
- last_mounted = ""
- for f in fwImages:
- dest, destBak, tf, sf = fwImages[f]
- # Not incremental
- if sf is None:
- continue
- # Get the filename without the path and the patch (.p) extention
- f = f.split("/")[-1][:-2]
- # Parse filesmap destination paths for "/dev/" pattern in the beginng.
- # This would mean that the file must be written to block device -
- # fs mount needed
- if dest.startswith("/dev/"):
- if last_mounted != dest:
- info.script.AppendExtra('unmount("/firmware");')
- info.script.AppendExtra('mount("vfat", "EMMC", "%s", "/firmware");' %
- (dest))
- last_mounted = dest
- dest = "/firmware/image/" + f
- else:
- dest = dest + "/" + f
- info.script.PatchCheck(dest, tf.sha1, sf.sha1)
- for f in imgImages:
- dest, tf, sf = imgImages[f]
- # Not incremental
- if sf is None:
- continue
- info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" %
- (dest, sf.size, sf.sha1, tf.size, tf.sha1))
- last_mounted = ""
-
- info.script.CacheFreeSpaceCheck(largest_source_size)
- return True
-
-
-def FullOTA_Assertions(info):
- #TODO: Implement device specific asserstions.
- return
-
-
-def IncrementalOTA_Assertions(info):
- #TODO: Implement device specific asserstions.
- return
-
-
-def IncrementalOTA_VerifyEnd(info):
- OTA_VerifyEnd(info, info.target_version, info.target_zip, info.source_zip)
- return
-
-
-# This function handles only non-HLOS whole partition images
-def InstallRawImage(script, f, dest, tf, sf):
- if f.endswith('.p'):
- script.ApplyPatch("EMMC:%s:%d:%s:%d:%s" %
- (dest, sf.size, sf.sha1, tf.size, tf.sha1),
- "-", tf.size, tf.sha1, sf.sha1, f)
- elif f.endswith('.enc'):
- # Get the filename without the path
- fn = f.split("/")[-1]
- script.AppendExtra('package_extract_file("%s", "/tmp/%s");' % (f, fn))
- script.AppendExtra('msm.decrypt("/tmp/%s", "%s");' % (fn, dest))
- else:
- script.AppendExtra('package_extract_file("%s", "%s");' % (f, dest))
- return
-
-
-# This function handles only non-HLOS boot images - files list must contain
-# only such images (aboot, tz, etc)
-def InstallBootImages(script, files):
- bakExists = False
- # update main partitions
- script.AppendExtra('ifelse(msm.boot_update("main"), (')
- for f in files:
- dest, destBak, tf, sf = files[f]
- if destBak is not None:
- bakExists = True
- InstallRawImage(script, f, dest, tf, sf)
- script.AppendExtra('), "");')
-
- # update backup partitions
- if bakExists:
- script.AppendExtra('ifelse(msm.boot_update("backup"), (')
- for f in files:
- dest, destBak, tf, sf = files[f]
- if destBak is not None:
- InstallRawImage(script, f, destBak, tf, sf)
- script.AppendExtra('), "");')
- # just finalize primary update stage
- else:
- script.AppendExtra('msm.boot_update("backup");')
-
- # finalize partitions update
- script.AppendExtra('msm.boot_update("finalize");')
- return
-
-
-# This function handles only non-HLOS bin images
-def InstallBinImages(script, files):
- for f in files:
- dest, _, tf, sf = files[f]
- InstallRawImage(script, f, dest, tf, sf)
- return
-
-
-# This function handles only non-HLOS firmware files that are not whole
-# partition images (modem, dsp, etc)
-def InstallFwImages(script, files):
- last_mounted = ""
-
- for f in files:
- dest, _, tf, sf = files[f]
- # Get the filename without the path
- fn = f.split("/")[-1]
- # Parse filesmap destination paths for "/dev/" pattern in the beginng.
- # This would mean that the file must be written to block device -
- # fs mount needed
- if dest.startswith("/dev/"):
- if last_mounted != dest:
- script.AppendExtra('unmount("/firmware");')
- script.AppendExtra('mount("vfat", "EMMC", "%s", "/firmware");' %
- (dest))
- last_mounted = dest
- dest = "/firmware/image/" + fn
- else:
- dest = dest + "/" + fn
-
- if f.endswith('.p'):
- script.ApplyPatch(dest[:-2], "-", tf.size, tf.sha1, sf.sha1, f)
- elif f.endswith('.enc'):
- script.AppendExtra('package_extract_file("%s", "/tmp/%s");' % (f, fn))
- script.AppendExtra('msm.decrypt("/tmp/%s", "%s");' % (fn, dest[:-4]))
- else:
- script.AppendExtra('package_extract_file("%s", "%s");' % (f, dest))
-
- if last_mounted != "":
- script.AppendExtra('unmount("/firmware");')
- return
-
-# This function handles *.img images
-def InstallImgImages(script, files):
- for f in files:
- dest, _, tf, sf = files[f]
- InstallRawImage(script, f, dest, tf, sf)
- return
-
-
-def OTA_InstallEnd(info):
- print "Applying radio-update script modifications..."
- info.script.Comment("---- radio update tasks ----")
- info.script.Print("Patching firmware images...")
-
- if bootImages != {}:
- InstallBootImages(info.script, bootImages)
- if binImages != {}:
- InstallBinImages(info.script, binImages)
- if fwImages != {}:
- InstallFwImages(info.script, fwImages)
- if imgImages != {}:
- InstallImgImages(info.script, imgImages)
- return
-
-
-def FullOTA_InstallEnd_MMC(info):
- if OTA_VerifyEnd(info, info.input_version, info.input_zip):
- OTA_InstallEnd(info)
- return
-
-
-def FullOTA_InstallEnd_MTD(info):
- print "warning radio-update: radio update for NAND devices not supported"
- return
-
-
-def FullOTA_InstallEnd(info):
- FullOTA_InstallEnd_MMC(info)
- return
-
-def IncrementalOTA_InstallEnd_MMC(info):
- OTA_InstallEnd(info)
- return
-
-
-def IncrementalOTA_InstallEnd_MTD(info):
- print "warning radio-update: radio update for NAND devices not supported"
- return
-
-def IncrementalOTA_InstallEnd(info):
- IncrementalOTA_InstallEnd_MMC(info)
- return