/*---------------------------------------------------------------------*/ static int start_program(void) { /* Link, load, and start new program. */ int ret; s.fd = cfs_open("codeprop.out", CFS_READ); ret = elfloader_load(s.fd); /* XXX: Interrupts seems to be turned off a little too long during the ELF loading process, so we need to "manually" trigger a timer interrupt here. */ TACCR1 = TAR + 1000; if(ret == ELFLOADER_OK) { sprintf(msg, "ok\n"); PRINTF("Ok, starting new program.\n"); /* Start processes. */ autostart_start(elfloader_autostart_processes); } else { sprintf(msg, "err %d %s", ret, elfloader_unknown); PRINTF("Error: '%s'.\n", msg); } cfs_close(s.fd); return ret; }
/*---------------------------------------------------------------------*/ static PT_THREAD(recv_tcpthread(struct pt *pt)) { PT_BEGIN(pt); /* Read the header. */ PT_WAIT_UNTIL(pt, uip_newdata() && uip_datalen() > 0); if(uip_datalen() < sizeof(struct codeprop_tcphdr)) { PRINTF(("codeprop: header not found in first tcp segment\n")); uip_abort(); goto thread_done; } s.len = uip_htons(((struct codeprop_tcphdr *)uip_appdata)->len); s.addr = 0; uip_appdata += sizeof(struct codeprop_tcphdr); uip_len -= sizeof(struct codeprop_tcphdr); xmem_erase(XMEM_ERASE_UNIT_SIZE, EEPROMFS_ADDR_CODEPROP); /* Read the rest of the data. */ do { if(uip_len > 0) { xmem_pwrite(uip_appdata, uip_len, EEPROMFS_ADDR_CODEPROP + s.addr); s.addr += uip_len; } if(s.addr < s.len) { PT_YIELD_UNTIL(pt, uip_newdata()); } } while(s.addr < s.len); /* Kill old program. */ elfloader_unload(); /* Link, load, and start new program. */ int s; static char msg[30 + 10]; s = elfloader_load(EEPROMFS_ADDR_CODEPROP); if (s == ELFLOADER_OK) sprintf(msg, "ok\n"); else sprintf(msg, "err %d %s\n", s, elfloader_unknown); /* Return "ok" message. */ do { s = strlen(msg); uip_send(msg, s); PT_WAIT_UNTIL(pt, uip_acked() || uip_rexmit() || uip_closed()); } while(uip_rexmit()); /* Close the connection. */ uip_close(); thread_done:; PT_END(pt); }
void runReceivedProgram() { printf("runReceivedProgram\n"); printf("originator: %u\n", filenameOriginatorRecv.originator); printf("filename: %s\n", filename_download); fd = cfs_open(filename_download, CFS_READ | CFS_WRITE); if(fd < 0) { printf("exec: could not open %s\n", filename_download); } else { int ret; char *print, *symbol; ret = elfloader_load(fd); cfs_close(fd); symbol = ""; switch(ret) { case ELFLOADER_OK: print = "OK"; break; case ELFLOADER_BAD_ELF_HEADER: print = "Bad ELF header"; break; case ELFLOADER_NO_SYMTAB: print = "No symbol table"; break; case ELFLOADER_NO_STRTAB: print = "No string table"; break; case ELFLOADER_NO_TEXT: print = "No text segment"; break; case ELFLOADER_SYMBOL_NOT_FOUND: print = "Symbol not found: "; break; case ELFLOADER_SEGMENT_NOT_FOUND: print = "Segment not found: "; break; case ELFLOADER_NO_STARTPOINT: print = "No starting point"; break; default: print = "Unknown return code from the ELF loader (internal bug)"; break; } if(ret == ELFLOADER_OK) { int i; for(i = 0; elfloader_autostart_processes[i] != NULL; ++i) { printf("exec: starting process %s\n", elfloader_autostart_processes[i]->name); } autostart_start(elfloader_autostart_processes); } } }
/*---------------------------------------------------------------------*/ int codeprop_start_program(void) { int err; codeprop_exit_program(); err = elfloader_load(fd); if(err == ELFLOADER_OK) { PRINTF(("codeprop: starting %s\n", elfloader_autostart_processes[0]->name)); autostart_start(elfloader_autostart_processes); } return err; }
bool elfexec_init(void *elf, size_t file_size, struct elfexec *holder, uint8_t priority, seL4_CPtr io_ep) { if (io_ep == seL4_CapNull || elf == NULL || holder == NULL) { ERRX_RAISE_GENERIC(GERR_NULL_VALUE); return false; } holder->page_directory = object_alloc(seL4_IA32_PageDirectoryObject); if (holder->page_directory == NULL) { ERRX_TRACEPOINT; return false; } holder->cspace = object_alloc(seL4_CapTableObject); if (holder->cspace == NULL) { object_free_token(holder->page_directory); ERRX_TRACEPOINT; return false; } holder->priv_cookie = 0; holder->pd = elfloader_load(elf, file_size, object_cap(holder->page_directory)); if (holder->pd == NULL) { elfexec_destroy(holder); ERRX_TRACEPOINT; return false; } seL4_IA32_Page ipc_page = elfloader_get_page(holder->pd, (void *) IPC_ADDRESS, ELF_MEM_READABLE | ELF_MEM_WRITABLE, true); if (ipc_page == seL4_CapNull) { elfexec_destroy(holder); ERRX_TRACEPOINT; return false; } if (!cspace_configure(holder, ipc_page, io_ep)) { elfexec_destroy(holder); ERRX_TRACEPOINT; return false; } // other capability parameters such as page directory are pulled from the cspace holder->priv_cookie = exec_init(object_cap(holder->cspace), IPC_ADDRESS, priority, holder->pd->entry_position); if (!holder->priv_cookie) { elfexec_destroy(holder); ERRX_TRACEPOINT; return false; } return true; }
/*---------------------------------------------------------------------*/ PROCESS_THREAD(codeprop_process, ev, data) { PROCESS_BEGIN(); s.id = 0/*random_rand()*/; send_time = CLOCK_SECOND/4; PT_INIT(&s.udpthread_pt); PT_INIT(&s.recv_udpthread_pt); tcp_listen(HTONS(CODEPROP_DATA_PORT)); udp_conn = udp_broadcast_new(HTONS(CODEPROP_DATA_PORT), NULL); codeprop_event_quit = process_alloc_event(); s.state = STATE_NONE; s.received = 0; s.addr = 0; s.len = 0; while(1) { PROCESS_YIELD(); if(ev == EVENT_START_PROGRAM) { /* First kill old program. */ elfloader_unload(); elfloader_load(EEPROMFS_ADDR_CODEPROP); } else if(ev == tcpip_event) { uipcall(data); } else if(ev == PROCESS_EVENT_TIMER) { tcpip_poll_udp(udp_conn); } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(console_server, ev, data) { static uint8_t buf[257]; static uint8_t processingFile = 0; static uint32_t received = 0; static struct cfs_dirent dirent; static struct cfs_dir dir; static uint32_t fdFile; static char *filename; PROCESS_BEGIN(); elfloader_init(); printf("Console server started !\n"); while(1) { PROCESS_YIELD(); if (ev == serial_line_event_message) { if (!strcmp(data, "ls")) { if(cfs_opendir(&dir, ".") == 0) { while(cfs_readdir(&dir, &dirent) != -1) { printf("File: %s (%ld bytes)\n", dirent.name, (long)dirent.size); } cfs_closedir(&dir); } } else if (!strcmp(data, "format")) { /* format the flash */ printf("Formatting\n"); printf("It takes around 3 minutes\n"); printf("...\n"); fdFile = cfs_coffee_format(); printf("Formatted with result %ld\n", fdFile); } else if (strstr(data, "cat") == data) { int n, jj; char* tmp = strstr(data, " "); tmp++; fdFile = cfs_open(tmp, CFS_READ); if (fdFile < 0) printf("error opening the file %s\n", tmp); while ((n = cfs_read(fdFile, buf, 60)) > 0) { for (jj = 0 ; jj < n ; jj++) printf("%c", (char)buf[jj]); } printf("\n"); cfs_close(fdFile); if (n!=0) printf("Some error reading the file\n"); } else if (strstr(data, "loadelf") == data) { filename = strstr(data, " "); filename++; // Cleanup previous loads if (elfloader_autostart_processes != NULL) autostart_exit(elfloader_autostart_processes); elfloader_autostart_processes = NULL; // Load elf file fdFile = cfs_open(filename, CFS_READ | CFS_WRITE); received = elfloader_load(fdFile); cfs_close(fdFile); printf("Result of loading %lu\n", received); // As the file has been modified and can't be reloaded, remove it printf("Remove dirty firmware '%s'\n", filename); cfs_remove(filename); // execute the program if (ELFLOADER_OK == received) { if (elfloader_autostart_processes) { PRINT_PROCESSES(elfloader_autostart_processes); autostart_start(elfloader_autostart_processes); } } else if (ELFLOADER_SYMBOL_NOT_FOUND == received) { printf("Symbol not found: '%s'\n", elfloader_unknown); } } else if (strstr(data, "rm") == data) { int n, jj; char* tmp = strstr(data, " "); tmp++; cfs_remove(tmp); } else if (strstr(data, "upload") == data) { char* tmp = strstr(data, " "); tmp++; fdFile = cfs_open(tmp, CFS_READ | CFS_WRITE); printf("Uploading file %s\n", tmp); processingFile = 1; } else if (!strcmp(data, "endupload")) { cfs_close(fdFile); printf("File uploaded (%ld bytes)\n", received); received = 0; processingFile = 0; } else if (processingFile) { int n = strlen(data); int r = decode(data, n, buf); received += r; cfs_write(fdFile, buf, r); } else { printf("%s (%lu bytes received)\n", (char*)data, received); } } } PROCESS_END(); }
void elf_netload (void) { int elfloader_err; uint32_t sleep_time = 4000; uint16_t packet_nr = 0; uint16_t packet_nrfake = 111; /* Store thread handle for later from com.c */ elfthread = mos_thread_current(); /* Make sure packets will not be dropped before comparison */ com_mode(IFACE_RADIO, IF_LISTEN); printf("elf_netload started\n"); while (1) { last_packet_nr = -1; received_termination = 0; while (!received_termination) { /* Suspend thread waiting for radio data - similar to com_recv() */ mos_thread_suspend(); /* Analyze packet data */ if (is_elf_packet(elfbuf)) { packet_nr = -1; // Check header for packet number memcpy(&packet_nr, &elfbuf->data[PACKET_NR_OFFSET], sizeof(uint16_t)); if (last_packet_nr + 1 >= packet_nr) { if (elfbuf->size == DATA_OFFSET) { // Received termination packet... printf("received termination packet: %d\n", packet_nr); received_termination = 1; } else { last_packet_nr = packet_nr; printf("writing data to elfstore: %d\n", packet_nr); elfstore_write(&elfbuf->data[DATA_OFFSET], (DATASIZE)*packet_nr, DATASIZE); } } else { // ignore out of synch packets printf("received out of sync elf packet %d\n", packet_nr); } } else { printf("error, elf_netload() received non-ELF data\n"); } com_free_buf(elfbuf); mos_led_toggle (2); } printf("loading elf now\n"); /* Load and unload forever */ if (elfloader_loaded_unload != NULL) { printf("shutting down already started application...\n"); elfloader_loaded_unload(); elfloader_loaded_unload == NULL; } printf("sleeping...\n"); mos_thread_sleep (SLEEPTIME); /* Load ELF */ printf("loading ELF now..."); elfloader_err = elfloader_load(); if (elfloader_err != ELFLOADER_OK) { printf("failed\n"); printf("ELF loader returned error %C, elfloader_unknown = %s\n", elfloader_err, elfloader_unknown); printf("symbols size is %C\n", sizeof(symbols)); } else { /* Start loaded application */ printf("success\n"); printf("sleeping...\n"); mos_thread_sleep (SLEEPTIME); printf("starting loaded application now...\n"); elfloader_loaded_load(); } printf("waiting until duplicate packets gone\n"); mos_thread_sleep (SLEEPTIME); } }
static int exec_file(char *name, char **error) { int fd; int ret; *error = 0; /* Kill any old processes. */ if(elfloader_autostart_processes != NULL) { autostart_exit(elfloader_autostart_processes); } fd = cfs_open(name, CFS_READ | CFS_WRITE); if(fd < 0) { #if DEBUG error = "Could not open file"; #endif } else { ret = elfloader_load(fd); cfs_close(fd); #if DEBUG switch(ret) { case ELFLOADER_OK: *error = "OK"; break; case ELFLOADER_BAD_ELF_HEADER: *error = "Bad ELF header"; break; case ELFLOADER_NO_SYMTAB: *error = "No symbol table"; break; case ELFLOADER_NO_STRTAB: *error = "No string table"; break; case ELFLOADER_NO_TEXT: *error = "No text segment"; break; case ELFLOADER_SYMBOL_NOT_FOUND: *error = "Symbol not found"; // symbol = elfloader_unknown; PRINTF("Symbol not found: %s\n", elfloader_unknown); break; case ELFLOADER_SEGMENT_NOT_FOUND: *error = "Segment not found"; // symbol = elfloader_unknown; PRINTF("Segment not found: %s\n", elfloader_unknown); break; case ELFLOADER_NO_STARTPOINT: *error = "No starting point"; break; default: *error = "Unknown return code from the ELF loader (internal bug)"; break; } #endif if(ret == ELFLOADER_OK) { autostart_start(elfloader_autostart_processes); return 0; } } return 1; }