[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/lib/bootimage/bootimage.c b/src/bsp/lk/lib/bootimage/bootimage.c
new file mode 100644
index 0000000..436d19c
--- /dev/null
+++ b/src/bsp/lk/lib/bootimage/bootimage.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2014 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <lib/bootimage.h>
+#include <trace.h>
+#include <err.h>
+#include <debug.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lib/bootimage_struct.h>
+#include <lib/mincrypt/sha256.h>
+
+#define LOCAL_TRACE 1
+
+struct bootimage {
+ const uint8_t *ptr;
+ size_t len;
+};
+
+static status_t validate_bootimage(bootimage_t *bi)
+{
+ if (!bi)
+ return ERR_INVALID_ARGS;
+
+ /* is it large enough to hold the first entry */
+ if (bi->len < 4096) {
+ LTRACEF("bootentry too short\n");
+ return ERR_BAD_LEN;
+ }
+
+ bootentry *be = (bootentry *)bi->ptr;
+
+ /* check that the first entry is a file, type boot info, and is 4096 bytes at offset 0 */
+ if (be->kind != KIND_FILE ||
+ be->file.type != TYPE_BOOT_IMAGE ||
+ be->file.offset != 0 ||
+ be->file.length != 4096 ||
+ memcmp(be->file.name, BOOT_MAGIC, sizeof(be->file.name))) {
+ LTRACEF("invalid first entry\n");
+ return ERR_INVALID_ARGS;
+ }
+
+ /* check the sha256 of the rest of the first page */
+ SHA256_CTX ctx;
+ SHA256_init(&ctx);
+
+ SHA256_update(&ctx, be + 1, 4096 - sizeof(bootentry));
+ const uint8_t *hash = SHA256_final(&ctx);
+
+ if (memcmp(hash, be->file.sha256, sizeof(be->file.sha256)) != 0) {
+ LTRACEF("bad hash of first section\n");
+
+ return ERR_CHECKSUM_FAIL;
+ }
+
+ /* look at the second entry, which should be a boot info structure */
+ if (be[1].kind != KIND_BOOT_INFO) {
+ LTRACEF("second entry not boot info\n");
+ return ERR_INVALID_ARGS;
+ }
+
+ bootentry_info *info = &be[1].info;
+
+ /* is the image a handled version */
+ if (info->version > BOOT_VERSION) {
+ LTRACEF("unhandled version 0x%x\n", info->version);
+ return ERR_INVALID_ARGS;
+ }
+
+ /* is the image the right size? */
+ if (info->image_size > bi->len) {
+ LTRACEF("boot image block says image is too big (0x%x bytes)\n", info->image_size);
+ return ERR_INVALID_ARGS;
+ }
+
+ /* trim the len to what the info block says */
+ bi->len = info->image_size;
+
+ /* iterate over the remaining entries in the list */
+ for (size_t i = 2; i < info->entry_count; i++) {
+ if (be[i].kind == 0)
+ break;
+
+ LTRACEF("%u: kind 0x%x\n", i, be[i].kind);
+
+ switch (be[i].kind) {
+ case KIND_BOOT_INFO:
+ break;
+ case KIND_BOARD:
+ break;
+ case KIND_BUILD:
+ break;
+ case KIND_FILE: {
+ LTRACEF("\ttype %c%c%c%c offset 0x%x, length 0x%x\n",
+ (be[i].file.type >> 0) & 0xff, (be[i].file.type >> 8) & 0xff,
+ (be[i].file.type >> 16) & 0xff, (be[i].file.type >> 24) & 0xff,
+ be[i].file.offset, be[i].file.length);
+
+ /* check that the file section is inside the overall image */
+ uint32_t end = be[i].file.offset + be[i].file.length;
+ if (end < be[i].file.offset || end > info->image_size) {
+ LTRACEF("bad file section, size too large\n");
+ return ERR_INVALID_ARGS;
+ }
+
+ /* check the sha256 hash */
+ SHA256_init(&ctx);
+
+ LTRACEF("\tvalidating SHA256 hash\n");
+ SHA256_update(&ctx, (const uint8_t *)bi->ptr + be[i].file.offset, be[i].file.length);
+ const uint8_t *hash = SHA256_final(&ctx);
+
+ if (memcmp(hash, be[i].file.sha256, sizeof(be[i].file.sha256)) != 0) {
+ LTRACEF("bad hash of file section\n");
+
+ return ERR_CHECKSUM_FAIL;
+ }
+
+ break;
+ }
+ default:
+ LTRACEF("unknown kind 0x%x\n", be[i].kind);
+ return ERR_INVALID_ARGS;
+ }
+ }
+
+ LTRACEF("image good\n");
+ return NO_ERROR;
+}
+
+status_t bootimage_open(const void *ptr, size_t len, bootimage_t **bi)
+{
+ LTRACEF("ptr %p, len %zu\n", ptr, len);
+
+ if (!bi)
+ return ERR_INVALID_ARGS;
+
+ *bi = calloc(1, sizeof(bootimage_t));
+ if (!*bi)
+ return ERR_NO_MEMORY;
+
+ (*bi)->ptr = ptr;
+ (*bi)->len = len;
+
+ /* try to validate it */
+ status_t err = validate_bootimage(*bi);
+ if (err < 0) {
+ bootimage_close(*bi);
+ return err;
+ }
+
+ return NO_ERROR;
+}
+
+status_t bootimage_close(bootimage_t *bi)
+{
+ if (bi)
+ free(bi);
+
+ return NO_ERROR;
+}
+
+status_t bootimage_get_range(bootimage_t *bi, const void **ptr, size_t *len)
+{
+ if (!bi)
+ return ERR_INVALID_ARGS;
+
+ if (ptr)
+ *ptr = bi->ptr;
+ if (len)
+ *len = bi->len;
+
+ return NO_ERROR;
+}
+
+status_t bootimage_get_file_section(bootimage_t *bi, uint32_t type, const void **ptr, size_t *len)
+{
+ if (!bi)
+ return ERR_INVALID_ARGS;
+
+ bootentry *be = (bootentry *)bi->ptr;
+ bootentry_info *info = &be[1].info;
+
+ for (size_t i = 2; i < info->entry_count; i++) {
+ if (be[i].kind == 0)
+ break;
+
+ if (be[i].kind != KIND_FILE)
+ continue;
+
+ if (type == be[i].file.type) {
+ if (ptr)
+ *ptr = bi->ptr + be[i].file.offset;
+ if (len)
+ *len = be[i].file.length;
+ return NO_ERROR;
+ }
+ }
+
+ return ERR_NOT_FOUND;
+}
+
diff --git a/src/bsp/lk/lib/bootimage/include/lib/bootimage.h b/src/bsp/lk/lib/bootimage/include/lib/bootimage.h
new file mode 100644
index 0000000..2318048
--- /dev/null
+++ b/src/bsp/lk/lib/bootimage/include/lib/bootimage.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#pragma once
+
+#include <sys/types.h>
+#include <compiler.h>
+#include <lib/bootimage_struct.h>
+
+typedef struct bootimage bootimage_t;
+
+status_t bootimage_open(const void *ptr, size_t len, bootimage_t **bi) __NONNULL();
+status_t bootimage_close(bootimage_t *bi) __NONNULL();
+status_t bootimage_get_range(bootimage_t *bi, const void **ptr, size_t *len) __NONNULL((1));
+
+/* ask for a file section of the bootimage, by type */
+status_t bootimage_get_file_section(bootimage_t *bi, uint32_t type, const void **ptr, size_t *len) __NONNULL((1));
+
diff --git a/src/bsp/lk/lib/bootimage/include/lib/bootimage_struct.h b/src/bsp/lk/lib/bootimage/include/lib/bootimage_struct.h
new file mode 100644
index 0000000..a59768e
--- /dev/null
+++ b/src/bsp/lk/lib/bootimage/include/lib/bootimage_struct.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014 Brian Swetland
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+typedef struct {
+ uint32_t kind;
+ uint32_t type;
+ uint32_t offset; /* byte offset from start of file */
+ uint32_t length; /* length in bytes */
+ uint8_t name[16];
+ uint8_t sha256[32];
+} __attribute__ ((packed)) bootentry_file;
+
+typedef struct {
+ uint32_t kind;
+ union {
+ uint32_t u[15];
+ uint8_t b[60];
+ } __attribute__((packed)) u;
+} __attribute__((packed)) bootentry_data;
+
+typedef struct {
+ uint32_t kind;
+ uint32_t version; /* bootimage version */
+ uint32_t image_size; /* byte size of entire image */
+ uint32_t entry_count; /* number of valid bootentries */
+ uint32_t reserved[12];
+} __attribute__((packed)) bootentry_info;
+
+typedef union {
+ uint32_t kind;
+ bootentry_file file;
+ bootentry_data data;
+ bootentry_info info;
+} bootentry;
+
+#define BOOT_VERSION 0x00010000 /* 1.0 */
+
+#define BOOT_MAGIC "<lk-boot-image>"
+#define BOOT_MAGIC_LENGTH 16
+
+// header (bootentry_file, but special):
+
+// bootentry kinds:
+#define KIND_FILE 0x656c6966 // 'file'
+#define KIND_BOOT_INFO 0x6f666e69 // 'info'
+#define KIND_BOARD 0x67726174 // 'targ' board id string
+#define KIND_BUILD 0x706d7473 // 'stmp' build id string
+
+// bootentry_file types:
+#define TYPE_BOOT_IMAGE 0x746f6f62 // 'boot'
+#define TYPE_LK 0x6b6c6b6c // 'lklk'
+#define TYPE_FPGA_IMAGE 0x61677066 // 'fpga'
+#define TYPE_LINUX_KERNEL 0x6b78636c // 'lcxk'
+#define TYPE_LINUX_INITRD 0x64697264 // 'drid'
+#define TYPE_DEVICE_TREE 0x74766564 // 'devt'
+#define TYPE_SYSPARAMS 0x70737973 // 'sysp'
+#define TYPE_UNKNOWN 0x6e6b6e75 // 'unkn'
+
+// first entry must be:
+// kind: KIND_FILE
+// type: TYPE_BOOT_IMAGE
+// offset: 0
+// length: 4096
+// name: BOOT_MAGIC
+// sha256: of bootentry[1..63]
+
+// second entry must be:
+// kind: KIND_BOOT_INFO
+
+// offsets should be multiple-of-4096
diff --git a/src/bsp/lk/lib/bootimage/rules.mk b/src/bsp/lk/lib/bootimage/rules.mk
new file mode 100644
index 0000000..e75cfce
--- /dev/null
+++ b/src/bsp/lk/lib/bootimage/rules.mk
@@ -0,0 +1,11 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_DEPS := \
+ lib/mincrypt
+
+MODULE_SRCS := \
+ $(LOCAL_DIR)/bootimage.c
+
+include make/module.mk