📄 proc.c
字号:
/* * Roadrunner/pk * Copyright (C) 1989-2001 Cornfed Systems, Inc. * * The Roadrunner/pk operating system is free software; you can * redistribute and/or modify it under the terms of the GNU General * Public License, version 2, as published by the Free Software * Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * More information about the Roadrunner/pk operating system of * which this file is a part is available on the World-Wide Web * at: http://www.cornfed.com. * */#include <errno.h>#include <fcntl.h>#include <fs.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys.h>#include <sys/config.h>#include <sys/intr.h>#include <sys/mem.h>#include <sys/proc.h>#include <sys/queue.h>#include <unistd.h>static char *cwdpaths = NULL;struct proc proctab[PROCS];proc_t current = NULL;struct queue ready;voidproc_clear(proc_t proc){ int i; //2002年10月09日修改-vm //if (proc->context.ptrec != NULL) { // pt_push(proc->context.ptrec); // proc->context.ptrec = NULL; //} //proc->context.kstk = NULL;
proc->context.stk = NULL; proc->context.start = NULL; proc->context.argc = 0; proc->context.argv = NULL; proc->next = NULL; proc->q = NULL; proc->state = PS_NULL; proc->wait = NULL; bzero(proc->cwd, PATH_LENGTH); strcpy(proc->cwd, "/"); for (i = 0; i < PFDS; i++) proc->fd[i] = (-1);}voidproc_sysinit(){ int i; //2002年10月09日修改 //cwdpaths = (char *) kmalloc(PROCS * PATH_LENGTH);
cwdpaths = (char *) malloc(PROCS * PATH_LENGTH); bzero(cwdpaths, PROCS * PATH_LENGTH); for (i = 0; i < PROCS; i++) { proctab[i].context.tss = &(tsstab[i]); proctab[i].slot = i; proctab[i].cwd = cwdpaths + (i * PATH_LENGTH); proc_clear(&(proctab[i])); }} voidproc_transfer(){ proc_t proc = current; /* Assume interrupts are disabled */ if ((current = remfirstq(&ready)) == NULL) { kprintf("proc_transfer: no ready processes\n"); //halt();//2002年09月12日修改 } current->state = PS_RUN; if (current == proc) { enable; return; } //2002年09月12日修改 proc_jmp(&proc->context.tss->ssp,¤t->context.tss->ssp); /* enables interrupts */ enable;
}
voidproc_start(){ (current->context.start) (current->context.argc, current->context.argv); proc_exit(0); /* Not reached */}inttask_exec(void *start){ int i; void *stk; proc_t proc; u_long *SP_INIT; disable; for (i = 0; i < PROCS; i++) if (proctab[i].state == PS_NULL) break; if (i == PROCS) { proc = NULL; enable; return EAGAIN; } /* Allocate user stack */ stk = mem_alloc(STACK_SIZE); if (stk == NULL) { //mem_free(kstk); proc = NULL; enable; return ENOMEM; } proc = &(proctab[i]); //mem_transfer(kstk, *proc); mem_transfer(stk, proc); strcpy(proc->cwd, current->cwd); filetab[current->fd[PFD_STDIN]].refcnt++; filetab[current->fd[PFD_STDOUT]].refcnt++; filetab[current->fd[PFD_STDERR]].refcnt++; proc->fd[PFD_STDIN] = current->fd[PFD_STDIN]; proc->fd[PFD_STDOUT] = current->fd[PFD_STDOUT]; proc->fd[PFD_STDERR] = current->fd[PFD_STDERR]; /* Initialize execution context */ proc->context.stk = stk; proc->context.start = start; tssinit(proc->context.tss,(u_long)stk,STACK_SIZE); proc->context.argc = 0; proc->context.argv = NULL; //2002年09月12日修改 SP_INIT = (u_long *)(proc->context.tss->ssp); *SP_INIT =(u_long)proc->context.argv; SP_INIT -= 1; *SP_INIT = (u_long)proc->context.argc; SP_INIT -=1; *SP_INIT = (u_long)proc->context.start; SP_INIT -= 1; //r4 *SP_INIT = 0;
SP_INIT -= 1; //r0 *SP_INIT = 0; SP_INIT -= 1; //r1 *SP_INIT = 0; SP_INIT -= 1; //r2 *SP_INIT = 0; SP_INIT -= 1; //r3 *SP_INIT = 0; SP_INIT -= 1; //r4 *SP_INIT = 0; SP_INIT -= 1; //r5 *SP_INIT = 0; SP_INIT -= 1; //r6 *SP_INIT = 0; SP_INIT -= 1; //r7 *SP_INIT = 0; SP_INIT -= 1; //r8 *SP_INIT = 0; SP_INIT -= 1; //r9 *SP_INIT = 0; SP_INIT -= 1; //r10 *SP_INIT = 0; SP_INIT -= 1; //r11 *SP_INIT = 0; SP_INIT -= 1; //r12 *SP_INIT = 0;
proc->context.tss->ssp = (u_long)SP_INIT; insq(proc, &ready); current->state = PS_READY; insq(current, &ready); proc_transfer(); /* enables interrupts */ return proc->slot;}intproc_init(proc_t * proc, void *start, int argc, char **argv){ //void *kstk, *stk; int i; void *stk; u_long *SP_INIT; /* Find process table slot */ for (i = 0; i < PROCS; i++) if (proctab[i].state == PS_NULL) break; if (i == PROCS) { *proc = NULL; return EAGAIN; } /* Allocate kernel stack */ //2002年10月09日修改-vm //kstk = mem_alloc(STACK_SIZE); //if (kstk == NULL) { // //*proc = NULL; // //return ENOMEM; //} /* Allocate user stack */ stk = mem_alloc(STACK_SIZE); if (stk == NULL) { //mem_free(kstk); *proc = NULL; return ENOMEM; } *proc = &(proctab[i]); //mem_transfer(kstk, *proc); mem_transfer(stk, *proc); strcpy((*proc)->cwd, current->cwd); /* Duplicate access to file descriptors *//*#if 0 { char fullpath[PATH_LENGTH]; file_t file; bzero(fullpath, PATH_LENGTH); mkpath(filetab[current->fd[PFD_STDERR]].fs->path, filetab[current->fd[PFD_STDERR]].path, fullpath); file_open(fullpath, O_RDONLY, &file); (*proc)->fd[PFD_STDERR] = file->slot; bzero(fullpath, PATH_LENGTH); mkpath(filetab[current->fd[PFD_STDIN]].fs->path, filetab[current->fd[PFD_STDIN]].path, fullpath); file_open(fullpath, O_RDONLY, &file); (*proc)->fd[PFD_STDIN] = file->slot; bzero(fullpath, PATH_LENGTH); mkpath(filetab[current->fd[PFD_STDOUT]].fs->path, filetab[current->fd[PFD_STDOUT]].path, fullpath); file_open(fullpath, O_RDONLY, &file); (*proc)->fd[PFD_STDOUT] = file->slot; }#endif*/ filetab[current->fd[PFD_STDIN]].refcnt++; filetab[current->fd[PFD_STDOUT]].refcnt++; filetab[current->fd[PFD_STDERR]].refcnt++; (*proc)->fd[PFD_STDIN] = current->fd[PFD_STDIN]; (*proc)->fd[PFD_STDOUT] = current->fd[PFD_STDOUT]; (*proc)->fd[PFD_STDERR] = current->fd[PFD_STDERR]; /* Initialize execution context */ //(*proc)->context.kstk = kstk; (*proc)->context.stk = stk; (*proc)->context.start = start; tssinit((*proc)->context.tss,(u_long)stk,STACK_SIZE); SP_INIT = (u_long *)((u_long)start + 12); *SP_INIT = (*proc)->context.tss->ssp; /* Initialize memory protection */ /* XXX Need to do error handling on pt_pop() */ //2002年10月09日修改-vm //(*proc)->context.ptrec = pt_pop(); //(*proc)->context.tss->cr3 = (u_long) (*proc)->context.ptrec->pd; //vm_map_init((pt_t) (*proc)->context.tss->cr3); //vm_kmap((pt_t) (*proc)->context.tss->cr3); //vm_map_range((pt_t) (*proc)->context.tss->cr3, // // kstk, STACK_SIZE, PTE_WRITE | PTE_PRESENT); //vm_map_range((pt_t) (*proc)->context.tss->cr3, // // stk, STACK_SIZE, PTE_WRITE | PTE_USER | PTE_PRESENT); /* Handle argv array */ if (argv != NULL) { region_t r; //r = valid_region(argv); //if (r == NULL) { // (*proc)->context.argc = 0; // (*proc)->context.argv = NULL; // //} else
{ (*proc)->context.argc = argc; (*proc)->context.argv = argv; // /* Transfer ownership of argv array memory to new process */ // mem_transfer(argv, *proc); // //vm_map_range((pt_t) (*proc)->context.tss->cr3, argv, // //r->len, PTE_WRITE | PTE_USER | PTE_PRESENT); // //vm_unmap_range((pt_t) current->context.tss->cr3, argv, r->len); } } //2002年09月12日修改 SP_INIT = (u_long *)((*proc)->context.tss->ssp); *SP_INIT =(u_long)(*proc)->context.argv; SP_INIT -= 1; *SP_INIT = (u_long)(*proc)->context.argc; SP_INIT -=1; *SP_INIT = (u_long)(*proc)->context.start; SP_INIT -= 1; //r4 *SP_INIT = 0; SP_INIT -= 1; //r0 *SP_INIT = 0; SP_INIT -= 1; //r1 *SP_INIT = 0; SP_INIT -= 1; //r2 *SP_INIT = 0; SP_INIT -= 1; //r3 *SP_INIT = 0; SP_INIT -= 1; //r4 *SP_INIT = 0; SP_INIT -= 1; //r5 *SP_INIT = 0; SP_INIT -= 1; //r6 *SP_INIT = 0; SP_INIT -= 1; //r7 *SP_INIT = 0; SP_INIT -= 1; //r8 *SP_INIT = 0; SP_INIT -= 1; //r9 *SP_INIT = 0; SP_INIT -= 1; //r10 *SP_INIT = 0; SP_INIT -= 1; //r11 *SP_INIT = 0; SP_INIT -= 1; //r12 *SP_INIT = 0;
(*proc)->context.tss->ssp = (u_long)SP_INIT; return 0; }pid_tproc_exec(char *path, int argc, char **argv){ proc_t proc; char *prog, *start; u_long size; int result; result = load(path, &prog, &size, &start); if (result < 0) {#if _DEBUG kprintf("proc_exec: could not load %s (%s)\n", path, strerror(result));#endif return result; } disable; result = proc_init(&proc, start, argc, argv); if (result < 0) {#if _DEBUG kprintf("proc_exec: init failed (%s)\n", strerror(result));#endif enable; return result; } /* Transfer ownership of program memory to new process */ //2002年10月09日修改-vm //mem_transfer(prog, proc); //vm_map_range((pt_t) proc->context.tss->cr3, prog, size, // // PTE_WRITE | PTE_USER | PTE_PRESENT); //vm_unmap_range((pt_t) current->context.tss->cr3, prog, size); /* Make new process ready to execute */ insq(proc, &ready); current->state = PS_READY; insq(current, &ready); proc_transfer(); /* enables interrupts */ return proc->slot;}char *proc_getcwd(char *buf, size_t size){ if (buf == NULL) return NULL; disable; strncpy(buf, current->cwd, size); enable; return buf;}intproc_chdir(char *path){ char *fullpath; file_t file; int result; if (path == NULL || strlen(path) > (PATH_LENGTH - 1)) return EINVAL; /* Make sure we have an absolute path */ if (path[0] == '/') fullpath = path; else { fullpath = (char *) malloc(PATH_LENGTH); if (fullpath == NULL) return ENOMEM; mkpath(current->cwd, path, fullpath); } /* Check whether directory exists */ result = file_open(fullpath, O_RDONLY, &file); if (result < 0) { if (fullpath != path) free(fullpath); return result; } /* Make sure the file is really a directory */ if (!(file->flags & F_DIR)) { if (fullpath != path) free(fullpath); return ENOTDIR; } file_close(file); disable; /* Set new working directory for current process */ bzero(current->cwd, PATH_LENGTH); strcpy(current->cwd, fullpath); enable; if (fullpath != path) free(fullpath); return 0;}intproc_wait(pid_t pid){ proc_t proc; if (pid < 0 || pid >= PROCS) return EINVAL; proc = &(proctab[pid]); disable; if (proc == current) { enable; return EINVAL; } if (proc->state == PS_NULL) { enable; return ESRCH; } current->state = PS_WAIT; current->next = proc->wait; proc->wait = current; proc_transfer(); /* enables interrupts */ return 0;}voidproc_exit(int status){ proc_t proc; /* Close stdpath file descriptors */ file_close(&(filetab[current->fd[PFD_STDIN]])); file_close(&(filetab[current->fd[PFD_STDOUT]])); file_close(&(filetab[current->fd[PFD_STDERR]])); disable; /* Schedule any waiting processes */ for (;;) { proc = current->wait; if (proc == NULL) break; current->wait = proc->next; proc->next = NULL; proc->state = PS_READY; insq(proc, &ready); } /* Free all memory allocated to the process */ mem_reclaim(current); /* Reclaim process table entry */ proc_clear(current); /* Transfer control to the next ready process */ proc_transfer(); /* enables interrupts */ kprintf("proc_exit: attempt to restart terminated process\n"); //halt();//2002年09月12日 /* Not reached */}pid_tproc_getpid(){ pid_t pid; disable; pid = current->slot; enable; return pid;}intproc_getstdpath(pid_t pid, int stdpath){ int fd; if (pid < 0 || pid >= PROCS || proctab[pid].state == PS_NULL) return EINVAL; disable; fd = proctab[pid].fd[stdpath]; enable; return fd;}voidproc_setstdpath(pid_t pid, int stdpath, int fd){ if (pid < 0 || pid >= PROCS || proctab[pid].state == PS_NULL) return; disable; proctab[pid].fd[stdpath] = fd; enable;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -