X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/rsbs2/blobdiff_plain/7ac4bfad34083f4897186ffd6cf4873a67fcd404..9eb4b3c68c23622076943399ae2c8d298eb32799:/firmware.c diff --git a/firmware.c b/firmware.c index 6b47e2b..6ef5971 100644 --- a/firmware.c +++ b/firmware.c @@ -8,6 +8,7 @@ #include #include #include "rsb-crc.h" +#include "rsb-lz.h" #define FINDSTR(addr, str) (!strncmp((char*)addr, str, strlen(str))) @@ -75,13 +76,13 @@ void show_properties(unsigned char *fw, int len) } if (prop->right_rw == 0x00 && prop->rw_mask == 0x00) { - printf("(R-) "); + printf("(R-)"); } else if (prop->right_rw == 0x01) { - printf("(RW mask: 0x%02x) ", prop->rw_mask); + printf("(RW mask: 0x%02x)", prop->rw_mask); } else { - printf("(UNK 0x%02x 0x%02x) ", prop->right_rw, prop->rw_mask); + printf("(UNK 0x%02x 0x%02x)", prop->right_rw, prop->rw_mask); } - printf("\n"); + printf(", length: %d\n", *((unsigned int*)(fw + i - 4))); } } } @@ -152,9 +153,99 @@ void change_properties(unsigned char *fw, int len, struct propaction *paction) } } +#define BD_SERIAL1 0x14,0x02 +#define BD_ICMB 0x14,0x04 +#define BD_LAN 0x14,0x08 +#define BD_SERIAL2 0x14,0x10 +#define BD_SERIAL3 0x14,0x20 +#define BD_USB 0x14,0x40 +#define BD_PCI 0x15,0x03 +#define BD_LPC 0x15,0x04 +#define BD_VGA 0x15,0x08 +#define BD_BATTERY 0x15,0x10 +#define BD_ACDC 0x15,0x20 +#define BD_STANDBY 0x15,0x40 +#define BD_POWERCONN 0x15,0x70 +#define BD_DVI 0x15,0x80 +#define BD_PWRATX 0x16,0x01 +#define BD_PWRRELAY 0x16,0x02 +#define BD_PS2A 0x19,0xff + +#define MAGIC(fn, args...) fn(args) + +#define _BD_IS_SET(bd, byte, bits) (bd[byte] & bits) +#define BD_IS_SET(bd, ident) MAGIC(_BD_IS_SET, bd, BD_##ident) +#define BD_TEXT(bd, ident) (BD_IS_SET(bd, ident) ? "TRUE" : "FALSE") + +#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) +{ + int j; + + for (j = 0; j < 32; j++) { + printf("%02x ", *(bd+j)); + } + printf("\n"); + + /* com/agilent/rmc/amr/AmrMaster.class + * com/agilent/rmc/mgui/RmcPanel.class + * com/agilent/rmc/mgui/panels/AvrManualConfig.class + * com/agilent/rmc/mgui/panels/CardConf.jad + * com/agilent/rmc/mgui/panels/PowerMgmtConf.jad + * com/agilent/rmc/mgui/panels/RemoteDiskConf.jad + */ + printf("\tserial1Present\t\t: %s\n", BD_TEXT(bd, SERIAL1)); + printf("\ticmbPresent\t\t: %s\n", BD_TEXT(bd, ICMB)); + printf("\tlanPresent\t\t: %s\n", BD_TEXT(bd, LAN)); + printf("\tserial2Present\t\t: %s\n", BD_TEXT(bd, SERIAL2)); + printf("\tserial3Present\t\t: %s\n", BD_TEXT(bd, SERIAL3)); + printf("\tusbPresent\t\t: %s\n", BD_TEXT(bd, USB)); + printf("\tpciPresent\t\t: %s\n", BD_TEXT(bd, PCI)); + printf("\tlpcPresent\t\t: %s\n", BD_TEXT(bd, LPC)); + printf("\tvgaPresent\t\t: %s\n", BD_TEXT(bd, VGA)); + printf("\tbatteryPresent\t\t: %s\n", BD_TEXT(bd, BATTERY)); + printf("\tacdcPresent\t\t: %s\n", BD_TEXT(bd, ACDC)); + printf("\tstandbyPresent\t\t: %s\n", BD_TEXT(bd, STANDBY)); + printf("\thasPowerConnectors\t: %s\n", BD_TEXT(bd, POWERCONN)); + printf("\tdviPresent\t\t: %s\n", BD_TEXT(bd, DVI)); + printf("\tpowerSwitchATX\t\t: %s\n", BD_TEXT(bd, PWRATX)); + printf("\tpowerSwitchRelay\t: %s\n", BD_TEXT(bd, PWRRELAY)); + /* 22 & 4 */ + printf("\tps2aPresent\t\t: %s\n", BD_TEXT(bd, PS2A)); +} + void handle_boarddescription(unsigned char *fw, int len, int patch) { - /* 0x01 0x01 0x50 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88 0x02 0xac 0x01 0xd0 0x05 0x00 0x00 0x6a 0x3a 0x00 0x00 0x06 0x00 0x01 0x00 0x00 0x00 0x00 0x00 */ + int i; + + for (i = len - (strlen("pdata")+1); i > 0; i--) { + if (FINDSTR(fw+i, "pdata")) { + unsigned char *pos = fw + i + strlen("pdata") + 1; + + /* MAGIC? */ + if (*((unsigned int*)pos) != 0x00002802) { + continue; + } + + pos += 26; + + /* MAGIC2? */ + if (*((unsigned int*)pos) != 0x00500101) { + continue; + } + + if (patch) { + /* Enable relay power switching */ + BD_SET(pos, PWRRELAY); + } + printf("0x%08x: BOARD_DESCRIPTION: ", pos-fw); + print_boarddescription(pos); + + break; + } + } } void syntax(char *name) @@ -163,6 +254,8 @@ void syntax(char *name) fprintf(stderr,"parameters as follows:\n"); fprintf(stderr,"\t-d\t\tdisplay all properties of the image\n"); fprintf(stderr,"\t-u\t\tupdate checksum of the image\n"); + fprintf(stderr,"\t-b\t\tmodify BOARD_DESCRIPTION for more power-switch options\n"); + fprintf(stderr,"\t-e\t\textract files in firmware\n"); fprintf(stderr,"\t-t property\tset 'property' to true\n"); fprintf(stderr,"\t-f property\tset 'property' to false\n"); fprintf(stderr,"\t-w property\tallow read-write access to 'property'\n"); @@ -258,12 +351,14 @@ int main(int argc, char **argv) struct propaction *paction = NULL; int showall = 0; int update_crc = 0; + int patch_bd = 0; int patch_fw = 0; + int extract = 0; if (argc < 2) syntax(argv[0]); - while ((opt = getopt(argc, argv, "dut:f:w:r:")) != -1) { + while ((opt = getopt(argc, argv, "dubet:f:w:r:")) != -1) { switch(opt) { case 'd': showall = 1; @@ -271,6 +366,12 @@ int main(int argc, char **argv) case 'u': update_crc = 1; break; + case 'b': + patch_bd = 1; + break; + case 'e': + extract = 1; + break; case 't': case 'f': case 'w': @@ -322,6 +423,7 @@ int main(int argc, char **argv) ret = check_crc(fw, statbuf.st_size); if ((ret != 0) && (!update_crc)) { fprintf(stderr,"Checksum incorrect, aborting...\n"); + exit(1); } if (patch_fw) { @@ -350,10 +452,20 @@ int main(int argc, char **argv) printf("\n"); } - if (showall) + if (patch_bd) { + handle_boarddescription(fw, statbuf.st_size -4, 1); + } + + if (showall) { show_properties(fw, statbuf.st_size - 4); + handle_boarddescription(fw, statbuf.st_size -4, 0); + } + + if (extract) { + search_lz_sections(fw, statbuf.st_size - 4); + } - if (update_crc || patch_fw) { + 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;