系统调用实习报告
目录
内容一:总体概述 .......................................................... 2 内容二:任务完成情况 ...................................................... 2
任务完成列表(Y/N) .................................................... 2 具体Exercise得完成情况 .............................................. 2 内容三:遇到得困难以及解决方法 ........................................... 14 内容四:收获及感想 ....................................................... 15 内容五:对课程得意见与建议 ............................................... 15 内容六:参考文献 ......................................................... 15
内容一:总体概述
本次lab得主要内容就是实现nachos定义得系统调用。理论方面,我们需要了解nachos系统调用得实现原理,实践方面,我们需要实现文进系统相关系统调用与用户程序相关系统调用,并且编写用户程序验证相关系统调用得正确性。
内容二:任务完成情况
任务完成列表(Y/N)
Exercise1 Exercise2 Exercise3 Exercise4 Exercise5 Y Y Y Y Y 具体Exercise得完成情况 一、理解Nachos系统调用 Exercise 1 源代码阅读
阅读与系统调用相关得源代码,理解系统调用得实现原理。 code/userprog/syscall、h code/userprog/exception、cc
code/test/start、s
userprog/syscall、h定义nachos得系统调用,主要包括系统调用号与系统调用函数,内核通过识别用户程序传递得系统调用号确定系统调用类型 已经实现得系统调用包括 void Halt();
关闭nachos虚拟机,打印性能统计信息 需要实现得系统调用包括: 3种系统调用涉及地址空间:
1)、void Exit(int status); 用户程序完成,status = 0表示正常退出 2)、SpaceId Exec(char *name);
加载并执行名字就是name得Nachos可执行文件,返回其地址空间得标志符 SpaceId实际就是整型,标识地址空间 3)、int Join(SpaceId id);
等待标志符为id得用户线程运行完毕,返回其退出状态 5种系统调用涉及文件系统: 1)、void Create(char *name); 创建文件名name得Nachos文件 2)、OpenFileId Open(char *name);
3)打开文件名name得Nachos文件,返回打开文件标志符 OpenFileId实际就是整形,标识打开文件
3)、void Write(char *buffer, int size, OpenFileId id); 向标志符就是id得文件写入buffer中长度为size字节得数据 4)、int Read(char *buffer, int size, OpenFileId id);
从标志符就是id得文件读取长度为size字节得数据存入buffer,返回实际读取得字节数
5)、void Close(OpenFileId id); 关闭标志符就是id得文件
2种系统调用涉及用户级线程,用于支持多线程用户程序: 1)、void Fork(void (*func)());
创建与当前线程拥有相同地址空间得线程,运行func指针指向得函数 2)、void Yield(); 当前线程让出CPU
code/userprog/exception、cc定义进行异常处理得ExceptionHandler函数,主要流程就是根据异常信息处理不同异常,包括系统调用 目前支持得异常:
NoException, // 正常
SyscallException, // 系统调用
PageFaultException, // 缺页(页表/快表) ReadOnlyException, // 访问只读页面 BusErrorException, // 总线错误
AddressErrorException, // 访问地址对齐错误/超出范围 OverflowException, // 算数溢出 IllegalInstrException, // 非法指令
NumExceptionTypes
处理系统调用时,需要从2号寄存器获得系统调用号确定系统调用类型 code/test/start、s就是辅助用户程序运行得汇编代码,主要包括初始化用户程序与系统调用相关操作
(1)初始化用户程序:通过调用main函数运行用户程序 、globl __start 、ent __start __start: jal
main //跳转到main函数执行用户程序
move $4,$0 //main函数返回
//r4寄存器存入0,作为下面调用Exit参数 jal
Exit
、end __start
(2)系统调用:用户程序执行系统调用时,将系统调用号存入r2寄存器,然后跳转到exception、cc执行,例如系统调用Halt: Halt:
addiu $2,$0,SC_Halt //将系统调用号存入r2寄存器 syscall j $31
、end Halt 系统调用相关寄存器:
r2->系统调用号,系统调用返回值 r4->系统调用参数1 r5->系统调用参数2 r6->系统调用参数3 r7->系统调用参数4
系统调用主要流程:
machine得Run函数运行用户程序,实现在machine/mipssim、cc,基本流程就是通过OneInstruction函数完成指令译码与执行,通过interrupt得OneTick函数使得时钟前进
(1)OneInstruction函数判断当前指令就是系统调用,转入start、s (2)通过start、s确定系统调用入口,通过寄存器r2传递系统调用号,转入exception、cc(此时系统调用参数位于相应寄存器)
(3)exception、cc通过系统调用号识别系统调用,进行相关处理,如果系统调
用存在返回值,那么通过寄存器r2传递,流程结束时,需要更新PC (4)系统调用结束,程序继续执行 添加系统调用:
(1)syscall、h定义系统调用接口、系统调用号 (2)code/test/start、s添加链接代码 (3)exception、cc添加系统调用处理过程 二、文件系统相关得系统调用 Exercise 2 系统调用实现
类比Halt得实现,完成与文件系统相关得系统调用:Create, Open,Close,Write,Read。Syscall、h文件中有这些系统调用基本说明。 基本思路:
修改userprog/exception、cc,按照userprog/syscall、h得定义实现系统调用 系统调用Create定义
void Create(char *name); 系统调用Create基本流程
(1)通过寄存器r4获得文件名指针
(2)使用文件名指针通过已经实现ReadMem函数获得文件名 (3)通过已经实现得Create函数创建文件 (4)通过函数PC_advance更新PC
系统调用Open定义
OpenFileId Open(char *name);