int stage_1_prep (libusb_device_handle *handle, uchar *buf) { int x; ShowURB (5); version = aw_fel_get_version (handle); if (IsA10 (version)) // 0x1623 = A10 { printf ("Detected A10 (ID 0x%04X)\n", version); FN = &FN_sun4i; } else if (IsA20 (version)) // 0x1651 = A20 { printf ("Detected A20 (ID 0x%04X)\n", version); FN = &FN_sun7i; } else if (IsH3 (version)) // 0x1680 = H3 printf ("Detected H3 (ID 0x%04X)\n", version); else { printf ("Unknown processor ID 0x%04X\n", version); PerhapsQuit (); } ShowURB (14); version = aw_fel_get_version (handle); // URB 23 - 27 ShowURB (23); aw_fel_read (handle, 0x7e00, buf, 256); // get 256 0xCC for (x = 0; x < 256; x++) { if (buf [x] != 0xCC) { printf ("Non 0xCC at entry %d\n", x); hexdump (buf, 0, 256); save_file ((char *) "Dump1_000023", buf, 256); PerhapsQuit (); break; } } ShowURB (32); version = aw_fel_get_version (handle); ShowURB (41); PutNulls (buf, 4); aw_fel_write (handle, 0x7e00, buf, 256); ShowURB (50); version = aw_fel_get_version (handle); return 0; }
int stage_2_prep (libusb_device_handle *handle, uchar *buf) { int x, version2; if (errors) { printf ("Due to previous errors it might not be safe to continue.\n"); PerhapsQuit (); } if (IsA10 (version)) MagicAddr = 0x40330000; ShowURB (5); version2 = aw_fel_get_version (handle); if (version2 != 0x1610) // 0x1610 = flash mode { printf ("Expected ID 0x1610, got %04X\n", version2); PerhapsQuit (); } ShowURB (14); aw_fel_get_version (handle); ShowURB (24); aw_fes_read (handle, 0x7e00, buf, 0x100, AW_FEL2_DRAM); for (x = 0; x < 256; x++) { if (buf [x] != (x < 4) ? 0x00 : 0xCC) { printf ("Scratchpad incorrect\n"); hexdump (buf, 0, 256); save_file ((char *) "Dump2_000024", buf, 256); PerhapsQuit (); break; } } ShowURB (32); aw_fel_get_version (handle); ShowURB (42); aw_fes_write (handle, 0x7e00, buf, 0x100, AW_FEL2_DRAM); return 0; }
int restore_system (libusb_device_handle *handle, uchar *buf) { ShowURB (113664); aw_fel_get_version (handle); ShowURB (113673); aw_fes_write (handle, 0x7e04, (char*) "\xcd\xa5\x34\x12", 0x04, AW_FEL2_DRAM); ShowURB (113682); aw_fes_send_file (handle, MagicAddr, AW_FEL2_DRAM, FN->magic_de_start); ShowURB (113691); aw_fes_send_file (handle, 0x40430000, AW_FEL2_DRAM, FN->fet_restore, 0x8000); ShowURB (113703); aw_fes_send_file (handle, MagicAddr, AW_FEL2_DRAM, FN->magic_de_end); ShowURB (113709); aw_fes_exec (handle, 0x40430000, 0x11); ShowURB (113712); PutNulls (buf, 16); aw_pad_write (handle, buf, 0x10); return 0; }
int main(int argc, char **argv) { int rc; libusb_device_handle *handle = NULL; int iface_detached = -1; rc = libusb_init(NULL); assert(rc == 0); if (argc <= 1) { printf("Usage: %s command arguments... [command...]\n" " hex[dump] address length Dumps memory region in hex\n" " dump address length Binary memory dump\n" " exe[cute] address Call function address\n" " read address length file Write memory contents into file\n" " write address file Store file contents into memory\n" " ver[sion] Show BROM version\n" " clear address length Clear memory\n" " fill address length value Fill memory\n" , argv[0] ); } handle = libusb_open_device_with_vid_pid(NULL, 0x1f3a, 0xefe8); if (!handle) { fprintf(stderr, "ERROR: Allwinner USB FEL device not found!\n"); exit(1); } rc = libusb_claim_interface(handle, 0); #if defined(__linux__) if (rc != LIBUSB_SUCCESS) { libusb_detach_kernel_driver(handle, 0); iface_detached = 0; rc = libusb_claim_interface(handle, 0); } #endif assert(rc == 0); while (argc > 1 ) { int skip = 1; if (strncmp(argv[1], "hex", 3) == 0 && argc > 3) { aw_fel_hexdump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0)); skip = 3; } else if (strncmp(argv[1], "dump", 4) == 0 && argc > 3) { aw_fel_dump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0)); skip = 3; } else if ((strncmp(argv[1], "exe", 3) == 0 && argc > 2) ) { aw_fel_execute(handle, strtoul(argv[2], NULL, 0)); skip=3; } else if (strncmp(argv[1], "ver", 3) == 0 && argc > 1) { aw_fel_get_version(handle); skip=1; } else if (strcmp(argv[1], "write") == 0 && argc > 3) { size_t size; void *buf = load_file(argv[3], &size); aw_fel_write(handle, buf, strtoul(argv[2], NULL, 0), size); free(buf); skip=3; } else if (strcmp(argv[1], "read") == 0 && argc > 4) { size_t size = strtoul(argv[3], NULL, 0); void *buf = malloc(size); aw_fel_read(handle, strtoul(argv[2], NULL, 0), buf, size); save_file(argv[4], buf, size); free(buf); skip=4; } else if (strcmp(argv[1], "clear") == 0 && argc > 2) { aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), 0); skip=3; } else if (strcmp(argv[1], "fill") == 0 && argc > 3) { aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), (unsigned char)strtoul(argv[4], NULL, 0)); skip=4; } else { fprintf(stderr,"Invalid command %s\n", argv[1]); exit(1); } argc-=skip; argv+=skip; } #if defined(__linux__) if (iface_detached >= 0) libusb_attach_kernel_driver(handle, iface_detached); #endif return 0; }
int main(int argc, char **argv) { int rc; libusb_device_handle *handle = NULL; rc = libusb_init(NULL); assert(rc == 0); if (argc <= 1) { printf("Usage: %s command arguments... [command...]\n" " hex[dump] address length Dumps memory region in hex\n" " dump address length Binary memory dump\n" " exe[cute] address Call function address\n" " write address file Store file contents into memory\n" " ver[sion] Show BROM version\n" " clear address length Clear memory\n" " fill address length value Fill memory\n" , argv[0] ); } handle = libusb_open_device_with_vid_pid(NULL, 0x1f3a, 0xefe8); if (!handle) { fprintf(stderr, "A10 USB FEL device not found!"); exit(1); } rc = libusb_claim_interface(handle, 0); assert(rc == 0); while (argc > 1 ) { int skip = 1; if (strncmp(argv[1], "hex", 3) == 0 && argc > 3) { aw_fel_hexdump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0)); skip = 3; } else if (strncmp(argv[1], "dump", 4) == 0 && argc > 3) { aw_fel_dump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0)); skip = 3; } else if ((strncmp(argv[1], "exe", 3) == 0 && argc > 2) ) { aw_fel_execute(handle, strtoul(argv[2], NULL, 0)); skip=3; } else if (strncmp(argv[1], "ver", 3) == 0 && argc > 1) { aw_fel_get_version(handle); skip=1; } else if (strcmp(argv[1], "write") == 0 && argc > 3) { size_t size; void *buf = load_file(argv[3], &size); aw_fel_write(handle, buf, strtoul(argv[2], NULL, 0), size); free(buf); skip=3; } else if (strcmp(argv[1], "clear") == 0 && argc > 2) { aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), 0); skip=3; } else if (strcmp(argv[1], "fill") == 0 && argc > 3) { aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), (unsigned char)strtoul(argv[4], NULL, 0)); skip=4; } else { fprintf(stderr,"Invalid command %s\n", argv[1]); exit(1); } argc-=skip; argv+=skip; } return 0; }