diff options
-rw-r--r-- | tools/firmware-utils/src/fw.h | 8 | ||||
-rw-r--r-- | tools/firmware-utils/src/mkfwimage.c | 168 |
2 files changed, 129 insertions, 47 deletions
diff --git a/tools/firmware-utils/src/fw.h b/tools/firmware-utils/src/fw.h index e37859c52d..44f8d851d2 100644 --- a/tools/firmware-utils/src/fw.h +++ b/tools/firmware-utils/src/fw.h @@ -24,6 +24,7 @@ #define MAGIC_HEADER "OPEN" #define MAGIC_PART "PART" #define MAGIC_END "END." +#define MAGIC_ENDS "ENDS" #define MAGIC_LENGTH 4 @@ -57,6 +58,13 @@ typedef struct signature { u_int32_t pad; } __attribute__ ((packed)) signature_t; +typedef struct signature_rsa { + char magic[MAGIC_LENGTH]; +// u_int32_t crc; + unsigned char rsa_signature[256]; + u_int32_t pad; +} __attribute__ ((packed)) signature_rsa_t; + #define VERSION "1.2" #define INFO(...) fprintf(stdout, __VA_ARGS__) diff --git a/tools/firmware-utils/src/mkfwimage.c b/tools/firmware-utils/src/mkfwimage.c index d8d5239cc5..2b84d3db53 100644 --- a/tools/firmware-utils/src/mkfwimage.c +++ b/tools/firmware-utils/src/mkfwimage.c @@ -29,65 +29,106 @@ #include <stdio.h> #include <stdlib.h> #include <limits.h> +#include <stdbool.h> #include "fw.h" typedef struct fw_layout_data { - char name[PATH_MAX]; u_int32_t kern_start; u_int32_t kern_entry; u_int32_t firmware_max_length; } fw_layout_t; -fw_layout_t fw_layout_data[] = { +struct fw_info { + char name[PATH_MAX]; + struct fw_layout_data fw_layout; + bool sign; +}; + +struct fw_info fw_info[] = { { - .name = "XS2", - .kern_start = 0xbfc30000, - .kern_entry = 0x80041000, - .firmware_max_length= 0x00390000, + .name = "XS2", + .fw_layout = { + .kern_start = 0xbfc30000, + .kern_entry = 0x80041000, + .firmware_max_length= 0x00390000, + }, + .sign = false, }, { - .name = "XS5", - .kern_start = 0xbe030000, - .kern_entry = 0x80041000, - .firmware_max_length= 0x00390000, + .name = "XS5", + .fw_layout = { + .kern_start = 0xbe030000, + .kern_entry = 0x80041000, + .firmware_max_length= 0x00390000, + }, + .sign = false, }, { - .name = "RS", - .kern_start = 0xbf030000, - .kern_entry = 0x80060000, - .firmware_max_length= 0x00B00000, + .name = "RS", + .fw_layout = { + .kern_start = 0xbf030000, + .kern_entry = 0x80060000, + .firmware_max_length= 0x00B00000, + }, + .sign = false, }, { - .name = "RSPRO", - .kern_start = 0xbf030000, - .kern_entry = 0x80060000, - .firmware_max_length= 0x00F00000, + .name = "RSPRO", + .fw_layout = { + .kern_start = 0xbf030000, + .kern_entry = 0x80060000, + .firmware_max_length= 0x00F00000, + }, + .sign = false, }, { - .name = "LS-SR71", - .kern_start = 0xbf030000, - .kern_entry = 0x80060000, - .firmware_max_length= 0x00640000, + .name = "LS-SR71", + .fw_layout = { + .kern_start = 0xbf030000, + .kern_entry = 0x80060000, + .firmware_max_length= 0x00640000, + }, + .sign = false, }, { - .name = "XS2-8", - .kern_start = 0xa8030000, - .kern_entry = 0x80041000, - .firmware_max_length= 0x006C0000, + .name = "XS2-8", + .fw_layout = { + .kern_start = 0xa8030000, + .kern_entry = 0x80041000, + .firmware_max_length= 0x006C0000, + }, + .sign = false, + }, { - .name = "XM", - .kern_start = 0x9f050000, - .kern_entry = 0x80002000, - .firmware_max_length= 0x00760000, + .name = "XM", + .fw_layout = { + .kern_start = 0x9f050000, + .kern_entry = 0x80002000, + .firmware_max_length= 0x00760000, + }, + .sign = false, }, { - .name = "UBDEV01", - .kern_start = 0x9f050000, - .kern_entry = 0x80002000, - .firmware_max_length= 0x006A0000, + .name = "UBDEV01", + .fw_layout = { + .kern_start = 0x9f050000, + .kern_entry = 0x80002000, + .firmware_max_length= 0x006A0000, + }, + .sign = false, }, - { .name = "", + { + .name = "WA", + .fw_layout = { + .kern_start = 0x9f050000, + .kern_entry = 0x80002000, + .firmware_max_length= 0x00F60000, + }, + .sign = true, + }, + { + .name = "", }, }; @@ -116,8 +157,20 @@ typedef struct image_info { char outputfile[PATH_MAX]; u_int32_t part_count; part_data_t parts[MAX_SECTIONS]; + struct fw_info* fwinfo; } image_info_t; +static struct fw_info* get_fwinfo(char* board_name) { + struct fw_info *fwinfo = fw_info; + while(strlen(fwinfo->name)) { + if(strcmp(fwinfo->name, board_name) == 0) { + return fwinfo; + } + fwinfo++; + } + return NULL; +} + static void write_header(void* mem, const char *magic, const char* version) { header_t* header = mem; @@ -142,6 +195,17 @@ static void write_signature(void* mem, u_int32_t sig_offset) sign->pad = 0L; } +static void write_signature_rsa(void* mem, u_int32_t sig_offset) +{ + /* write signature */ + signature_rsa_t* sign = (signature_rsa_t*)(mem + sig_offset); + memset(sign, 0, sizeof(signature_rsa_t)); + + memcpy(sign->magic, MAGIC_ENDS, MAGIC_LENGTH); +// sign->crc = htonl(crc32(0L,(unsigned char *)mem, sig_offset)); + sign->pad = 0L; +} + static int write_part(void* mem, part_data_t* d) { char* addr; @@ -237,17 +301,9 @@ static int create_image_layout(const char* kernelfile, const char* rootfsfile, c part_data_t* kernel = &im->parts[0]; part_data_t* rootfs = &im->parts[1]; - fw_layout_t* p; + fw_layout_t* p = &im->fwinfo->fw_layout; - p = &fw_layout_data[0]; - while (*p->name && (strcmp(p->name, board_name) != 0)) - p++; - if (!*p->name) { - printf("BUG! Unable to find default fw layout!\n"); - exit(-1); - } - - printf("board = %s\n", p->name); + printf("board = %s\n", im->fwinfo->name); strcpy(kernel->partition_name, "kernel"); kernel->partition_index = 1; kernel->partition_baseaddr = p->kern_start; @@ -330,7 +386,12 @@ static int build_image(image_info_t* im) int i; // build in-memory buffer - mem_size = sizeof(header_t) + sizeof(signature_t); + mem_size = sizeof(header_t); + if(im->fwinfo->sign) { + mem_size += sizeof(signature_rsa_t); + } else { + mem_size += sizeof(signature_t); + } for (i = 0; i < im->part_count; ++i) { part_data_t* d = &im->parts[i]; @@ -359,7 +420,11 @@ static int build_image(image_info_t* im) ptr += sizeof(part_t) + d->stats.st_size + sizeof(part_crc_t); } // write signature - write_signature(mem, mem_size - sizeof(signature_t)); + if(im->fwinfo->sign) { + write_signature_rsa(mem, mem_size - sizeof(signature_rsa_t)); + } else { + write_signature(mem, mem_size - sizeof(signature_t)); + } // write in-memory buffer into file if ((f = fopen(im->outputfile, "w")) == NULL) @@ -388,6 +453,7 @@ int main(int argc, char* argv[]) char board_name[PATH_MAX]; int o, rc; image_info_t im; + struct fw_info *fwinfo; memset(&im, 0, sizeof(im)); memset(kernelfile, 0, sizeof(kernelfile)); @@ -447,6 +513,14 @@ int main(int argc, char* argv[]) return -2; } + if ((fwinfo = get_fwinfo(board_name)) == NULL) { + ERROR("Invalid baord name '%s'\n", board_name); + usage(argv[0]); + return -2; + } + + im.fwinfo = fwinfo; + if ((rc = create_image_layout(kernelfile, rootfsfile, board_name, &im)) != 0) { ERROR("Failed creating firmware layout description - error code: %d\n", rc); |