From ff3d93821e22588ce607c17252334ca2d9ca54a4 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Wed, 17 Dec 2008 18:03:49 -0800 Subject: [PATCH] Code drop from //branches/cupcake/...@124589 --- Android.mk | 3 + minui/graphics.c | 57 +++++------ mtdutils/Android.mk | 2 + res/images/icon_firmware_install.bmp | Bin 91076 -> 91076 bytes res/images/icon_installing.bmp | Bin 91076 -> 91076 bytes tools/Android.mk | 1 + tools/ota/Android.mk | 22 ++++ tools/ota/add-property-tag.c | 141 ++++++++++++++++++++++++++ tools/ota/check-lost+found.c | 144 +++++++++++++++++++++++++++ tools/ota/make-update-script.c | 2 +- verifier.c | 4 +- 11 files changed, 341 insertions(+), 35 deletions(-) create mode 100644 tools/Android.mk create mode 100644 tools/ota/add-property-tag.c create mode 100644 tools/ota/check-lost+found.c diff --git a/Android.mk b/Android.mk index b085568..816d143 100644 --- a/Android.mk +++ b/Android.mk @@ -4,6 +4,7 @@ include $(CLEAR_VARS) commands_recovery_local_path := $(LOCAL_PATH) ifneq ($(TARGET_SIMULATOR),true) +ifeq ($(TARGET_ARCH),arm) LOCAL_SRC_FILES := \ recovery.c \ @@ -49,9 +50,11 @@ $(intermediates)/install.o: $(RECOVERY_INSTALL_OTA_KEYS_INC) include $(commands_recovery_local_path)/minui/Android.mk +endif # TARGET_ARCH == arm endif # !TARGET_SIMULATOR include $(commands_recovery_local_path)/amend/Android.mk include $(commands_recovery_local_path)/minzip/Android.mk include $(commands_recovery_local_path)/mtdutils/Android.mk +include $(commands_recovery_local_path)/tools/Android.mk commands_recovery_local_path := diff --git a/minui/graphics.c b/minui/graphics.c index 4f3026a..05e8763 100644 --- a/minui/graphics.c +++ b/minui/graphics.c @@ -57,24 +57,27 @@ static int get_framebuffer(GGLSurface *fb) void *bits; fd = open("/dev/graphics/fb0", O_RDWR); - if(fd < 0) { + if (fd < 0) { perror("cannot open fb0"); return -1; } - if(ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) { + if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) { perror("failed to get fb0 info"); + close(fd); return -1; } - if(ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) { + if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) { perror("failed to get fb0 info"); + close(fd); return -1; } bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if(bits == MAP_FAILED) { + if (bits == MAP_FAILED) { perror("failed to mmap framebuffer"); + close(fd); return -1; } @@ -99,24 +102,14 @@ static int get_framebuffer(GGLSurface *fb) static void set_active_framebuffer(unsigned n) { - if(n > 1) return; + if (n > 1) return; vi.yres_virtual = vi.yres * 2; vi.yoffset = n * vi.yres; - if(ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { - fprintf(stderr,"active fb swap failed!\n"); + if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { + perror("active fb swap failed"); } } -static void dumpinfo(struct fb_var_screeninfo *vi) -{ - fprintf(stderr,"vi.xres = %d\n", vi->xres); - fprintf(stderr,"vi.yres = %d\n", vi->yres); - fprintf(stderr,"vi.xresv = %d\n", vi->xres_virtual); - fprintf(stderr,"vi.yresv = %d\n", vi->yres_virtual); - fprintf(stderr,"vi.xoff = %d\n", vi->xoffset); - fprintf(stderr,"vi.yoff = %d\n", vi->yoffset); -} - void gr_flip(void) { GGLContext *gl = gr_context; @@ -163,7 +156,7 @@ int gr_text(int x, int y, const char *s) while((off = *s++)) { off -= 32; - if(off < 96) { + if (off < 96) { gl->texCoord2i(gl, (off * font->cwidth) - x, 0 - y); gl->recti(gl, x, y, x + font->cwidth, y + font->cheight); } @@ -240,31 +233,29 @@ static void gr_init_font(void) int gr_init(void) { - GGLContext *gl; - int fd; - gglInit(&gr_context); - gl = gr_context; + GGLContext *gl = gr_context; gr_init_font(); - - fd = open("/dev/tty0", O_RDWR | O_SYNC); - if(fd < 0) return -1; - - if(ioctl(fd, KDSETMODE, (void*) KD_GRAPHICS)) { - close(fd); + gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC); + if (gr_vt_fd < 0) { + // This is non-fatal; post-Cupcake kernels don't have tty0. + perror("can't open /dev/tty0"); + } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) { + // However, if we do open tty0, we expect the ioctl to work. + perror("failed KDSETMODE to KD_GRAPHICS on tty0"); + gr_exit(); return -1; } gr_fb_fd = get_framebuffer(gr_framebuffer); - - if(gr_fb_fd < 0) { - ioctl(fd, KDSETMODE, (void*) KD_TEXT); - close(fd); + if (gr_fb_fd < 0) { + gr_exit(); return -1; } - gr_vt_fd = fd; + fprintf(stderr, "framebuffer: fd %d (%d x %d)\n", + gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height); /* start with 0 as front (displayed) and 1 as back (drawing) */ gr_active_fb = 0; diff --git a/mtdutils/Android.mk b/mtdutils/Android.mk index c75eb01..1a75423 100644 --- a/mtdutils/Android.mk +++ b/mtdutils/Android.mk @@ -1,4 +1,5 @@ ifneq ($(TARGET_SIMULATOR),true) +ifeq ($(TARGET_ARCH),arm) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) @@ -18,4 +19,5 @@ LOCAL_STATIC_LIBRARIES := libmtdutils LOCAL_SHARED_LIBRARIES := libcutils libc include $(BUILD_EXECUTABLE) +endif # TARGET_ARCH == arm endif # !TARGET_SIMULATOR diff --git a/res/images/icon_firmware_install.bmp b/res/images/icon_firmware_install.bmp index 7096bf9077ff236ab436a3029bff2a8fb1f0f7a1..b0f5f959b4903d5394280589bb61055cf8933c98 100644 GIT binary patch literal 91076 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 AyZ`_I literal 91076 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 diff --git a/res/images/icon_installing.bmp b/res/images/icon_installing.bmp index 2287170a68d6f713c1d57fa685ff9664949e07a7..fff99fd7e58b882ba65521ea6b42c6e303215a70 100644 GIT binary patch literal 91076 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 R3glgZyep7*1)O{Z{vRubPq6?1 diff --git a/tools/Android.mk b/tools/Android.mk new file mode 100644 index 0000000..6571161 --- /dev/null +++ b/tools/Android.mk @@ -0,0 +1 @@ +include $(all-subdir-makefiles) diff --git a/tools/ota/Android.mk b/tools/ota/Android.mk index 43e2135..b7a57d6 100644 --- a/tools/ota/Android.mk +++ b/tools/ota/Android.mk @@ -18,3 +18,25 @@ include $(CLEAR_VARS) LOCAL_MODULE := make-update-script LOCAL_SRC_FILES := make-update-script.c include $(BUILD_HOST_EXECUTABLE) + +ifneq ($(TARGET_SIMULATOR),true) + +include $(CLEAR_VARS) +LOCAL_FORCE_STATIC_EXECUTABLE := true +LOCAL_MODULE := add-property-tag +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) +LOCAL_MODULE_TAGS := debug +LOCAL_SRC_FILES := add-property-tag.c +LOCAL_STATIC_LIBRARIES := libc +include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) +LOCAL_FORCE_STATIC_EXECUTABLE := true +LOCAL_MODULE := check-lost+found +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) +LOCAL_MODULE_TAGS := debug +LOCAL_SRC_FILES := check-lost+found.c +LOCAL_STATIC_LIBRARIES := libcutils libc +include $(BUILD_EXECUTABLE) + +endif # !TARGET_SIMULATOR diff --git a/tools/ota/add-property-tag.c b/tools/ota/add-property-tag.c new file mode 100644 index 0000000..5277edd --- /dev/null +++ b/tools/ota/add-property-tag.c @@ -0,0 +1,141 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +/* + * Append a tag to a property value in a .prop file if it isn't already there. + * Normally used to modify build properties to record incremental updates. + */ + +// Return nonzero if the tag should be added to this line. +int should_tag(const char *line, const char *propname) { + const char *prop = strstr(line, propname); + if (prop == NULL) return 0; + + // Make sure this is actually the property name (not an accidental hit) + const char *ptr; + for (ptr = line; ptr < prop && isspace(*ptr); ++ptr) ; + if (ptr != prop) return 0; // Must be at the beginning of the line + + for (ptr += strlen(propname); *ptr != '\0' && isspace(*ptr); ++ptr) ; + return (*ptr == '='); // Must be followed by a '=' +} + +// Remove existing tags from the line, return the following number (if any) +int remove_tag(char *line, const char *tag) { + char *pos = strstr(line, tag); + if (pos == NULL) return 0; + + char *end; + int num = strtoul(pos + strlen(tag), &end, 10); + strcpy(pos, end); + return num; +} + +// Write line to output with the tag added, adding a number (if >0) +void write_tagged(FILE *out, const char *line, const char *tag, int number) { + const char *end = line + strlen(line); + while (end > line && isspace(end[-1])) --end; + if (number > 0) { + fprintf(out, "%.*s%s%d%s", end - line, line, tag, number, end); + } else { + fprintf(out, "%.*s%s%s", end - line, line, tag, end); + } +} + +int main(int argc, char **argv) { + const char *filename = "/system/build.prop"; + const char *propname = "ro.build.fingerprint"; + const char *tag = NULL; + int do_remove = 0, do_number = 0; + + int opt; + while ((opt = getopt(argc, argv, "f:p:rn")) != -1) { + switch (opt) { + case 'f': filename = optarg; break; + case 'p': propname = optarg; break; + case 'r': do_remove = 1; break; + case 'n': do_number = 1; break; + case '?': return 2; + } + } + + if (argc != optind + 1) { + fprintf(stderr, + "usage: add-property-tag [flags] tag-to-add\n" + "flags: -f /dir/file.prop (default /system/build.prop)\n" + " -p prop.name (default ro.build.fingerprint)\n" + " -r (if set, remove the tag rather than adding it)\n" + " -n (if set, add and increment a number after the tag)\n"); + return 2; + } + + tag = argv[optind]; + FILE *input = fopen(filename, "r"); + if (input == NULL) { + fprintf(stderr, "can't read %s: %s\n", filename, strerror(errno)); + return 1; + } + + char tmpname[PATH_MAX]; + snprintf(tmpname, sizeof(tmpname), "%s.tmp", filename); + FILE *output = fopen(tmpname, "w"); + if (output == NULL) { + fprintf(stderr, "can't write %s: %s\n", tmpname, strerror(errno)); + return 1; + } + + int found = 0; + char line[4096]; + while (fgets(line, sizeof(line), input)) { + if (!should_tag(line, propname)) { + fputs(line, output); // Pass through unmodified + } else { + found = 1; + int number = remove_tag(line, tag); + if (do_remove) { + fputs(line, output); // Remove the tag but don't re-add it + } else { + write_tagged(output, line, tag, number + do_number); + } + } + } + + fclose(input); + fclose(output); + + if (!found) { + fprintf(stderr, "property %s not found in %s\n", propname, filename); + remove(tmpname); + return 1; + } + + if (rename(tmpname, filename)) { + fprintf(stderr, "can't rename %s to %s: %s\n", + tmpname, filename, strerror(errno)); + remove(tmpname); + return 1; + } + + return 0; +} diff --git a/tools/ota/check-lost+found.c b/tools/ota/check-lost+found.c new file mode 100644 index 0000000..f856275 --- /dev/null +++ b/tools/ota/check-lost+found.c @@ -0,0 +1,144 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "private/android_filesystem_config.h" + +// Sentinel file used to track whether we've forced a reboot +static const char *kMarkerFile = "/data/misc/check-lost+found-rebooted-2"; + +// Output file in tombstones directory (first 8K will be uploaded) +static const char *kOutputDir = "/data/tombstones"; +static const char *kOutputFile = "/data/tombstones/check-lost+found-log"; + +// Partitions to check +static const char *kPartitions[] = { "/system", "/data", "/cache", NULL }; + +/* + * 1. If /data/misc/forced-reboot is missing, touch it & force "unclean" boot. + * 2. Write a log entry with the number of files in lost+found directories. + */ + +int main(int argc, char **argv) { + mkdir(kOutputDir, 0755); + chown(kOutputDir, AID_SYSTEM, AID_SYSTEM); + FILE *out = fopen(kOutputFile, "a"); + if (out == NULL) { + fprintf(stderr, "Can't write %s: %s\n", kOutputFile, strerror(errno)); + return 1; + } + + // Note: only the first 8K of log will be uploaded, so be terse. + time_t start = time(NULL); + fprintf(out, "*** check-lost+found ***\nStarted: %s", ctime(&start)); + + struct stat st; + if (stat(kMarkerFile, &st)) { + // No reboot marker -- need to force an unclean reboot. + // But first, try to create the marker file. If that fails, + // skip the reboot, so we don't get caught in an infinite loop. + + int fd = open(kMarkerFile, O_WRONLY|O_CREAT, 0444); + if (fd >= 0 && close(fd) == 0) { + fprintf(out, "Wrote %s, rebooting\n", kMarkerFile); + fflush(out); + sync(); // Make sure the marker file is committed to disk + + // If possible, dirty each of these partitions before rebooting, + // to make sure the filesystem has to do a scan on mount. + int i; + for (i = 0; kPartitions[i] != NULL; ++i) { + char fn[PATH_MAX]; + snprintf(fn, sizeof(fn), "%s/%s", kPartitions[i], "dirty"); + fd = open(fn, O_WRONLY|O_CREAT, 0444); + if (fd >= 0) { // Don't sweat it if we can't write the file. + write(fd, fn, sizeof(fn)); // write, you know, some data + close(fd); + unlink(fn); + } + } + + reboot(RB_AUTOBOOT); // reboot immediately, with dirty filesystems + fprintf(out, "Reboot failed?!\n"); + exit(1); + } else { + fprintf(out, "Can't write %s: %s\n", kMarkerFile, strerror(errno)); + } + } else { + fprintf(out, "Found %s\n", kMarkerFile); + } + + int i; + for (i = 0; kPartitions[i] != NULL; ++i) { + char fn[PATH_MAX]; + snprintf(fn, sizeof(fn), "%s/%s", kPartitions[i], "lost+found"); + DIR *dir = opendir(fn); + if (dir == NULL) { + fprintf(out, "Can't open %s: %s\n", fn, strerror(errno)); + } else { + int count = 0; + struct dirent *ent; + while ((ent = readdir(dir))) { + if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..")) + ++count; + } + closedir(dir); + if (count > 0) { + fprintf(out, "OMGZ FOUND %d FILES IN %s\n", count, fn); + } else { + fprintf(out, "%s is clean\n", fn); + } + } + } + + char dmesg[131073]; + int len = klogctl(KLOG_READ_ALL, dmesg, sizeof(dmesg) - 1); + if (len < 0) { + fprintf(out, "Can't read kernel log: %s\n", strerror(errno)); + } else { // To conserve space, only write lines with certain keywords + fprintf(out, "--- Kernel log ---\n"); + dmesg[len] = '\0'; + char *saveptr, *line; + int in_yaffs = 0; + for (line = strtok_r(dmesg, "\n", &saveptr); line != NULL; + line = strtok_r(NULL, "\n", &saveptr)) { + if (strstr(line, "yaffs: dev is")) in_yaffs = 1; + + if (in_yaffs || + strstr(line, "yaffs") || + strstr(line, "mtd") || + strstr(line, "msm_nand")) { + fprintf(out, "%s\n", line); + } + + if (strstr(line, "yaffs_read_super: isCheckpointed")) in_yaffs = 0; + } + } + + return 0; +} diff --git a/tools/ota/make-update-script.c b/tools/ota/make-update-script.c index 0fb7ed0..225dc52 100644 --- a/tools/ota/make-update-script.c +++ b/tools/ota/make-update-script.c @@ -171,7 +171,7 @@ int main(int argc, char *argv[]) { printf("assert compatible_with(\"0.2\") == \"true\"\n"); // if known, make sure the device name is correct - const char *device = getenv("TARGET_PRODUCT"); + const char *device = getenv("TARGET_DEVICE"); if (device != NULL) { printf("assert getprop(\"ro.product.device\") == \"%s\" || " "getprop(\"ro.build.product\") == \"%s\"\n", device, device); diff --git a/verifier.c b/verifier.c index 67a4f39..1180ae8 100644 --- a/verifier.c +++ b/verifier.c @@ -126,13 +126,15 @@ static const ZipEntry *verifySignature(const ZipArchive *pArchive, strncpy(sfName, rsaName.str, rsaName.len - sizeof(rsa) + 1); strcpy(sfName + rsaName.len - sizeof(rsa) + 1, sf); const ZipEntry *sfEntry = mzFindZipEntry(pArchive, sfName); - free(sfName); if (sfEntry == NULL) { LOGW("Missing signature file %s\n", sfName); + free(sfName); continue; } + free(sfName); + uint8_t sfDigest[SHA_DIGEST_SIZE]; if (!digestEntry(pArchive, sfEntry, NULL, 0, sfDigest)) continue;