pintospro2项目2用户程序

上传人:桔**** 文档编号:477025336 上传时间:2023-07-02 格式:DOC 页数:45 大小:363KB
返回 下载 相关 举报
pintospro2项目2用户程序_第1页
第1页 / 共45页
pintospro2项目2用户程序_第2页
第2页 / 共45页
pintospro2项目2用户程序_第3页
第3页 / 共45页
pintospro2项目2用户程序_第4页
第4页 / 共45页
pintospro2项目2用户程序_第5页
第5页 / 共45页
点击查看更多>>
资源描述

《pintospro2项目2用户程序》由会员分享,可在线阅读,更多相关《pintospro2项目2用户程序(45页珍藏版)》请在金锄头文库上搜索。

1、wordPintos project2 某某电子科技大学王永刚 QQ:357543420这个项目将使pintos可以加载并执行用户程序,并且为用户程序提供系统调用。Project2 需要完成的的任务有四个: Task1 Process Termination Messages进程终止信息 Task2 Argument Passing 参数传递 Task3 System Calls 系统调用 Task4 Denying Writes to Executables不能写入可执行文件Task1: Process Termination Messages进程终止信息要求: 1.在进程完毕时输出退出代码

2、(就是main函数的返回值,或者异常退出代码。 注意: 用户进程完毕时输入退出代码,核心线程返回时不输入。输出格式被规定如下: printf (“%s: exit(%d)n,.); 实现方法:1. 既然要打印返回值,就得用一个变量保存返回值,于是在struct thread 结构中参加一个变量回保存返回值:int ret; 在init_thread()函数中初始化为0这里可以不用初始化。2. 在线程退出里要保存其返回值到ret中,这个将在系统调用里的exit函数中保存,这里先不考虑。在什么地方参加printf()呢?每个线程完毕后,都要调用thread_exit()函数,如果是加载了用户进程,

3、在thread_exit()函数中还会调用process_exit()函数, 在process_exit()函数中,如果是用户进程,那么其页表一定不为NULL,而核心进程页表一定为NULL,即只有用户进程退出时if(pd!=NULL) 就会成立,所以在大括号中参加:printf (“%s: exit(%d)n,cur-name,cur-ret);其中cur=thread_current();即当前线程的struct thread 指针。TASK1 OKTASK2 Argument Passing 参数传递要求:1. 别离从命令行传入的文件名和各个参数。2. 按照C函数调用约定,把参数放入栈中。

4、实现方法:strtok_r()函数,在string.c中有详细的说明。2.在process_execute()函数中,因为thread_create()需要一个线程名,此时应该传递给它文件名(不带参数)。可如下处理:char *real_name, *save_ptr; real_name = strtok_r (file_name, , &save_ptr); tid = thread_create (real_name, PRI_DEFAULT, start_process, fn_copy);3在start_process()函数中,再次别离参数,放入栈中。由于在process_exec

5、ute()对file_name作了复制,文件名并未丢失,但是要注意,无论加载用户程序成功还是失败,都得释放file_name所占用的一个页的空间(Debug here 3 weeks)。 注意:传给Load()函数的参数也只能有文件名,所以在load()函数前要别离出文件名:char *token=NULL, *save_ptr=NULL;token = strtok_r (file_name, , &save_ptr);success = load (token, &if_.eip, &if_.esp);参数放置的一种方法:1找到用户栈指针:在start_process()函数中有struc

6、t intr_frame if_; 这样一个结构,其中有一个成员if_.esp,这就是用户栈指针,在load()函数中为其赋值,分配了栈空间。2调用strtok_r 别离出一个个参数(就是一个个字符串了),把每个字符串都复制到用户栈中,并把他在栈中的位置记录到一个数组中,以备下一步使用。注意:栈是向下增长,而字符串是向上增长。 char *esp=(char *)if_.esp; char *arg256; /assume numbers of argument below 256 int i,n=0; for (; token != NULL;token = strtok_r (NULL,

7、, &save_ptr) esp-=strlen(token)+1; /because user stack increase to low addr.strlcpy(esp,token,strlen(token)+2); /copy param to user stack argn+=esp; 3要参加一个双字的对齐,因为是32位的,所以就是四字节对齐。while(int)esp%4make) /word align esp-; /注意:栈是向下增长,所以这里是而不是+;(4)要将第2步保存下的指针逆序放入栈中。按照C约定,先要放入一个0,以防没有参数。 int *p=esp-4; *p-=

8、0; 然后依次放入参数n的地址,参数n-1的地址 参数0的地址。for(i=n-1;i=0;i-) /place the arguments pointers to stack *p-=(int *)argi;(5)放入argc,argv*p-=p+1; *p-=n; *p-=0; esp=p+1;(6)让用户栈指针指向新的栈顶 if_.esp=esp如如下图摆放。 如果命令行是:/bin/ls lfoo bar完整代码见附录!TASK 3 system call 系统调用要求:1实现以下系统调用: pfnSYS_WRITE=IWrite; /printf和写文件需要。 pfnSYS_EXIT

9、=IExit; /退出时return后调用 pfnSYS_CREATE=ICreate; /创建文件 pfnSYS_OPEN=IOpen;/打开文件 pfnSYS_CLOSE=IClose; /关闭文件 pfnSYS_READ=IRead; / 读文件 pfnSYS_FILESIZE=IFileSize; /返回文件大小 pfnSYS_EXEC=IExec; /加载用户程序 pfnSYS_WAIT=IWait;/等待子进程完毕 pfnSYS_SEEK=ISeek; /移动文件指针 pfnSYS_REMOVE=IRemove; /删除文件 pfnSYS_TELL=ITell; /返回文件指针位置

10、 pfnSYS_HALT=IHalt; /关机要想完成以上系统调用,还要明白系统调用的机制,见后边。参考文件有:src/lib/user/syscall.c 了解每个系统调用的形式。src/lib/syscall-nr.h 了解每个系统调用号。实现方法:(1) 搭建框架用一个数组保存各函数名,数组下标就是系统调用号。在syscall_init()函数中初始化数组pfn为NULL在syscall_handler()函数中依据系统调用号调用相函数。typedef void (*CALL_PROC)(struct intr_frame*);CALL_PROC pfnMAXCALL;voidsysca

11、ll_init (void) intr_register_int (0x30, 3, INTR_ON, syscall_handler, syscall); int i; for(i=0;iesp) ExitStatus(-1); int No=*(int *)(f-esp); if(No=MAXCALL|MAXCALLret=status; /保存返回值。 thread_exit();SYS_CREATE-创建文件 void ICreate(struct intr_frame *f) 取出仅有的一个参数文件名。调用filesys_create()函数。保存返回值。SYS_OPEN-打开文件void IOpen(struct intr_frame *f)取出文件名。调用filesys_open()函数打开文件。这里需要为每个进程维护一个打开文件表。打开文件后要为这个文件分配一个句柄号。在struct thread 结构中参加:

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号