summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2010-02-17 13:03:32 -0800
committerJean-Baptiste Queru <jbq@google.com>2010-02-17 16:27:58 -0800
commitef1953356b258154f5ddefa26a8a05f799f9b31e (patch)
tree5b9de7cba00a2c03a8782d70a6e0091ee640eb56
parent9a282a00f5b63c8671933934f756b0e653aa4674 (diff)
downloadcommon-ef1953356b258154f5ddefa26a8a05f799f9b31e.tar.gz
Move open-sourceable passion files
Change-Id: I545475bbd7ee265c2560fae065c4169ae2e8310c
-rw-r--r--Android.mk1
-rw-r--r--common.mk23
-rw-r--r--common_small.mk23
-rw-r--r--overlay/frameworks/base/core/res/res/values/strings.xml140
-rw-r--r--updater/Android.mk31
-rw-r--r--updater/MODULE_LICENSE_APACHE20
-rw-r--r--updater/NOTICE190
-rw-r--r--updater/bootloader.c317
-rw-r--r--updater/bootloader.h78
-rw-r--r--updater/firmware.c104
-rw-r--r--updater/firmware.h32
-rw-r--r--updater/log_recovery.c73
-rw-r--r--updater/recovery_updater.c100
13 files changed, 1112 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..6571161
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1 @@
+include $(all-subdir-makefiles)
diff --git a/common.mk b/common.mk
new file mode 100644
index 0000000..1b3dc80
--- /dev/null
+++ b/common.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# 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.
+#
+
+# This lists the aspects that are unique to HTC but shared between all
+# HTC devices
+
+-include vendor/htc/common/common-vendor.mk
+
+PRODUCT_MANUFACTURER := HTC
+DEVICE_PACKAGE_OVERLAYS := device/htc/common/overlay $(DEVICE_PACKAGE_OVERLAYS)
diff --git a/common_small.mk b/common_small.mk
new file mode 100644
index 0000000..b9bd7dd
--- /dev/null
+++ b/common_small.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# 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.
+#
+
+# This lists the aspects that are unique to HTC but shared between all
+# HTC devices. These are specially fine-tuned for devices with a small
+# system partition.
+
+$(call inherit-product, device/htc/common/common.mk)
+
+-include vendor/htc/common/common_small-vendor.mk
diff --git a/overlay/frameworks/base/core/res/res/values/strings.xml b/overlay/frameworks/base/core/res/res/values/strings.xml
new file mode 100644
index 0000000..0b0cde1
--- /dev/null
+++ b/overlay/frameworks/base/core/res/res/values/strings.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- An Array of [[Carrier-ID] -->
+ <!-- [default-locale] -->
+ <!-- [default-wifi-allowed-channels]] -->
+ <string-array translatable="false" name="carrier_properties">
+ <item>AirTel-India</item>
+ <item>en_IN</item>
+ <item></item>
+ <item>Chunghwa-Taiwan</item>
+ <item>zh_TW</item>
+ <item></item>
+ <item>DCM</item>
+ <item>ja_JP</item>
+ <item>14</item>
+ <item>Era</item>
+ <item>pl_PL</item>
+ <item></item>
+ <item>H3G-Italy</item>
+ <item>it_IT</item>
+ <item></item>
+ <item>Hutch-Australia</item>
+ <item>en_AU</item>
+ <item>11</item>
+ <item>iTELEF-Spain</item>
+ <item>es_ES</item>
+ <item></item>
+ <item>OPTUS-Australia</item>
+ <item>en_AU</item>
+ <item>11</item>
+ <item>ORANGE-French</item>
+ <item>fr_FR</item>
+ <item></item>
+ <item>SMC-Voda-HK</item>
+ <item>zh_HK</item>
+ <item></item>
+ <item>StarHub-Singapore</item>
+ <item>en_SG</item>
+ <item>11</item>
+ <item>TIM-Italy</item>
+ <item>it_IT</item>
+ <item></item>
+ <item>TMA</item>
+ <item>de_AT</item>
+ <item>13</item>
+ <item>TMCZ</item>
+ <item>cs_CZ</item>
+ <item>13</item>
+ <item>TMD</item>
+ <item>de_DE</item>
+ <item>13</item>
+ <item>TMHR</item>
+ <item>hr_HR</item>
+ <item></item>
+ <item>TMMK</item>
+ <item>mk_MK</item>
+ <item></item>
+ <item>TMNL</item>
+ <item>nl_NL</item>
+ <item>13</item>
+ <item>TMSK</item>
+ <item>sk_SK</item>
+ <item></item>
+ <item>TMUK</item>
+ <item>en_GB</item>
+ <item>13</item>
+ <item>TMUS</item>
+ <item>en_US</item>
+ <item>11</item>
+ <item>VODA-Africa-South</item>
+ <item>en_ZA</item>
+ <item></item>
+ <item>VODA-Australia</item>
+ <item>en_AU</item>
+ <item>11</item>
+ <item>VODA-Germany</item>
+ <item>de_DE</item>
+ <item>13</item>
+ <item>VODA-Greece</item>
+ <item>el_GR</item>
+ <item></item>
+ <item>VODA-Ireland</item>
+ <item>en_IE</item>
+ <item></item>
+ <item>VODA-Italy</item>
+ <item>it_IT</item>
+ <item></item>
+ <item>VODA-Mobilkom</item>
+ <item>de_AT</item>
+ <item>13</item>
+ <item>VODA-Netherland</item>
+ <item>nl_NL</item>
+ <item>13</item>
+ <item>VODA-New-Zealand</item>
+ <item>en_NZ</item>
+ <item></item>
+ <item>VODA-Portugal</item>
+ <item>pt_PT</item>
+ <item></item>
+ <item>VODA-SFR</item>
+ <item>fr_FR</item>
+ <item></item>
+ <item>VODA-Spain</item>
+ <item>es_ES</item>
+ <item></item>
+ <item>VODA-Swisscom-DE</item>
+ <item>de_CH</item>
+ <item>13</item>
+ <item>VODA-Swisscom-FR</item>
+ <item>fr_CH</item>
+ <item></item>
+ <item>VODA-Swisscom-IT</item>
+ <item>it_CH</item>
+ <item></item>
+ <item>VODA-Swisscom-WWE</item>
+ <item>en_CH</item>
+ <item></item>
+ <item>VODA-UK</item>
+ <item>en_GB</item>
+ <item>13</item>
+ </string-array>
+</resources>
diff --git a/updater/Android.mk b/updater/Android.mk
new file mode 100644
index 0000000..056fe41
--- /dev/null
+++ b/updater/Android.mk
@@ -0,0 +1,31 @@
+ifneq ($(TARGET_SIMULATOR),true)
+ifeq ($(TARGET_ARCH),arm)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# librecovery_ui_htc is a static library included by all the recovery
+# UI libraries for specific devices (passion, sapphire, dream). It
+# knows how to recover the log stored in the cache partition when a
+# radio or hboot update is done.
+
+LOCAL_SRC_FILES := log_recovery.c
+LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_MODULE := librecovery_ui_htc
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+# librecovery_update_htc is a set of edify extension functions for
+# doing radio and hboot updates on HTC devices.
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := recovery_updater.c firmware.c bootloader.c
+LOCAL_STATIC_LIBRARIES += libmtdutils
+LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_MODULE := librecovery_updater_htc
+include $(BUILD_STATIC_LIBRARY)
+
+endif # TARGET_ARCH == arm
+endif # !TARGET_SIMULATOR
diff --git a/updater/MODULE_LICENSE_APACHE2 b/updater/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/updater/MODULE_LICENSE_APACHE2
diff --git a/updater/NOTICE b/updater/NOTICE
new file mode 100644
index 0000000..64aaa8d
--- /dev/null
+++ b/updater/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2009, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/updater/bootloader.c b/updater/bootloader.c
new file mode 100644
index 0000000..52f537a
--- /dev/null
+++ b/updater/bootloader.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "bootloader.h"
+#include "common.h"
+#include "mtdutils/mtdutils.h"
+#include "roots.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+static const int MISC_PAGES = 3; // number of pages to save
+static const int MISC_COMMAND_PAGE = 1; // bootloader command is this page
+
+#undef LOGE
+#define LOGE(...) fprintf(stderr, "E:" __VA_ARGS__)
+
+#ifdef LOG_VERBOSE
+static void dump_data(const char *data, int len) {
+ int pos;
+ for (pos = 0; pos < len; ) {
+ printf("%05x: %02x", pos, data[pos]);
+ for (++pos; pos < len && (pos % 24) != 0; ++pos) {
+ printf(" %02x", data[pos]);
+ }
+ printf("\n");
+ }
+}
+#endif
+
+int get_bootloader_message(struct bootloader_message *out) {
+ size_t write_size;
+ const MtdPartition *part = mtd_find_partition_by_name(MISC_NAME);
+ if (part == NULL || mtd_partition_info(part, NULL, NULL, &write_size)) {
+ LOGE("Can't find %s\n", MISC_NAME);
+ return -1;
+ }
+
+ MtdReadContext *read = mtd_read_partition(part);
+ if (read == NULL) {
+ LOGE("Can't open %s\n(%s)\n", MISC_NAME, strerror(errno));
+ return -1;
+ }
+
+ const ssize_t size = write_size * MISC_PAGES;
+ char data[size];
+ ssize_t r = mtd_read_data(read, data, size);
+ if (r != size) LOGE("Can't read %s\n(%s)\n", MISC_NAME, strerror(errno));
+ mtd_read_close(read);
+ if (r != size) return -1;
+
+#ifdef LOG_VERBOSE
+ printf("\n--- get_bootloader_message ---\n");
+ dump_data(data, size);
+ printf("\n");
+#endif
+
+ memcpy(out, &data[write_size * MISC_COMMAND_PAGE], sizeof(*out));
+ return 0;
+}
+
+int set_bootloader_message(const struct bootloader_message *in) {
+ size_t write_size;
+ const MtdPartition *part = mtd_find_partition_by_name(MISC_NAME);
+ if (part == NULL || mtd_partition_info(part, NULL, NULL, &write_size)) {
+ LOGE("Can't find %s\n", MISC_NAME);
+ return -1;
+ }
+
+ MtdReadContext *read = mtd_read_partition(part);
+ if (read == NULL) {
+ LOGE("Can't open %s\n(%s)\n", MISC_NAME, strerror(errno));
+ return -1;
+ }
+
+ ssize_t size = write_size * MISC_PAGES;
+ char data[size];
+ ssize_t r = mtd_read_data(read, data, size);
+ if (r != size) LOGE("Can't read %s\n(%s)\n", MISC_NAME, strerror(errno));
+ mtd_read_close(read);
+ if (r != size) return -1;
+
+ memcpy(&data[write_size * MISC_COMMAND_PAGE], in, sizeof(*in));
+
+#ifdef LOG_VERBOSE
+ printf("\n--- set_bootloader_message ---\n");
+ dump_data(data, size);
+ printf("\n");
+#endif
+
+ MtdWriteContext *write = mtd_write_partition(part);
+ if (write == NULL) {
+ LOGE("Can't open %s\n(%s)\n", MISC_NAME, strerror(errno));
+ return -1;
+ }
+ if (mtd_write_data(write, data, size) != size) {
+ LOGE("Can't write %s\n(%s)\n", MISC_NAME, strerror(errno));
+ mtd_write_close(write);
+ return -1;
+ }
+ if (mtd_write_close(write)) {
+ LOGE("Can't finish %s\n(%s)\n", MISC_NAME, strerror(errno));
+ return -1;
+ }
+
+ LOGI("Set boot command \"%s\"\n", in->command[0] != 255 ? in->command : "");
+ return 0;
+}
+
+/* Update Image
+ *
+ * - will be stored in the "cache" partition
+ * - bad blocks will be ignored, like boot.img and recovery.img
+ * - the first block will be the image header (described below)
+ * - the size is in BYTES, inclusive of the header
+ * - offsets are in BYTES from the start of the update header
+ * - two raw bitmaps will be included, the "busy" and "fail" bitmaps
+ * - for dream, the bitmaps will be 320x480x16bpp RGB565
+ */
+
+struct update_header {
+ unsigned char MAGIC[UPDATE_MAGIC_SIZE];
+
+ unsigned version;
+ unsigned size;
+
+ unsigned image_offset;
+ unsigned image_length;
+
+ unsigned bitmap_width;
+ unsigned bitmap_height;
+ unsigned bitmap_bpp;
+
+ unsigned busy_bitmap_offset;
+ unsigned busy_bitmap_length;
+
+ unsigned fail_bitmap_offset;
+ unsigned fail_bitmap_length;
+};
+
+int write_update_for_bootloader(
+ const char *update, int update_length,
+ int bitmap_width, int bitmap_height, int bitmap_bpp,
+ const char *busy_bitmap, const char *fail_bitmap,
+ const char *log_filename) {
+ const MtdPartition *part = mtd_find_partition_by_name(CACHE_NAME);
+ if (part == NULL) {
+ LOGE("Can't find %s\n", CACHE_NAME);
+ return -1;
+ }
+
+ MtdWriteContext *write = mtd_write_partition(part);
+ if (write == NULL) {
+ LOGE("Can't open %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ return -1;
+ }
+
+ /* Write an invalid (zero) header first, to disable any previous
+ * update and any other structured contents (like a filesystem),
+ * and as a placeholder for the amount of space required.
+ */
+
+ struct update_header header;
+ memset(&header, 0, sizeof(header));
+ const ssize_t header_size = sizeof(header);
+ if (mtd_write_data(write, (char*) &header, header_size) != header_size) {
+ LOGE("Can't write header to %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ mtd_write_close(write);
+ return -1;
+ }
+
+ /* Write each section individually block-aligned, so we can write
+ * each block independently without complicated buffering.
+ */
+
+ memcpy(&header.MAGIC, UPDATE_MAGIC, UPDATE_MAGIC_SIZE);
+ header.version = UPDATE_VERSION;
+ header.size = header_size;
+
+ if (log_filename != NULL) {
+ // Write 1 byte into the following block, then fill to the end
+ // in order to reserve that block. We'll use the block to
+ // send a copy of the log through to the next invocation of
+ // recovery. We write the log as late as possible in order to
+ // capture any messages emitted by this function.
+ mtd_erase_blocks(write, 0);
+ if (mtd_write_data(write, (char*) &header, 1) != 1) {
+ LOGE("Can't write log block to %s\n(%s)\n",
+ CACHE_NAME, strerror(errno));
+ mtd_write_close(write);
+ return -1;
+ }
+ }
+
+ off_t image_start_pos = mtd_erase_blocks(write, 0);
+ header.image_length = update_length;
+ if ((int) header.image_offset == -1 ||
+ mtd_write_data(write, update, update_length) != update_length) {
+ LOGE("Can't write update to %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ mtd_write_close(write);
+ return -1;
+ }
+ off_t busy_start_pos = mtd_erase_blocks(write, 0);
+ header.image_offset = mtd_find_write_start(write, image_start_pos);
+
+ header.bitmap_width = bitmap_width;
+ header.bitmap_height = bitmap_height;
+ header.bitmap_bpp = bitmap_bpp;
+
+ int bitmap_length = (bitmap_bpp + 7) / 8 * bitmap_width * bitmap_height;
+
+ LOGE("writing busy bitmap\n");
+ header.busy_bitmap_length = busy_bitmap != NULL ? bitmap_length : 0;
+ if ((int) header.busy_bitmap_offset == -1 ||
+ mtd_write_data(write, busy_bitmap, bitmap_length) != bitmap_length) {
+ LOGE("Can't write bitmap to %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ mtd_write_close(write);
+ return -1;
+ }
+ LOGE("busy bitmap written\n");
+ off_t fail_start_pos = mtd_erase_blocks(write, 0);
+ LOGE("block padded\n");
+ header.busy_bitmap_offset = mtd_find_write_start(write, busy_start_pos);
+
+ header.fail_bitmap_length = fail_bitmap != NULL ? bitmap_length : 0;
+ if ((int) header.fail_bitmap_offset == -1 ||
+ mtd_write_data(write, fail_bitmap, bitmap_length) != bitmap_length) {
+ LOGE("Can't write bitmap to %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ mtd_write_close(write);
+ return -1;
+ }
+ LOGE("finishing block\n");
+ mtd_erase_blocks(write, 0);
+ LOGE("finished block\n");
+ header.fail_bitmap_offset = mtd_find_write_start(write, fail_start_pos);
+
+ /* Write the header last, after all the blocks it refers to, so that
+ * when the magic number is installed everything is valid.
+ */
+
+ if (mtd_write_close(write)) {
+ LOGE("Can't finish writing %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ return -1;
+ }
+
+ write = mtd_write_partition(part);
+ if (write == NULL) {
+ LOGE("Can't reopen %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ return -1;
+ }
+
+ if (mtd_write_data(write, (char*) &header, header_size) != header_size) {
+ LOGE("Can't rewrite header to %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ mtd_write_close(write);
+ return -1;
+ }
+
+ if (log_filename != NULL) {
+ LOGE("writing log\n");
+ size_t erase_size;
+ if (mtd_partition_info(part, NULL, &erase_size, NULL) != 0) {
+ LOGE("Error reading block size\n(%s)\n", strerror(errno));
+ mtd_write_close(write);
+ return -1;
+ }
+ mtd_erase_blocks(write, 0);
+
+ if (erase_size > 0) {
+ char* log = malloc(erase_size);
+ FILE* f = fopen(log_filename, "rb");
+ // The fseek() may fail if it tries to go before the
+ // beginning of the log, but that's okay because we want
+ // to be positioned at the start anyway.
+ fseek(f, -(erase_size-sizeof(size_t)-LOG_MAGIC_SIZE), SEEK_END);
+ memcpy(log, LOG_MAGIC, LOG_MAGIC_SIZE);
+ size_t read = fread(log+sizeof(size_t)+LOG_MAGIC_SIZE,
+ 1, erase_size-sizeof(size_t)-LOG_MAGIC_SIZE, f);
+ LOGI("read %d bytes from log\n", (int)read);
+ *(size_t *)(log + LOG_MAGIC_SIZE) = read;
+ fclose(f);
+ if (mtd_write_data(write, log, erase_size) != erase_size) {
+ LOGE("failed to store log in cache partition\n(%s)\n",
+ strerror(errno));
+ mtd_write_close(write);
+ }
+ free(log);
+ }
+ }
+
+ if (mtd_erase_blocks(write, 0) != image_start_pos) {
+ LOGE("Misalignment rewriting %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ mtd_write_close(write);
+ return -1;
+ }
+
+ LOGE("closing partition\n");
+ if (mtd_write_close(write)) {
+ LOGE("Can't finish header of %s\n(%s)\n", CACHE_NAME, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/updater/bootloader.h b/updater/bootloader.h
new file mode 100644
index 0000000..443f206
--- /dev/null
+++ b/updater/bootloader.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#ifndef _RECOVERY_BOOTLOADER_H
+#define _RECOVERY_BOOTLOADER_H
+
+/* Bootloader Message
+ *
+ * This structure describes the content of a block in flash
+ * that is used for recovery and the bootloader to talk to
+ * each other.
+ *
+ * The command field is updated by linux when it wants to
+ * reboot into recovery or to update radio or bootloader firmware.
+ * It is also updated by the bootloader when firmware update
+ * is complete (to boot into recovery for any final cleanup)
+ *
+ * The status field is written by the bootloader after the
+ * completion of an "update-radio" or "update-hboot" command.
+ *
+ * The recovery field is only written by linux and used
+ * for the system to send a message to recovery or the
+ * other way around.
+ */
+struct bootloader_message {
+ char command[32];
+ char status[32];
+ char recovery[1024];
+};
+
+/* Read and write the bootloader command from the "misc" partition.
+ * These return zero on success.
+ */
+int get_bootloader_message(struct bootloader_message *out);
+int set_bootloader_message(const struct bootloader_message *in);
+
+/* Write an update to the cache partition for update-radio or update-hboot.
+ * Note, this destroys any filesystem on the cache partition!
+ * The expected bitmap format is 240x320, 16bpp (2Bpp), RGB 5:6:5.
+ */
+int write_update_for_bootloader(
+ const char *update, int update_len,
+ int bitmap_width, int bitmap_height, int bitmap_bpp,
+ const char *busy_bitmap, const char *error_bitmap,
+ const char *log_filename);
+
+/* Look for a log stored in the cache partition in the block after the
+ * firmware update header. If we can read such a log, copy it to
+ * stdout (ie, the current log).
+ */
+void recover_firmware_update_log();
+
+#define CACHE_NAME "cache"
+#define MISC_NAME "misc"
+
+#define UPDATE_MAGIC "MSM-RADIO-UPDATE"
+#define UPDATE_MAGIC_SIZE 16
+#define UPDATE_VERSION 0x00010000
+
+#define LOG_MAGIC "LOGmagic"
+#define LOG_MAGIC_SIZE 8
+
+
+
+#endif
diff --git a/updater/firmware.c b/updater/firmware.c
new file mode 100644
index 0000000..76b9344
--- /dev/null
+++ b/updater/firmware.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "bootloader.h"
+#include "common.h"
+#include "firmware.h"
+#include "mtdutils/mtdutils.h"
+
+#include <errno.h>
+#include <string.h>
+#include <sys/reboot.h>
+
+/* Bootloader / Recovery Flow
+ *
+ * On every boot, the bootloader will read the bootloader_message
+ * from flash and check the command field. The bootloader should
+ * deal with the command field not having a 0 terminator correctly
+ * (so as to not crash if the block is invalid or corrupt).
+ *
+ * The bootloader will have to publish the partition that contains
+ * the bootloader_message to the linux kernel so it can update it.
+ *
+ * if command == "boot-recovery" -> boot recovery.img
+ * else if command == "update-radio" -> update radio image (below)
+ * else if command == "update-hboot" -> update hboot image (below)
+ * else -> boot boot.img (normal boot)
+ *
+ * Radio/Hboot Update Flow
+ * 1. the bootloader will attempt to load and validate the header
+ * 2. if the header is invalid, status="invalid-update", goto #8
+ * 3. display the busy image on-screen
+ * 4. if the update image is invalid, status="invalid-radio-image", goto #8
+ * 5. attempt to update the firmware (depending on the command)
+ * 6. if successful, status="okay", goto #8
+ * 7. if failed, and the old image can still boot, status="failed-update"
+ * 8. write the bootloader_message, leaving the recovery field
+ * unchanged, updating status, and setting command to
+ * "boot-recovery"
+ * 9. reboot
+ *
+ * The bootloader will not modify or erase the cache partition.
+ * It is recovery's responsibility to clean up the mess afterwards.
+ */
+
+#undef LOGE
+#define LOGE(...) fprintf(stderr, "E:" __VA_ARGS__)
+
+int install_firmware_update(const char *update_type,
+ const char *update_data,
+ size_t update_length,
+ int width, int height, int bpp,
+ const char* busy_image,
+ const char* fail_image,
+ const char *log_filename) {
+ if (update_data == NULL || update_length == 0) return 0;
+
+ mtd_scan_partitions();
+
+ /* We destroy the cache partition to pass the update image to the
+ * bootloader, so all we can really do afterwards is wipe cache and reboot.
+ * Set up this instruction now, in case we're interrupted while writing.
+ */
+
+ struct bootloader_message boot;
+ memset(&boot, 0, sizeof(boot));
+ strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
+ strlcpy(boot.recovery, "recovery\n--wipe_cache\n", sizeof(boot.command));
+ if (set_bootloader_message(&boot)) return -1;
+
+ if (write_update_for_bootloader(
+ update_data, update_length,
+ width, height, bpp, busy_image, fail_image, log_filename)) {
+ LOGE("Can't write %s image\n(%s)\n", update_type, strerror(errno));
+ return -1;
+ }
+
+ /* The update image is fully written, so now we can instruct the bootloader
+ * to install it. (After doing so, it will come back here, and we will
+ * wipe the cache and reboot into the system.)
+ */
+ snprintf(boot.command, sizeof(boot.command), "update-%s", update_type);
+ if (set_bootloader_message(&boot)) {
+ return -1;
+ }
+
+ reboot(RB_AUTOBOOT);
+
+ // Can't reboot? WTF?
+ LOGE("Can't reboot\n");
+ return -1;
+}
diff --git a/updater/firmware.h b/updater/firmware.h
new file mode 100644
index 0000000..7297ecf
--- /dev/null
+++ b/updater/firmware.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#ifndef _RECOVERY_FIRMWARE_H
+#define _RECOVERY_FIRMWARE_H
+
+/* Reboot into the bootloader to install the given update.
+ * Returns 0 if no radio image was defined, nonzero on error,
+ * doesn't return at all on success...
+ */
+int install_firmware_update(const char *update_type,
+ const char *update_data,
+ size_t update_length,
+ int width, int height, int bpp,
+ const char* busy_image,
+ const char* fail_image,
+ const char *log_filename);
+
+#endif
diff --git a/updater/log_recovery.c b/updater/log_recovery.c
new file mode 100644
index 0000000..2c23f6e
--- /dev/null
+++ b/updater/log_recovery.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bootloader.h"
+#include "mtdutils/mtdutils.h"
+
+#define LOGE(...) fprintf(stderr, "E:" __VA_ARGS__)
+
+void recover_firmware_update_log() {
+ printf("recovering log from before firmware update\n");
+
+ mtd_scan_partitions();
+ const MtdPartition *part = mtd_find_partition_by_name(CACHE_NAME);
+ if (part == NULL) {
+ LOGE("Can't find %s\n", CACHE_NAME);
+ return;
+ }
+
+ MtdReadContext* read = mtd_read_partition(part);
+
+ size_t erase_size;
+ if (mtd_partition_info(part, NULL, &erase_size, NULL) != 0) {
+ LOGE("Error reading block size\n(%s)\n", strerror(errno));
+ mtd_read_close(read);
+ return;
+ }
+
+ char* buffer = malloc(erase_size);
+ if (mtd_read_data(read, buffer, erase_size) != erase_size) {
+ LOGE("Error reading header block\n(%s)\n", strerror(errno));
+ mtd_read_close(read);
+ free(buffer);
+ return;
+ }
+ if (mtd_read_data(read, buffer, erase_size) != erase_size) {
+ LOGE("Error reading log block\n(%s)\n", strerror(errno));
+ mtd_read_close(read);
+ free(buffer);
+ return;
+ }
+ mtd_read_close(read);
+
+ if (memcmp(buffer, LOG_MAGIC, LOG_MAGIC_SIZE) != 0) {
+ printf("no log to recover from cache partition\n");
+ free(buffer);
+ return;
+ }
+
+ size_t log_size = *(size_t *)(buffer + LOG_MAGIC_SIZE);
+
+ printf("\n###\n### START RECOVERED LOG\n###\n\n");
+ fwrite(buffer + sizeof(size_t) + LOG_MAGIC_SIZE, 1, log_size, stdout);
+ printf("\n\n###\n### END RECOVERED LOG\n###\n\n");
+
+ free(buffer);
+}
diff --git a/updater/recovery_updater.c b/updater/recovery_updater.c
new file mode 100644
index 0000000..4f2e1cf
--- /dev/null
+++ b/updater/recovery_updater.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "edify/expr.h"
+#include "firmware.h"
+
+char* UpdateFn(const char* name, State* state, int argc, Expr* argv[]) {
+ if (argc != 6) {
+ return ErrorAbort(state, "%s() expects 6 args, got %d", name, argc);
+ }
+
+ char* type = strrchr(name, '_');
+ if (type == NULL || *(type+1) == '\0') {
+ return ErrorAbort(state, "%s() couldn't get type from function name",
+ name);
+ }
+ ++type;
+
+ char* image_string;
+ char* width_string;
+ char* height_string;
+ char* bpp_string;
+ char* busy_string;
+ char* fail_string;
+ if (ReadArgs(state, argv, 6, &image_string,
+ &width_string, &height_string, &bpp_string,
+ &busy_string, &fail_string) < 0) {
+ return NULL;
+ }
+
+ int width = strtol(width_string, NULL, 10);
+ int height = strtol(height_string, NULL, 10);
+ int bpp = strtol(bpp_string, NULL, 10);
+
+ long image_size = *(long *)image_string;
+ if (image_size < 0) {
+ printf("image argument is missing data (length %ld)\n", image_size);
+ goto done;
+ }
+ char* image_data = image_string + sizeof(long);
+
+ long busy_size = *(long *)busy_string;
+ char* busy_data;
+ if (busy_size > 0) {
+ busy_data = busy_string + sizeof(long);
+ } else {
+ busy_data = NULL;
+ }
+
+ long fail_size = *(long *)fail_string;
+ char* fail_data;
+ if (fail_size > 0) {
+ fail_data = fail_string + sizeof(long);
+ } else {
+ fail_data = NULL;
+ }
+
+ install_firmware_update(type, image_data, image_size,
+ width, height, bpp,
+ busy_data, fail_data,
+ "/tmp/recovery.log");
+ printf("%s: install_firmware_update returned!\n", name);
+
+ done:
+ free(image_string);
+ free(width_string);
+ free(height_string);
+ free(bpp_string);
+ free(busy_string);
+ free(fail_string);
+ // install_firmware_update should reboot. If it returns, it failed.
+ return strdup("");
+}
+
+void Register_librecovery_updater_htc() {
+ fprintf(stderr, "installing HTC updater extensions\n");
+
+ RegisterFunction("htc.install_radio", UpdateFn);
+ RegisterFunction("htc.install_hboot", UpdateFn);
+}