xv6知识initcode.S
调用exec
,将exec
参数放进寄存器a0
和a1
,系统调用号放入a7
kernel/syscall.c
中的Syscalls
数组为函数指针表,与系统调用号进行匹配ecall
指令进入内核并执行uservec
、usertrap
,然后执行syscall
syscall
从a7
中获取调用号与Syscalls
索引匹配,进入实现函数sys_exec
系统调用实现函数返回时,将返回值放在p->trapframe->a0
,一般返回-1为失败
trace
的大致流程
首先在shell
中输入trace调用trace()
,函数内进行解析后,准备前往内核进行内核的调用
经过user/user.h
以及汇编指令,进入内核,利用ecall
进行系统调用
系统调用号由syscall.h
规定,寄存器a7
中存放系统调用号,syscall.c
中的函数利用系统调用号根据维护的函数指针数组找到系统实现函数的地址,将实现函数调用的返回值放在a0
中,系统实现函数保存在sysproc.c
中syscall.c
中的函数调用proc.c
中的myproc()
获取在proc.h
中定义的proc
结构体,结构体保存了进程相关的各种信息
实验1实现思路
在proc
结构体中增加新参数mask,作用为控制打印,系统调用时,根据系统调用号,系统调用会调用syscall.c
中的syscall()
,利用新写入的字符串输出代码,进行实验的最后输出,输出参数均可以在函数中获得
修改proc.c
中的fork()
,在建立子进程时复制masksysproc.c
添加trace系统调用实现函数,对当前进程proc
结构体的mask项进行赋值,mask的来源为调用syscall.c
中的函数获得的proc
结构体中保存的a0
,当正常调用时a0
不为0,使得mask也不为0,mask标志位将决定是否打印
syscall.c中的函数argint()
接受一个整数n和一个指针,函数内调用argraw()
,功能为将指针指向的值变为进程中第n个状态参数,调用不成功将返回-1,argint()
返回0