uint32_t ep_reader::get_file_data_from_package(const char* file_path, char** buf) { const std::string pkg_dir = _p_ep_package->get_package_dir(); uint64_t str_hash = ep_bkdr_hash(file_path, EP_HASH_SEED); const MAP_EP_FILE_ENTITY_EX& map_ep_files = _p_ep_package->get_ep_file_info(); MAP_EP_FILE_ENTITY_EX_CONST_ITERATOR it = map_ep_files.find(str_hash); if (it != map_ep_files.end()) { *buf = new char[it->second.source_data_size + 1]; memset(*buf, 0, it->second.source_data_size + 1); char* compressed_buf = new char[it->second.compressed_data_size]; memset(compressed_buf, 0, it->second.compressed_data_size); uint32_t data_offset = it->second.offset + sizeof(EPFileEntity)+it->second.compress_relative_path_size; ep_read(pkg_dir.c_str(), data_offset, it->second.compressed_data_size, compressed_buf); uLongf dest_len = it->second.source_data_size + 1; uncompress((Bytef*)*buf, &dest_len, (Bytef*)compressed_buf, it->second.compressed_data_size); if (dest_len != it->second.source_data_size) { printf("error"); } EP_SAFE_DELETE_ARR(compressed_buf); return it->second.source_data_size; } return 0; }
void ep_drain_fifo(U8 ep) { U8 byte_cnt; usb_pcb_t *pcb = usb_pcb_get(); ep_select(ep); byte_cnt = UEBCX; if (byte_cnt <= (MAX_BUF_SZ - pcb->fifo[ep].len)) { ep_read(ep); pcb->pending_data &= ~(1<<ep); FIFOCON_INT_CLR(); } }
int ep_package::parse_package() { unsigned long package_size = ep_get_file_size(_package_dir.c_str()); unsigned long offset = 0; // read ep_package sign uint32_t size = EP_SIGN_LENGTH; char* buf = new char[size]; ep_read(_package_dir.c_str(), offset, size, buf); offset += size; if (strcmp(buf, EP_PACKAGE_SIGN) != 0) { EP_SAFE_DELETE_ARR(buf); return -1; } printf("sign %s\n", buf); // read ep_package version size = EP_VERSION_LENGTH; buf = new char[size]; ep_read(_package_dir.c_str(), offset, size, buf); offset += size; if (strcmp(buf, EP_VERSION) != 0) { EP_SAFE_DELETE_ARR(buf); return -1; } printf("EP_VERSION %s\n", buf); // ep_header size = sizeof(EPHeader); buf = new char[size]; ep_read(_package_dir.c_str(), offset, size, buf); EPHeader* p_header = (EPHeader*)buf; _ep_header.compressed = p_header->compressed; offset += size; EP_SAFE_DELETE_ARR(buf); // ep_file_entity unsigned int file_entity_size = sizeof(EPFileEntity); while (offset < package_size) { printf("offset package_size %d %d\n", offset, package_size); buf = new char[file_entity_size]; // EPFileEntityEx -- EPFileEntity if (ep_read(_package_dir.c_str(), offset, file_entity_size, buf) != 0){ EP_SAFE_DELETE_ARR(buf); return -1; } EPFileEntityEx file_entity_ex; EPFileEntity* p_file_entity = (EPFileEntity*)buf; file_entity_ex.offset = p_file_entity->offset; file_entity_ex.relative_path_hash = p_file_entity->relative_path_hash; file_entity_ex.relative_path_size = p_file_entity->relative_path_size; file_entity_ex.compress_relative_path_size = p_file_entity->compress_relative_path_size; file_entity_ex.source_data_size = p_file_entity->source_data_size; file_entity_ex.compressed_data_size = p_file_entity->compressed_data_size; file_entity_ex.crc32_source_data = p_file_entity->crc32_source_data; // offset += file_entity_size; EP_SAFE_DELETE_ARR(buf); // EPFileEntityEx -- EPFileEntity relative_path uint32_t compress_path_size = file_entity_ex.compress_relative_path_size; uLongf relative_size = file_entity_ex.relative_path_size; buf = new char[compress_path_size]; if (ep_read(_package_dir.c_str(), offset, file_entity_ex.compress_relative_path_size, buf) != 0) { EP_SAFE_DELETE_ARR(buf); return -1; } uncompress((Bytef*)file_entity_ex.relative_path, &relative_size, (Bytef*)buf, compress_path_size); EP_SAFE_DELETE_ARR(buf); _map_ep_files.insert(MAP_EP_FILE_ENTITY_EX_PAIR(file_entity_ex.relative_path_hash, file_entity_ex)); // offset += file_entity_ex.compress_relative_path_size; offset += file_entity_ex.compressed_data_size; } return 0; }
int main(int argc, char *argv[]) { int result; libusb_context *ctx; libusb_device_handle *usb_device; unsigned char *txbuf; int size; int retcode; int last_serial = -1; FILE *fp1, *fp2, *fp; char def1_inst[] = "/usr/share/rpiboot/usbbootcode.bin"; char def2_inst[] = "/usr/share/rpiboot/msd.elf"; char def3_inst[] = "/usr/share/rpiboot/buildroot.elf"; char def1_loc[] = "./usbbootcode.bin"; char def2_loc[] = "./msd.elf"; char def3_loc[] = "./buildroot.elf"; char *def1, *def2, *def3; char *stage1 = NULL, *stage2 = NULL; char *fatimage = NULL, *executable = NULL; int loop = 0; // if local file version exists use it else use installed if( access( def1_loc, F_OK ) != -1 ) { def1 = def1_loc; } else { def1 = def1_inst; } if( access( def2_loc, F_OK ) != -1 ) { def2 = def2_loc; } else { def2 = def2_inst; } if( access( def3_loc, F_OK ) != -1 ) { def3 = def3_loc; } else { def3 = def3_inst; } stage1 = def1; stage2 = def2; struct MESSAGE_S { int length; unsigned char signature[20]; } message; #if defined (__CYGWIN__) //printf("Running under Cygwin\n"); #else //exit if not run as sudo if(getuid() != 0) { printf("Must be run with sudo...\n"); exit(-1); } #endif // Skip the command name argv++; argc--; while(*argv) { if(strcmp(*argv, "-b") == 0) { argv++; argc--; if(argc < 1) usage(1); stage1 = def1; stage2 = def3; fatimage = *argv; } else if(strcmp(*argv, "-h") == 0 || strcmp(*argv, "--help") == 0) { usage(0); } else if(strcmp(*argv, "-x") == 0) { argv++; argc--; executable = *argv; } else if(strcmp(*argv, "-l") == 0) { loop = 1; } else if(strcmp(*argv, "-v") == 0) { verbose = 1; } else { usage(1); } argv++; argc--; } fp1 = fopen(stage1, "rb"); if (fp1 == NULL) { printf("Cannot open file %s\n", stage1); exit(-1); } fp2 = fopen(stage2, "rb"); if (fp2 == NULL) { printf("Cannot open file %s\n", stage2); exit(-1); } if(strcmp(stage2 + strlen(stage2) - 4, ".elf")) { printf("Third stage needs to be .elf format\n"); exit(-1); } int ret = libusb_init(&ctx); if (ret) { printf("Failed to initialise libUSB\n"); exit(-1); } libusb_set_debug(ctx, 0); do { FILE *fp_img = NULL; struct libusb_device_descriptor desc; printf("Waiting for BCM2835 ...\n"); // Wait for a device to get plugged in do { result = Initialize_Device(&ctx, &usb_device); if(result == 0) { libusb_get_device_descriptor(libusb_get_device (usb_device), &desc); // Make sure we've re-enumerated since the last time if(desc.iSerialNumber == last_serial) { result = -1; libusb_close(usb_device); } } if (result) { usleep(100); } } while (result); last_serial = desc.iSerialNumber; printf("Found serial = %d: writing file %s\n", desc.iSerialNumber, desc.iSerialNumber == 0 ? stage1 : stage2); fp = desc.iSerialNumber == 0 ? fp1 : fp2; fseek(fp, 0, SEEK_END); message.length = ftell(fp); fseek(fp, 0, SEEK_SET); if(desc.iSerialNumber == 1 && fatimage != NULL) { // Been given a filesystem image fp_img = fopen(fatimage, "rb"); if(fp_img == NULL) { printf("Failed to open image %s\n", fatimage); exit(-1); } fseek(fp_img, 0, SEEK_END); message.length += ftell(fp_img); if(verbose) printf("Adding %ld bytes of binary to end of elf\n", ftell(fp_img)); fseek(fp_img, 0, SEEK_SET); } txbuf = (unsigned char *)malloc(message.length); if (txbuf == NULL) { printf("Failed to allocate memory\n"); exit(-1); } size = fread(txbuf, 1, message.length, fp); if(fp_img) { size += fread(txbuf + size, 1, message.length - size, fp_img); } size = ep_write((unsigned char *)&message, sizeof(message), usb_device); if (size != sizeof(message)) { printf("Failed to write correct length, returned %d\n", size); exit(-1); } if(verbose) printf("Writing %d bytes\n", message.length); size = ep_write(txbuf, message.length, usb_device); if (size != message.length) { printf("Failed to read correct length, returned %d\n", size); exit(-1); } size = ep_read((unsigned char *)&retcode, sizeof(retcode), usb_device); if (retcode == 0) { if(verbose) printf("Successful\n"); if(fp == fp2 && executable) { system(executable); } } else printf("Failed : 0x%x", retcode); libusb_close(usb_device); } while(fp == fp1 || loop); libusb_exit(ctx); return 0; }