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