Trace

实现系统调用int trace(int mask);, 当调用mask中包含的系统调用号,打印出来。

在Makefile中增加trace用户程序的编译

UPROGS=\
	...
	$U/_trace

user/user.h中增加函数声明

int trace(int);

usys.pl中增加user space trace函数的入口。可以看到user space调用的系统调用, 是由这个脚本生成的函数。
以trace为例, 提供了trace函数的入口.global trace, 随后将定义在syscall.h中的SYS_trace编号存入寄存器a7, 通过ecall命令进入内核态。

sub entry {
    my $name = shift;
    print ".global $name\n";
    print "${name}:\n";
    print " li a7, SYS_${name}\n";
    print " ecall\n";
    print " ret\n";
}
entry("trace");

syscall.csyscall函数中通过获取a7寄存器中的编号,找到我们添加的系统调用函数,sys_trace

函数具体实现如下:

// 在proc结构体中增加mask成员
struct proc {
	//...
	int mask;
}

// 将user space传入的mask,传递给当前进程的mask变量
uint64 sys_trace(void)
{
  if(argint(0, &myproc()->mask) < 0)
    return -1;
  return 0;
}

// 随后执行的系统调用number如果 (1 << num == mask), 则打印
syscall(void)
{
    // ...
    if ((1 << num) & p->mask)
	printf("%d: syscall %s -> %d\n", p->pid, syscalls_name[num - 1], p->trapframe->a0);
}

Sysinfo

实现系统调用int sysinfo(struct sysinfo *);,返回free memory bytes和状态不是UNUSED的进程。

其中:

struct sysinfo {
  uint64 freemem;   // amount of free memory (bytes)
  uint64 nproc;     // number of process
};