int sys_load_proc(void) { char *name = 0; char *p = 0; if (argstr(0, &name) < 0) return -1; if (argptr(1, &p, sizeof(struct proc)) < 0) return -1; return load_proc(name, (struct proc *)p); }
int main() { struct proc *p; struct trapframe *tf; printf(1,"Loading...\n"); p = malloc(sizeof(struct proc)); tf = malloc(sizeof(struct trapframe)); int fd = open("STATE.bin", O_RDONLY); if (read(fd, p, sizeof(struct proc)) < sizeof(struct proc)) printf(2, "write unsuccessfull\n"); if (read(fd, tf, sizeof(struct trapframe)) < sizeof(struct trapframe)) printf(2, "write unsuccessfull\n"); p->tf = tf; close(fd); load_proc("STATE.bin", p); wait(); exit(); }
void start(uint32_t* modulep, void* physbase, void* physfree) { uint64_t phys_size = 0; uint64_t phys_base = 0; struct smap_t { uint64_t base, length; uint32_t type; }__attribute__((packed)) *smap; while(modulep[0] != 0x9001) modulep += modulep[1]+2; for(smap = (struct smap_t*)(modulep+2); smap < (struct smap_t*)((char*)modulep+modulep[1]+2*4); ++smap) { if (smap->type == 1 /* memory */ && smap->length != 0) { printf("Available Physical Memory [%x-%x]\n", smap->base, smap->base + smap->length); phys_base = smap->base; phys_size = smap->length; } } printf("tarfs in [%p:%p]\n", &_binary_tarfs_start, &_binary_tarfs_end); printf("phs_base: %p; physbase: %p\n", phys_base, physbase); printf("physfree: %p, phys_size: %d\n", physfree, phys_size); printf("the marginal: %p\n", phys_base+phys_size); // kernel starts here //debug phys_init(phys_base, (uint64_t)physfree, phys_size); paging_init(); printf("_binary_tarfs_start: %p\n", &_binary_tarfs_start); printf("_binary_tarfs_end: %p\n", &_binary_tarfs_end); //------------for test------------- // Schedule an Primal Kernel Process create_primal_proc(); // Create an init process to invoke shell load_proc("bin/hello", NULL); //schedule_flag = 0x1; }
object *reload_proc(object *arguments) { write(stdout, load_proc(cons(make_string("../lib/stdlib.ss"), the_empty_list))); printf("\n"); return ok_symbol; }
/** * Process management entry point. * This function can be entered in one of three states: * 1 - The process is not initialized and this is the very first time * through. * 2 - The current pid does not match the pid stored in the process passed * to this function (fork or clone has recently taken place) * 3 - First time through after an exec* call (memory is no longer valid) * @param p The state of the current process */ void do_initialize (proc_t * p) { char *log = NULL, *trace = NULL; pid_t ppid = 0, pid = gettid (); int first_time = 0, do_reset = 1; if (! _state) { /* * The global state is not valid, chekc if we were just exec'd. * State is managed periodically by writing to file so this * can be verified by finding a file with our pid or the parent pid. */ int res = 0; struct stat stat_buf; char fname[FNAME_SIZE] = {0}; /* check this pid first */ snprintf (fname, FNAME_SIZE, MARSHAL_FILE, pid); res = stat (fname, &stat_buf); if (res != 0 && res == ENOENT) { /* try the parent */ snprintf (fname, FNAME_SIZE, MARSHAL_FILE, getppid ()); res = stat (fname, &stat_buf); if (res != 0 && res == ENOENT) { /* no apparent saved history, * first time through ever * * Fall through */ } else if (res == 0) { /* Use ppid information */ _state = load_proc (fname); } } else if (res == 0) { /* use state of previous pid */ _state = load_proc (fname); } if (! _state) { /* No previous history found, allocate new memory */ _state = calloc (1, sizeof (proc_t)); if (! _state) _exit (42); first_time = 1; do_reset = 0; } p = _state; } if (p->pid == pid && p->initialized) return; if (p->pid == pid) do_reset = 0; ppid = p->pid; p->pid = pid; log = getenv ("NTRACE_LOG_FILE"); trace = getenv ("NTRACE_TRACE_FILE"); if (log) { p->log = fopen (log, "a"); } else { char logfile[FNAME_SIZE] = {0}; snprintf (logfile, FNAME_SIZE, "/tmp/call.%d.log", p->pid); p->log = fopen (logfile, "w"); } fprintf (p->log, CALL_HEADER); fflush (p->log); if (trace) { p->trace = fopen (trace, "a"); } else { char tracefile[FNAME_SIZE] = {0}; snprintf (tracefile, FNAME_SIZE, "/tmp/trace.%d.log", p->pid); p->trace = fopen (tracefile, "w"); } /* * On process creation, std{in,out,err} are assumed to be disk IO. * After that, all properties are inherited from the parent */ if (first_time) { TRACE (p, " Process created (%p): pid => %d, ppid => %d\n", p, p->pid, ppid); associate_fd (p, fileno (stdin), FD_DISK); associate_fd (p, fileno (stdout), FD_DISK); associate_fd (p, fileno (stderr), FD_DISK); } /* * If this flag is set, a parent's state was used to populate the * current process state. As such, it is necessary to re-hash all * of the flows to their respective positions in the flow storage * * NOTE: In the case where hash_key (p, fd) returns fd % X, this is * entirely a waste of time (current implementation). However, it may * be the case that the key becomes a function of the pid and fd in * which case this will be necessary. */ if (do_reset) { int i = 0; flow_t buff[FLOWS_MAX]; TRACE (p, " Copying details from ppid:%d (getppid:%d)\n", ppid, getppid ()); for (i = 0; i < FLOWS_MAX; ++i) memset (&buff[i], 0, sizeof (flow_t)); /* * While the fds are inherited from the parent, the traffic is *not* * Clear all entries before rehashing * * This implicitly assumes that fds active in the parent are * active in the child. */ for (i = 0; i < FLOWS_MAX; ++i) { clear_flow (&(p->flows[i])); if (p->flows[i].active) { key_t key = hash_key (p, p->flows[i].fd); TRACE (p, " rehash %d (%s)\n", p->flows[i].fd, flow2str (&(p->flows[i]))); memcpy (&buff[key], &(p->flows[i]), sizeof (flow_t)); } } /* copy back only the active flows*/ for (i = 0; i < FLOWS_MAX; ++i) memcpy (&(p->flows[i]), &buff[i], sizeof (flow_t)); } signal (SIGINT, signal_handler); atexit (exit_fun); p->initialized = 1; save_proc (p); }