int usb_boot( struct usb_handle *usb, void *data, unsigned sz, const char *rootfs) { const uint32_t msg_boot = 0xF0030002; uint32_t msg_size = sz; int i; pthread_t thread; struct thread_vars vars; struct termios tn; struct file_data fd_vector[MAX_OPEN_FILES]; if (read_asic_id(usb)) return -1; printf("sending xload to target...\n"); usleep(1000); usb_write(usb, &msg_boot, sizeof(msg_boot)); usleep(1000); usb_write(usb, &msg_size, sizeof(msg_size)); usleep(1000); usb_write(usb, data, sz); usleep(100000); munmap(data, msg_size); for (i = 0; i < MAX_OPEN_FILES; i++) fd_vector[i].data = NULL; vars.usb = usb; pthread_mutex_init(&vars.usb_mutex, NULL); tcgetattr(STDIN_FILENO, &vars.t_restore); tn = vars.t_restore; tn.c_lflag &= ~(ICANON | ECHO); printf(TFORMAT, TARGET_FORMAT); tcsetattr(STDIN_FILENO, TCSANOW, &tn); if (pthread_create(&thread, NULL, listenerTask, &vars)) host_print("listenerTask failed\n"); for (;;) { usleep(100); if (usb_read(usb, &i, 4) != 4) break; if (i == USBBOOT_FS_MAGIC) { usleep(100); pthread_mutex_lock(&vars.usb_mutex); process_file(usb, rootfs, fd_vector, &vars.t_restore); pthread_mutex_unlock(&vars.usb_mutex); continue; } printf("%c", i); fflush(stdout); } usb_close(usb); pthread_mutex_destroy(&vars.usb_mutex); tcsetattr(STDIN_FILENO, TCSANOW, &vars.t_restore); printf(HFORMAT, HOST_FORMAT); return 0; }
void *listenerTask(void *argument) { struct thread_vars *vars = argument; int c; for (;;) { c = getchar(); if (c == EOF) return NULL; pthread_mutex_lock(&vars->usb_mutex); if (usb_write(vars->usb, &c, 4) != 4) { host_print("could not send '%c' to target\n", c); panic(&vars->t_restore); } pthread_mutex_unlock(&vars->usb_mutex); } return NULL; }
int process_file(struct usb_handle *usb, const char *rootfs, struct file_data *fd_vector, struct termios *t_restore) { uint32_t i, j, pos, size; struct stat s; int fd, ret; char fname[256]; if (usb_read(usb, &i, 4) != 4) { host_print("USB error\n"); panic(t_restore); } ret = 0; switch (i) { case USBBOOT_FS_CMD_OPEN: for (j = 0; rootfs[j]; j++) fname[j] = rootfs[j]; for (;; j++) { if (usb_read(usb, &i, 4) != 4) { host_print("USB error\n"); panic(t_restore); } if (i == USBBOOT_FS_CMD_END) { fname[j] = 0; break; } else if (i > 0xFF) { host_print("Error in filename\n"); ret++; fname[j] = 0; break; } else fname[j] = i; } for (i = 0; i < MAX_OPEN_FILES && fd_vector[i].data; i++) ; if (i >= MAX_OPEN_FILES) { host_print("MAX_OPEN_FILES exceeded\n"); ret++; goto open_error_1; } fd = open(fname, O_RDONLY); if (fd < 0) { host_print("cannot open '%s'\n", fname); ret++; goto open_error_1; } if (fstat(fd, &s)) { host_print("cannot stat '%s'\n", fname); ret++; goto open_error_2; } fd_vector[i].data = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (fd_vector[i].data == MAP_FAILED) { host_print("cannot mmap '%s'\n", fname); ret++; goto open_error_2; } close(fd); fd_vector[i].size = size = s.st_size; fd = i; goto open_ok; open_error_2: close(fd); open_error_1: fd_vector[i].size = size = 0; fd_vector[i].data = NULL; fd = -1; open_ok: if (usb_write(usb, &fd, 4) != 4 || usb_write(usb, &size, 4) != 4 ) { host_print("could not send file size to target\n"); panic(t_restore); } break; case USBBOOT_FS_CMD_CLOSE: if (usb_read(usb, &i, 4) != 4) { host_print("USB error\n"); panic(t_restore); } if (i >= MAX_OPEN_FILES || !fd_vector[i].data) { host_print("invalid close index\n"); ret++; break; } if (usb_read(usb, &j, 4) != 4) { host_print("USB error\n"); panic(t_restore); } if (j != USBBOOT_FS_CMD_END) { host_print("invalid close\n"); ret++; break; } munmap(fd_vector[i].data, fd_vector[i].size); fd_vector[i].data = NULL; break; case USBBOOT_FS_CMD_READ: if (usb_read(usb, &i, 4) != 4) { host_print("USB error\n"); panic(t_restore); } if (i >= MAX_OPEN_FILES || !fd_vector[i].data) { host_print("invalid read index\n"); ret++; break; } if (usb_read(usb, &pos, 4) != 4) { host_print("USB error\n"); panic(t_restore); } if (pos >= fd_vector[i].size) { host_print("invalid read pos\n"); ret++; break; } if (usb_read(usb, &size, 4) != 4) { host_print("USB error\n"); panic(t_restore); } if (pos+size > fd_vector[i].size) { host_print("invalid read size\n"); ret++; break; } if (usb_read(usb, &j, 4) != 4) { host_print("USB error\n"); panic(t_restore); } if (j != USBBOOT_FS_CMD_END) { host_print("invalid read\n"); ret++; break; } if (usb_write(usb, fd_vector[i].data+pos, size) != size) { host_print("could not send file to target\n"); panic(t_restore); } break; case USBBOOT_FS_CMD_END: default: host_print("Unknown filesystem command\n"); ret++; break; } return ret; }
/** * GTraversFunction that allows the information for all hosts to be printed * * @param host_name the string name of the host * @param h the host struct paired with the name * @param ostr the output stream that the info will be printed to * @return 0 to cause the traversal to continue */ static int print_host_all(gchar* host_name, host_t* host, GOutputStream* ostr) { host_print(host, ostr); return 0; }