媒体驱动程序:完整课程,对实验课的建议及意见
来源: https://MP.weixin.QQ.com/s/L8O sg2 elbjnvcsozj 5k dlq在上次实验中,使用系统调用创建了一些实用程序。 在本实验中,您将向xv6添加新的系统调用。 这有助于了解它们是如何工作的,也有助于了解xv6内核的内部结构。 在今后的实验中,可能会添加更多的系统调用。
开始编码之前,请阅读xv6文档的第2章、第4章的4.3节、4.4节和下面列出的相关源文件。
系统调用的用户空间代码:位于user/user.h和user/usys.pl中。
内核空间代码:位于kernel/syscall.h和kernel/syscall.c中。
流程相关代码:可在kernel/proc.h和kernel/proc.c中找到。
开始本实验之前,请切换到syscall分支:
$ git fetch
$ git checkout syscall
$ make clean
1. 系统调用跟踪(难度:中等)
在33558www.Sina.com/XV6中添加系统调用跟踪功能,以帮助在以后的实验中调试程序。 创建用于控制跟踪的新trace系统调用。 参数、整数“mask”和位必须指定要跟踪的系统调用。 例如,为了跟踪fork系统调用,程序调用trace(1SYS_fork )。 其中sys_fork是kernel/syscall.h的syscall编号。 如果为掩码设置了系统调用编号,则必须修改xv6内核,以便在返回每个系统调用之前输出一行。 该行必须包括进程id、系统调用的名称和返回值。 不需要输出系统调用参数。 trace系统调用必须启用对调用它的进程及其后续子进程的跟踪,但不应影响其他进程。
提供跟踪用户级别的程序,以运行另一个启用了跟踪的程序(请参见user/trace.c )。 完成后,将显示与以下内容类似的输出:
在上面的第一个示例中,trace调用grep跟踪只有read系统调用。 32是1SYS_read。 在第二个示例中,trace跟踪执行grep时使用的所有系统调用。 其中,2147583647的低位31位为1。 在第三个示例中,未跟踪程序,因此不会打印跟踪输出。 在第四个示例中,将跟踪user tests forkfork测试的所有后代的fork系统调用。 如果程序如上所述运行,则解决方案是正确的。 但是,进程ID可能不同。
任务:
将$U/_trace添加到Makefile的UPROGS
运行make qemu时,您会看到编译器无法编译user/trace.c。 这是因为还没有系统调用的用户区域存根(stubs )。 将系统调用原型添加到user/user.h,存根添加到user/usys.pl,syscall编号添加到。makefile调用perl脚本user/usys.pl,user/usys.pl 修复编译问题后,运行trace 32 grep hello自述文件; 由于内核中没有实现系统调用,因此将失败。
在kernel/sysproc.c中添加sys_strace )函数,通过在proc结构的新变量中记住参数来实现新的系统调用(请参见kernel/proc.h )。 您可以在kernel/sysproc.c上看到使用kernel/syscall.c函数从用户空间中检索系统调用参数的示例。
将fork (更改) (请参见kernel/proc.c )跟踪掩码从父进程复制到子进程。
更改kernel/syscall.c的syscall ()函数,输出跟踪输出。 要创建索引,必须添加具有syscall名称的数组。
提示:
步骤1 :更改用户界面代码
(1)在user/user.h中添加系统调用函数的定义。
)2)在user/usys.pl中添加条目entry('trace ' )。
在生成时调用usys.pl生成user/usys.S程序集。 在这个汇编器中,每个函数有5行,其中有3条指令,其功能是用li(loadimm )把系统呼叫号码存入a7寄存器,然后用ecall指令进入内核状态,最后返回。
make之后,user/usys.S将显示下图中以. global trace开头的五行代码。
步骤2 :更改内核代码
(1)用kernel/syscall.h定义系统呼叫号码。
)2)添加与kernel/syscall.c中的syscalls函数指针数组相对应的函数。
syscall函数可以读取trapframe-a7以获取系统调用编号,并根据该系统调用编号在syscalls数组中查找和调用相应的处理函数。
)3)将trace_mask字段添加到proc结构中,使用fork函数将该字段复制到新的进程中,以创建子进程。
kernel/proc.h
kernel/proc.c
)4)系统调用sys_trace的实现。 将函数uint64 sys_trace(void )添加到sysproc.c中。 此函数通过argint函数读取参数并将其赋给mask变量,然后指定trace_mask字段位或。
)5)修正syscall函数,在系统呼叫号码与trace_mask一致的情况下输出相关信息。
请注意上图中黄线处的syscall_name[num]。 这需要定义。 如下图所示。
步骤3 :创作实用程序(注意:在源代码中可用) )。
user/trace.c
第4步:修改makefile并将$U/_trace添加到makefile的UPROGS中。
步骤5 :生成请求,然后测试。
xv6实验课程--Lab tools
xv6实验课程--Lab guidance
xv6实验课程--Xv6和Unix实用程序(
xv6实验课程--Xv6和Unix实用程序(