|
@@ -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);
|