XV6实验-Lab1 Syscalls

本文档详细介绍了XV6实验的两个部分:系统调用追踪(Lab1 Syscalls)和系统信息收集(Lab2 Sysinfo)。在系统调用追踪中,需创建名为`trace`的新系统调用来记录指定系统调用的调用信息;在系统信息收集实验中,要添加`sysinfo`系统调用来返回系统内存使用和进程状态等信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

EXERCISE 0

阅读xv6 book第二章和第四章4.3和4.4节以及相关代码,理解xv6内核和系统调用
用户空间代码位于 user / user.h 和 user / usys.pl中 。
内核空间代码为 kernel / syscall.h ,kernel / syscall.c。
进程相关的代码是 内核/ proc.h 和 内核/ proc.c 。

代码阅读
user.h
定义了系统调用的一系列函数
fork
exit
wait
pipe
write
read
close
kill
exec
open
mknod
unlink
fstat
link
mkdir
chdir
dup
getpid
sbrk
sleep
uptime

ulib.c
stat
strcpy
memmove
strchr
strcmp
fprintf
printf
gets
strlen
memset
malloc
free
atoi
memcmp
memcpy

usys.S
定义SYSCALL(name)的汇编代码

syscall.h
定义system call numbers1~21

syscall.c
fetchaddr获取当前进村的uint64地址
fetchstr
argraw
argint获取32bit 系统调用
argaddr获取一个指针,不检查合法性(在copyin/copyout中做)
argstr获取n字长的系统调用 复制进buf
定义一系列的系统调用函数
void syscall(void) 系统调用函数。

proc.h
为内核上下文开关保存的寄存器。
struct context{ra; sp; s0~s11}
struct cpu{proc; context; noff; intena}CPU状态

trapframe
/trampoline.S中陷阱处理代码的每进程数据。
//坐在一个页面本身就在trampoline页面的下面
//用户页表。在内核页表中没有特别映射。
//sscratch寄存器指向这里。
//trampoline.S中的uservec在trapframe中保存用户寄存器,
//然后从trapframe的//kernel_sp、kernel_hartid、kernel_satp,初始化寄存器,并跳到kernel_trap。
//在trampoline.S设置中的usertrapret()和userret
//trapframe的内核,从trapframe,切换到user page表,然后进入user space。
//trapframe包括被调用者保存的用户寄存器,如s0-s11,因为通过usertrapret()返回用户路径不会通过整个内核调用堆栈。

procstate{UNUSED, SLEEPING, RUNNABLE, RUNNING, ZOMBIE}

struct proc{lock, state, parent, chan, killed, xstate, pid, kstack, sz, pagetable, trapframe, context, ofile, vwd, name}每个进程的状态

proc.c
cpus
proc
initproc
forkret
wakeup1
freeproc
procinit//启动时初始化proc table
cpuid
mycpu
myproc
allocpid
allocproc
freeproc
proc_pagetable
proc_freepagetable
userinit
growproc
fork
reparent
exit
wait
scheduler
sched
yield
forkret
sleep
wakeup
wakeup1
kill
either_copyout
either_copyin
procdump

EXERCISE 1 System Call Tracing

目的

创建新的系统调用trace来控制跟踪。它有一个参数,即整数掩码(mask),位数指定跟踪的那个系统调用。
eg. trace(1 << SYS_fork),跟踪fork调用,其中SYS_fork是系统调用号,位于kernel / syscall.h中 。 。
如果在掩码中设置了系统调用的编号,则必须修改xv6内核以在每个系统调用即将返回时打印出一行。
该行应包含pid,系统调用name和返回值。
无需打印系统调用参数。 trace系统调用应该跟踪调用它的进程和进程fork的孩子,但应该不会影响其他进程。

提示

  1. 添加到Makefile的UPROGS中
  2. 运行make qemu会发现不能编译trace.c,因为系统调用的用户空间不存在。天津一个原型系统调用到user/user.h,存根到user/usys.pl和syscall号kernel/syscall.h中。Makefile会调用perl脚本user/usys.pl,生成user/usys.S,该存根使用RISC-V ecall指令转换到内核。解决编译问题后,运行trace 32 grep hello README,会失败,因为还没有实现系统调用
  3. 在kernel/sysproc.c中添加一个sys_trace()函数,该函数通过记住新变量中的参数来实现新的系统调用。proc结构(参阅kernel/proc.h),从用户空间检索系统调用的函数位于kernel/syscall.c中,参阅kernel/sysproc.c获得用法示例。
  4. 修改fork()(参阅kernel/proc.c)以将trace的掩码从父进程复制进子进程中。
  5. 修改syscall.c的syscall()函数以打印trace的输出。需要添加一个系统调用名称数组来建立索引。
//Makefile
	$U/_trace\
//user.h
int trace(int);// added by me.
//usys.pl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值