MIT6.828_HW3_XV6 System Call

Part One: System call tracing

第一个任务是修改xv6内核syscall.c中的代码,使其能够为每个系统调用都能输入如下格式的跟踪信息,跟踪信息由系统调用名称和系统调用返回值组成,格式如下:
MIT6.828_HW3_XV6 System Call
首先建立一个数组保存系统调用号和系统调用名称的映射关系,然后修改syscall函数即可,
curproc->tf->eax首先保存系统调用号,在执行系统调用后保存该系统调用的返回值,修改后的代码如下图:
MIT6.828_HW3_XV6 System Call
可选挑战:修改syscall函数使其能打印系统调用的参数
思路:eps后面的空间存储的即是参数,syscall中提供了三种取参的方法:argint(),argptr(),argstr(),但
不同系统调用的参数数量和参数类型都不同,需要加以区分,后期在熟悉syscall中涉及的十几个系统调用
后,再回来补坑。

Part Two: Date system call

第二个任务是为xv6添加一个新的系统调用,名为date,这个练习的主要目的是让我们了解一些系统调用机制的其他部分,该调用应当返回当前UTC时间给调用它的用户程序,lapic.c中定义的cmostime函数能读取实际时间,date.h中定义了rtcdate结构体,rtcdate*型指针是代入cmostime的参数类型,首先应当创建date.c文件,并在其中实现main()函数,之后在Makefile中的UPROGS区域添加_date,这一步让你能在shell下使用date指令,main()函数部分代码在课程中已经给出了,完整代码如下图:
MIT6.828_HW3_XV6 System Call
接下来的任务是创建并注册一个date系统调用,方法可以参考uptime系统调用,使用grep -n uptime *.[chs](这是一条正则查找指令, *.[chs]代表所有以.c/.h/.s后缀结尾的文件),可以查看为了创建uptime系统调用在哪些地方做了准备工作,查找结果如下图:
MIT6.828_HW3_XV6 System Call
我们依葫芦画瓢在这些地方为创建date系统调用添加相关代码即可,另外在usys.S需要添加一行SYSCALL(date),这样用户在调用date时,会自动陷入执行对应的sys_date()。
sys_date()实现代码:
MIT6.828_HW3_XV6 System Call
至此,一个新的系统调用就添加完毕,测试一下:
MIT6.828_HW3_XV6 System Call
成功!

可选挑战:添加一个dup2()系统调用,并修改shell让它能够使用该命令
dup2函数介绍:
函数原型:int dup2(int oldfd,int newfd);
函数作用:为oldfd指向的文件分配一个新的文件描述符newfd,当newfd指向的文件已被系统使用时,关闭该文件,再进行分配,当newfd=oldfd时,不关闭newfd,分配成功后,oldfd与newfd将指向同一文件。
函数返回值:newfd。
设计这个系统调用的重点是要知道怎么修改打开文件表,proc.h中定义了proc结构体用于描述当前进程状态,里面包含了该进程的打开文件表:
MIT6.828_HW3_XV6 System Call
dup2实现代码如下图
sys_dup2函数:
MIT6.828_HW3_XV6 System Calldup2.c中main函数:
MIT6.828_HW3_XV6 System Call
其他部分代码按前面做date系统调用的步骤添加就行了。