/* * Function: Angel_ReadParamConfigMessage * Purpose: read a parameter config from a buffer where it is in ADP format. * * see params.h for details */ bool Angel_ReadParamConfigMessage( const unsigned char *buffer, ParameterConfig *config ) { unsigned int word; unsigned int i; word = GET32LE( buffer ); buffer += sizeof( word ); if ( word > config->num_parameters ) { WARN( "not enough space" ); return FALSE; } config->num_parameters = word; for ( i = 0; i < config->num_parameters; ++i ) { config->param[i].type = (ADP_Parameter)GET32LE( buffer ); buffer += sizeof( word ); config->param[i].value = GET32LE( buffer ); buffer += sizeof( word ); } return TRUE; }
/* * Function: Angel_ReadParamOptionsMessage * Purpose: read a parameter options block from a buffer * where it is in ADP format. * * see params.h for details */ bool Angel_ReadParamOptionsMessage( const unsigned char *buffer, ParameterOptions *options ) { unsigned int word; unsigned int i, j; word = GET32LE( buffer ); buffer += sizeof( word ); if ( word > options->num_param_lists ) { WARN( "not enough space" ); return FALSE; } options->num_param_lists = word; for ( i = 0; i < options->num_param_lists; ++i ) { ParameterList *list = &options->param_list[i]; list->type = (ADP_Parameter)GET32LE( buffer ); buffer += sizeof( word ); word = GET32LE( buffer ); buffer += sizeof( word ); if ( word > list->num_options ) { WARN( "not enough list space" ); return FALSE; } list->num_options = word; for ( j = 0; j < list->num_options; ++j ) { list->option[j] = GET32LE( buffer ); buffer += sizeof( word ); } } return TRUE; }
static void unpack_rkfw(void) { const char *chip = NULL; info("RKFW signature detected\n"); info("version: %d.%d.%d\n", buf[9], buf[8], (buf[7]<<8)+buf[6]); info("date: %d-%02d-%02d %02d:%02d:%02d\n", (buf[0x0f]<<8)+buf[0x0e], buf[0x10], buf[0x11], buf[0x12], buf[0x13], buf[0x14]); switch(buf[0x15]) { case 0x50: chip = "rk29xx"; break; case 0x60: chip = "rk30xx"; break; case 0x70: chip = "rk31xx"; break; case 0x80: chip = "rk32xx"; break; case 0x41: chip = "rk3368"; break; default: info("You got a brand new chip (%#x), congratulations!!!\n", buf[0x15]); } info("family: %s\n", chip ? chip : "unknown"); ioff = GET32LE(buf+0x19); isize = GET32LE(buf+0x1d); if (memcmp(buf+ioff, "BOOT", 4)) fatal("cannot find BOOT signature\n"); info("%08x-%08x %-26s (size: %d)\n", ioff, ioff + isize -1, "BOOT", isize); write_file("BOOT", buf+ioff, isize); ioff = GET32LE(buf+0x21); isize = GET32LE(buf+0x25); if (memcmp(buf+ioff, "RKAF", 4)) fatal("cannot find embedded RKAF update.img\n"); info("%08x-%08x %-26s (size: %d)\n", ioff, ioff + isize -1, "embedded-update.img", isize); write_file("embedded-update.img", buf+ioff, isize); }
static void unpack_rkaf(void) { uint8_t *p; const char *name, *path, *sep; char dir[PATH_MAX]; int count; info("RKAF signature detected\n"); fsize = GET32LE(buf+4) + 4; if (fsize != (unsigned)size) info("invalid file size (should be %u bytes)\n", fsize); else info("file size matches (%u bytes)\n", fsize); info("manufacturer: %s\n", buf + 0x48); info("model: %s\n", buf + 0x08); count = GET32LE(buf+0x88); info("number of files: %d\n", count); for (p = &buf[0x8c]; count > 0; p += 0x70, count--) { name = (const char *)p; path = (const char *)p + 0x20; ioff = GET32LE(p+0x60); noff = GET32LE(p+0x64); isize = GET32LE(p+0x68); fsize = GET32LE(p+0x6c); if (memcmp(path, "SELF", 4) == 0) { info("skipping SELF entry\n"); } else { info("%08x-%08x %-26s (size: %d)\n", ioff, ioff + isize - 1, path, fsize); // strip header and footer of parameter file if (memcmp(name, "parameter", 9) == 0) { ioff += 8; fsize -= 12; } sep = path; while ((sep = strchr(sep, '/')) != NULL) { memcpy(dir, path, sep - path); dir[sep - path] = '\0'; if (mkdir(dir, 0755) == -1 && errno != EEXIST) fatal("%s: %s\n", dir, strerror(errno)); sep++; } write_file(path, buf+ioff, fsize); } } }