From 7215c0181e234f31f8970d9d8953ea7850d9f3de Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Fri, 9 Feb 2018 10:54:00 +0100 Subject: [PATCH 1/1] firmware: update for 64bit platforms --- src/.gitignore | 4 ++ src/filesystem.c | 53 ++++++++++++----------- src/filesystem.h | 16 +++---- src/firmware.c | 94 ++++++++++++++++++++-------------------- src/rsb-crc.c | 21 ++++----- src/rsb-crc.h | 4 +- src/rsb-lz.c | 109 ++++++++++++++++++++++++----------------------- src/rsb-lz.h | 4 +- 8 files changed, 157 insertions(+), 148 deletions(-) diff --git a/src/.gitignore b/src/.gitignore index 8112a8e..845cfdb 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,5 +1,9 @@ +filesystem.d filesystem.o firmware +firmware.d firmware.o +rsb-crc.d rsb-crc.o +rsb-lz.d rsb-lz.o diff --git a/src/filesystem.c b/src/filesystem.c index ef26de4..da3cf76 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,22 +13,22 @@ #include "rsb-lz.h" #include "filesystem.h" -struct file_entry* get_next_file(unsigned char *fw, int len) +struct file_entry* get_next_file(uint8_t *fw, int32_t len) { - static unsigned char *pos; - static unsigned char *start; - static unsigned char *end; + static uint8_t *pos; + static uint8_t *start; + static uint8_t *end; static struct file_entry fent; - int name_length; + int32_t name_length; if (fw != NULL && len != 0) { pos = fw + 0x28; #if 0 - printf("Start of filesystem: 0x%08x\n", *((unsigned int*)pos)); + printf("Start of filesystem: 0x%08x\n", *((uint32_t*)pos)); #endif start = fw; - pos = fw + *((unsigned int*)pos); + pos = fw + *((uint32_t*)pos); end = fw + len; } @@ -36,8 +37,8 @@ struct file_entry* get_next_file(unsigned char *fw, int len) if (fent.unknown == 0x00) { /* EOF */ - int fill = (4 - ((pos - start) % 4)) % 4; - int i; + int32_t fill = (4 - ((pos - start) % 4)) % 4; + int32_t i; for (i = 0; i < fill; i++) { if (*pos != 0xff) { @@ -56,10 +57,10 @@ struct file_entry* get_next_file(unsigned char *fw, int len) } - name_length = *((unsigned int*)pos); + name_length = *((uint32_t*)pos); pos += 4; - fent.length = *((unsigned int*)pos); + fent.length = *((uint32_t*)pos); pos += 4; if ((fent.length > (end - pos)) || @@ -79,7 +80,7 @@ struct file_entry* get_next_file(unsigned char *fw, int len) return &fent; } -void extract_files(unsigned char *fw, int len) +void extract_files(uint8_t *fw, int32_t len) { struct file_entry *fent; @@ -91,10 +92,10 @@ void extract_files(unsigned char *fw, int len) if (fent->length > 0) { write_file(extracted_file(fent->name), fent->start, fent->length); - if (*((unsigned int*)fent->start) == LZ_MAGIC) { + if (*((uint32_t*)fent->start) == LZ_MAGIC) { char *lzname; - unsigned char *outbuf; - unsigned int outlen; + uint8_t *outbuf; + uint32_t outlen; if ((lzname = strdup(fent->name)) == NULL) { perror("strdup"); @@ -115,18 +116,18 @@ void extract_files(unsigned char *fw, int len) free(outbuf); free(lzname); } else if (!strcmp(fent->name, "firmware")) { - unsigned char *lzpos; + uint8_t *lzpos; char lzname[128]; bzero(lzname, sizeof(lzname)); strcpy(lzname, "firmware."); - lzpos = fent->start + *((unsigned int*)(fent->start + 0x20)); + lzpos = fent->start + *((uint32_t*)(fent->start + 0x20)); memcpy(lzname + strlen(lzname), lzpos - 4, 4); lzpos += 4; - if (*((unsigned int*)(lzpos)) == LZ_MAGIC) { - unsigned char *outbuf; - unsigned int outlen; + if (*((uint32_t*)(lzpos)) == LZ_MAGIC) { + uint8_t *outbuf; + uint32_t outlen; printf("%s: compressed firmware part found", lzname); outbuf = extract_lz_file(lzpos, &outlen, 1); @@ -143,13 +144,13 @@ void extract_files(unsigned char *fw, int len) } } -void replace_add_file(unsigned char *fw, int len, char *fwname, char *lname) +void replace_add_file(uint8_t *fw, int32_t len, char *fwname, char *lname) { fprintf(stderr, "%s: Implement me!\n", __func__); exit(1); } -void list_files(unsigned char *fw, int len) +void list_files(uint8_t *fw, int32_t len) { struct file_entry *fent; @@ -185,12 +186,12 @@ void mkdir_p(char *dir) free(parent); } -void write_file(char *fname, unsigned char *buf, int len) +void write_file(char *fname, uint8_t *buf, int32_t len) { char *filename_c, *dirn; - int fd; - int remaining; - int ret; + int32_t fd; + int32_t remaining; + int32_t ret; if ((filename_c = strdup(fname)) == NULL) { perror("strdup"); diff --git a/src/filesystem.h b/src/filesystem.h index bf9a4c8..25cf1e4 100644 --- a/src/filesystem.h +++ b/src/filesystem.h @@ -1,13 +1,13 @@ struct file_entry { char *name; - unsigned char *start; - int length; - unsigned char unknown; + uint8_t *start; + int32_t length; + uint8_t unknown; }; -struct file_entry* get_next_file(unsigned char *fw, int len); -void extract_files(unsigned char *fw, int len); -void replace_add_file(unsigned char *fw, int len, char *fwname, char *lname); -void list_files(unsigned char *fw, int len); -void write_file(char *fname, unsigned char *buf, int len); +struct file_entry* get_next_file(uint8_t *fw, int32_t len); +void extract_files(uint8_t *fw, int32_t len); +void replace_add_file(uint8_t *fw, int32_t len, char *fwname, char *lname); +void list_files(uint8_t *fw, int32_t len); +void write_file(char *fname, uint8_t *buf, int32_t len); char *extracted_file(char *fname); diff --git a/src/firmware.c b/src/firmware.c index b575012..533f04d 100644 --- a/src/firmware.c +++ b/src/firmware.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -13,17 +14,17 @@ #define FINDSTR(addr, str) (!strncmp((char*)addr, str, strlen(str))) struct properties { - unsigned int magic; - unsigned char unknown0; - unsigned char unknown1; - unsigned char right_rw; - unsigned char rw_mask; - unsigned char type1; - unsigned char unknown5; - unsigned char unknown6; - unsigned char unknown7; - unsigned char type2; - unsigned char val[]; + uint32_t magic; + uint8_t unknown0; + uint8_t unknown1; + uint8_t right_rw; + uint8_t rw_mask; + uint8_t type1; + uint8_t unknown5; + uint8_t unknown6; + uint8_t unknown7; + uint8_t type2; + uint8_t val[]; }; #define PROP_ACTION_TRUE (1<<0) @@ -39,12 +40,12 @@ struct properties { struct propaction { char *property; - unsigned int action; - unsigned int status; + uint32_t action; + uint32_t status; struct propaction *next; }; -void show_properties(unsigned char *fw, int len) +void show_properties(uint8_t *fw, int32_t len) { struct file_entry *fent; @@ -54,7 +55,7 @@ void show_properties(unsigned char *fw, int len) FINDSTR(fent->name, "/default/oem_prop/")) { struct properties *prop; - printf("0x%08x: found setting: %s ", fent->start - fw, fent->name); + printf("0x%08x: found setting: %s ", (uint32_t)(fent->start - fw), fent->name); prop = (struct properties*)fent->start; @@ -68,7 +69,10 @@ void show_properties(unsigned char *fw, int len) } else if (prop->type1 == 0x01 && prop->type2 == 0x01) { printf("BOOL: %s ",(*prop->val ? "TRUE" : "FALSE")); } else if (prop->type1 == 0x04 && prop->type2 == 0x02) { - printf("VAL: 0x%x ", *((unsigned int*)prop->val)); + uint32_t val; + + memcpy(&val, prop->val, 4); + printf("VAL: 0x%x ", val); } else { printf("0x%02x 0x%2x...ignoring\n", prop->type1, prop->type2); continue; @@ -86,7 +90,7 @@ void show_properties(unsigned char *fw, int len) } } -void change_properties(unsigned char *fw, int len, struct propaction *paction) +void change_properties(uint8_t *fw, int32_t len, struct propaction *paction) { struct file_entry *fent; struct propaction *cpaction; @@ -178,9 +182,9 @@ void change_properties(unsigned char *fw, int len, struct propaction *paction) #define _BD_SET(bd, byte, bits) (bd[byte] |= bits) #define BD_SET(bd, ident) MAGIC(_BD_SET, bd, BD_##ident) -void print_boarddescription(unsigned char *bd) +void print_boarddescription(uint8_t *bd) { - int j; + int32_t j; for (j = 0; j < 32; j++) { printf("%02x ", *(bd+j)); @@ -214,10 +218,10 @@ void print_boarddescription(unsigned char *bd) printf("\tps2aPresent\t\t: %s\n", BD_TEXT(bd, PS2A)); } -void handle_boarddescription(unsigned char *fw, int len, int patch) +void handle_boarddescription(uint8_t *fw, int32_t len, int32_t patch) { struct file_entry *fent; - unsigned char *pos; + uint8_t *pos; for (fent = get_next_file(fw, len); fent != NULL; fent = get_next_file(NULL, 0)) { if (!strcmp(fent->name, "pdata")) @@ -232,7 +236,7 @@ void handle_boarddescription(unsigned char *fw, int len, int patch) pos = fent->start; /* MAGIC? */ - if (*((unsigned int*)pos) != 0x00002802) { + if (*((uint32_t*)pos) != 0x00002802) { fprintf(stderr, "pdata magic does not match, aborting!\n"); exit(1); } @@ -240,7 +244,7 @@ void handle_boarddescription(unsigned char *fw, int len, int patch) pos += 26; /* MAGIC2? */ - if (*((unsigned int*)pos) != 0x00500101) { + if (*((uint32_t*)pos) != 0x00500101) { fprintf(stderr, "pdata magic2 does not match, aborting!\n"); exit(1); } @@ -251,7 +255,7 @@ void handle_boarddescription(unsigned char *fw, int len, int patch) BD_SET(pos, PWRRELAY); } - printf("0x%08x: BOARD_DESCRIPTION: ", fent->start - fw); + printf("0x%08x: BOARD_DESCRIPTION: ", (uint32_t)(fent->start - fw)); print_boarddescription(pos); } @@ -272,7 +276,7 @@ void syntax(char *name) exit(1); } -void add_action(int opt, char *optarg, struct propaction **paction) { +void add_action(int32_t opt, char *optarg, struct propaction **paction) { struct propaction *pos = *paction; struct propaction *prev = NULL; @@ -331,13 +335,13 @@ void add_action(int opt, char *optarg, struct propaction **paction) { } } -int check_crc(unsigned char *fw, int len) +int32_t check_crc(uint8_t *fw, int32_t len) { - int ret; - unsigned int crc, oldcrc; + int32_t ret; + uint32_t crc, oldcrc; ret = rsb_crc2(fw, len, 0x55335053, &crc); - oldcrc = (unsigned int)*((unsigned int*)(fw + len - 4)); + oldcrc = (uint32_t)*((uint32_t*)(fw + len - 4)); printf("Checksum: 0x%08x (%s), should be: 0x%08x\n", crc, @@ -347,36 +351,34 @@ int check_crc(unsigned char *fw, int len) return ret; } -void check_image(unsigned char *fw, int len) +void check_image(uint8_t *fw, int32_t len) { struct file_entry *fent; - char *last_name = NULL; /* get_next_file will abort on error */ fent = get_next_file(fw, len); while (fent != NULL) { - last_name = fent->name; fent = get_next_file(NULL, 0); } } -int main(int argc, char **argv) +int32_t main(int32_t argc, char **argv) { struct stat statbuf; char *file = NULL; - unsigned char *fw; - int fd; - int remaining; - int ret; - int opt; - unsigned int crc; + uint8_t *fw; + int32_t fd; + int32_t remaining; + int32_t ret; + int32_t opt; + uint32_t crc; struct propaction *paction = NULL; - int showall = 0; - int update_crc = 0; - int patch_bd = 0; - int patch_fw = 0; - int extract = 0; - int list = 0; + int32_t showall = 0; + int32_t update_crc = 0; + int32_t patch_bd = 0; + int32_t patch_fw = 0; + int32_t extract = 0; + int32_t list = 0; if (argc < 2) syntax(argv[0]); @@ -503,7 +505,7 @@ int main(int argc, char **argv) if (update_crc || patch_fw || patch_bd) { ret = rsb_crc2(fw, statbuf.st_size, 0x55335053, &crc); if (ret == 4) { - *((unsigned int*)(fw + statbuf.st_size - 4)) = crc; + *((uint32_t*)(fw + statbuf.st_size - 4)) = crc; } check_image(fw, statbuf.st_size-4); diff --git a/src/rsb-crc.c b/src/rsb-crc.c index 6a2bf99..4363e30 100644 --- a/src/rsb-crc.c +++ b/src/rsb-crc.c @@ -1,11 +1,12 @@ #include +#include #define POLY 0x04c11db7 -unsigned int rsb_crc(unsigned int r11_crc, unsigned char *r10_buf, unsigned int r14_len) { - unsigned int r6_pos = 0; - unsigned int r3_data; - int r5_bit; +uint32_t rsb_crc(uint32_t r11_crc, uint8_t *r10_buf, uint32_t r14_len) { + uint32_t r6_pos = 0; + uint32_t r3_data; + int32_t r5_bit; while (r6_pos < r14_len) { r3_data = (*(r6_pos+r10_buf)) << 24; @@ -31,13 +32,13 @@ unsigned int rsb_crc(unsigned int r11_crc, unsigned char *r10_buf, unsigned int return r11_crc; } -unsigned int rsb_crc2(unsigned char *r0_buf, unsigned int r1_buflen, unsigned int r2_magic, unsigned int *crc_out) { - unsigned int r4_len; - unsigned int file_crc; +uint32_t rsb_crc2(uint8_t *r0_buf, uint32_t r1_buflen, uint32_t r2_magic, uint32_t *crc_out) { + uint32_t r4_len; + uint32_t file_crc; - r4_len = *(unsigned int*)(r0_buf + 0x20); + r4_len = *(uint32_t*)(r0_buf + 0x20); - if (*((unsigned int*)(r0_buf + 0x24)) != r2_magic) + if (*((uint32_t*)(r0_buf + 0x24)) != r2_magic) return 2; /* MAGIC does not match */ if (r1_buflen < r4_len) @@ -45,7 +46,7 @@ unsigned int rsb_crc2(unsigned char *r0_buf, unsigned int r1_buflen, unsigned in *crc_out = ~rsb_crc(~0x0, r0_buf, r4_len); - file_crc = *((unsigned int*)(r0_buf + r4_len)); + file_crc = *((uint32_t*)(r0_buf + r4_len)); if (file_crc != *crc_out) return 4; diff --git a/src/rsb-crc.h b/src/rsb-crc.h index f97e6da..a16f17f 100644 --- a/src/rsb-crc.h +++ b/src/rsb-crc.h @@ -1,2 +1,2 @@ -unsigned int rsb_crc(unsigned int r11_crc, unsigned char *r10_buf, unsigned int r14_len); -unsigned int rsb_crc2(unsigned char *r0_buf, unsigned int r1_buflen, unsigned int r2_magic, unsigned int *crc_out); +uint32_t rsb_crc(uint32_t r11_crc, uint8_t *r10_buf, uint32_t r14_len); +uint32_t rsb_crc2(uint8_t *r0_buf, uint32_t r1_buflen, uint32_t r2_magic, uint32_t *crc_out); diff --git a/src/rsb-lz.c b/src/rsb-lz.c index bb735d6..c4ae6b7 100644 --- a/src/rsb-lz.c +++ b/src/rsb-lz.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -15,20 +16,20 @@ void err_exit(const char *fname) } struct data_in_s { - unsigned char *start; - unsigned char *stop; - unsigned char bitpos; - unsigned char byte; + uint8_t *start; + uint8_t *stop; + uint8_t bitpos; + uint8_t byte; }; struct data_out_s { - unsigned char *pos; - unsigned char *end; + uint8_t *pos; + uint8_t *end; }; -unsigned char get_next_in_byte(struct data_in_s *data_in) +uint8_t get_next_in_byte(struct data_in_s *data_in) { - unsigned char byte; + uint8_t byte; if (data_in->stop < data_in->start) err_exit(__func__); @@ -39,9 +40,9 @@ unsigned char get_next_in_byte(struct data_in_s *data_in) return byte; } -unsigned char get_next_bit(struct data_in_s *data_in) +uint8_t get_next_bit(struct data_in_s *data_in) { - unsigned char bitval; + uint8_t bitval; if (data_in->bitpos == 0x80) { data_in->byte = get_next_in_byte(data_in); @@ -60,10 +61,10 @@ unsigned char get_next_bit(struct data_in_s *data_in) return 1; } -unsigned int get_next_bits(struct data_in_s *data_in, unsigned int bits) +uint32_t get_next_bits(struct data_in_s *data_in, uint32_t bits) { - unsigned int bit; - unsigned int next_bits; + uint32_t bit; + uint32_t next_bits; bit = 1 << (bits - 1); @@ -88,7 +89,7 @@ unsigned int get_next_bits(struct data_in_s *data_in, unsigned int bits) return next_bits; } -void write_byte(unsigned char byte, struct data_out_s *data_out) +void write_byte(uint8_t byte, struct data_out_s *data_out) { if (data_out->pos > data_out->end) { err_exit(__func__); @@ -100,12 +101,12 @@ void write_byte(unsigned char byte, struct data_out_s *data_out) void lz_expand(struct data_in_s *data_in, struct data_out_s *data_out) { - unsigned int pos; - unsigned int wordoffset; - unsigned int i; - unsigned char byte; - unsigned int wordlen; - unsigned char buf[1024]; + uint32_t pos; + uint32_t wordoffset; + uint32_t i; + uint8_t byte; + uint32_t wordlen; + uint8_t buf[1024]; pos = 1; @@ -143,9 +144,9 @@ void lz_expand(struct data_in_s *data_in, struct data_out_s *data_out) } } -void set_next_bit(unsigned char *buf, unsigned int set, unsigned int *currbit) { - unsigned char *pos; - unsigned char bitpos; +void set_next_bit(uint8_t *buf, uint32_t set, uint32_t *currbit) { + uint8_t *pos; + uint8_t bitpos; if (set) { pos = buf + ((*currbit) / 8); @@ -156,9 +157,9 @@ void set_next_bit(unsigned char *buf, unsigned int set, unsigned int *currbit) { *currbit = *currbit + 1; } -void write_bits(unsigned char *buf, unsigned int data, unsigned int bits, unsigned int *currbit) { - int i; - unsigned int bitpos; +void write_bits(uint8_t *buf, uint32_t data, uint32_t bits, uint32_t *currbit) { + int32_t i; + uint32_t bitpos; bitpos = 1 << (bits - 1); @@ -168,24 +169,24 @@ void write_bits(unsigned char *buf, unsigned int data, unsigned int bits, unsign } } -unsigned char *compress_lz(unsigned char *inbuf, int inlen, int *outlen) +uint8_t *compress_lz(uint8_t *inbuf, int32_t inlen, int32_t *outlen) { - unsigned char *end = inbuf + inlen; - unsigned char *outbuf; - unsigned char window[1024]; - int pos = 0; - int fill = 0; - unsigned int currbit = 0; - int offset; - int wordlen; - int found; - int i; + uint8_t *end = inbuf + inlen; + uint8_t *outbuf; + uint8_t window[1024]; + int32_t pos = 0; + int32_t fill = 0; + uint32_t currbit = 0; + int32_t offset; + int32_t wordlen; + int32_t found; + int32_t i; if ((outbuf = malloc((inlen * 2) + 4)) == NULL) { perror("malloc"); } - *((unsigned int*)outbuf) = LZ_MAGIC; + *((uint32_t*)outbuf) = LZ_MAGIC; currbit = 8 * 8; while(inbuf < end) { @@ -236,21 +237,21 @@ unsigned char *compress_lz(unsigned char *inbuf, int inlen, int *outlen) *outlen = (currbit / 8) + 1; - *((unsigned int*)(outbuf + 4)) = *outlen; + *((uint32_t*)(outbuf + 4)) = *outlen; return outbuf; } /* Checksum is only used for the compressed firmware in 'firmware' */ -unsigned int crc_check(unsigned char *buf, unsigned int len, unsigned int magic) +uint32_t crc_check(uint8_t *buf, uint32_t len, uint32_t magic) { - unsigned int file_crc; - unsigned int my_len; - unsigned int crc; - unsigned int my_magic; + uint32_t file_crc; + uint32_t my_len; + uint32_t crc; + uint32_t my_magic; - my_len = *((unsigned int*)(buf + 0x20)); - my_magic = *((unsigned int*)(buf + 0x24)); + my_len = *((uint32_t*)(buf + 0x20)); + my_magic = *((uint32_t*)(buf + 0x24)); if (my_magic != magic) { printf("\nmagic: 0x%08x <-> 0x%08x\n", my_magic, magic); @@ -261,7 +262,7 @@ unsigned int crc_check(unsigned char *buf, unsigned int len, unsigned int magic) return 3; crc = ~rsb_crc(~0x00, buf, len); - file_crc = *((unsigned int*)(buf + len)); + file_crc = *((uint32_t*)(buf + len)); if (file_crc != crc) { printf("\nChecksums: 0x%08x <-> 0x%08x!\n", crc, file_crc); @@ -271,16 +272,16 @@ unsigned int crc_check(unsigned char *buf, unsigned int len, unsigned int magic) return 0; } -unsigned char *extract_lz_file(unsigned char *inbuf, unsigned int *outlen , unsigned char check_crc) +uint8_t *extract_lz_file(uint8_t *inbuf, uint32_t *outlen , uint8_t check_crc) { - unsigned char *outbuf; + uint8_t *outbuf; struct data_in_s data_in; struct data_out_s data_out; - if (*((unsigned int*)inbuf) != LZ_MAGIC) + if (*((uint32_t*)inbuf) != LZ_MAGIC) err_exit(__func__); - *outlen = *((unsigned int*)(inbuf + 4)); + *outlen = *((uint32_t*)(inbuf + 4)); printf(", length: %d", *outlen); if ((outbuf = malloc(*outlen)) == NULL) { @@ -301,10 +302,10 @@ unsigned char *extract_lz_file(unsigned char *inbuf, unsigned int *outlen , unsi lz_expand(&data_in, &data_out); if (check_crc) { - unsigned int crclen; - int ret; + uint32_t crclen; + int32_t ret; - crclen = *((unsigned int*)(outbuf + 0x20)); + crclen = *((uint32_t*)(outbuf + 0x20)); if ((ret = crc_check(outbuf, crclen, 0x46335053)) != 0) { printf("crc_check return: %d\n", ret); diff --git a/src/rsb-lz.h b/src/rsb-lz.h index 4cf2c82..382b312 100644 --- a/src/rsb-lz.h +++ b/src/rsb-lz.h @@ -1,4 +1,4 @@ #define LZ_MAGIC 0x6110beef -unsigned char *extract_lz_file(unsigned char *inbuf, unsigned int *outlen , unsigned char check_crc); -unsigned char *compress_lz(unsigned char *inbuf, int inlen, int *outlen); +uint8_t *extract_lz_file(uint8_t *inbuf, uint32_t *outlen , uint8_t check_crc); +uint8_t *compress_lz(uint8_t *inbuf, int32_t inlen, int32_t *outlen); -- 2.39.5