643 字
3 分钟
Lab:System calls
2024-08-31
无标签

Lab:System calls#

实验目的:

弄懂系统调用的过程和如何添加一个系统调用,同时了解一下 xv6 的内部机制,如内存页的分配

  • 在 xv6 中如何实现一个系统调用?

1. 用户空间函数调用#

用户空间的应用程序调用 trace 函数。这个函数的原型定义在 user/user.h 中:

int trace(int tracemask);

2. 用户空间的系统调用桩文件 (usys.S)#

当用户调用 trace 函数时,它会通过一个系统调用桩文件(usys.S)发出系统调用。

这个桩文件由 user/usys.pl 脚本生成。在 user/usys.pl 中,你添加了:

entry("trace");

这个脚本会生成一个 trace 的系统调用桩,它实质上是使用 ecall 指令进行系统调用的汇编代码。

usys.pl 脚本会生成** usys.S 文件****,其中包含每个系统调用的汇编桩代码。假设我们已经添加了 trace 系统调用,生成的 usys.S 文件可能包含如下内容:**

.globl trace
trace:
li a7, SYS_trace     # Load the system call number into register a7
ecall                # Trigger the system call
ret                  # Return from the system call

当我们在用户空间调用这个函数的时候,其实就是执行上面这个代码

3. 系统调用号 (syscall.h)#

kernel/syscall.h 中定义了系统调用号:

#define SYS_trace 22  // 假设22是新的系统调用号

这个系统调用号唯一标识 trace 系统调用。

4. 系统调用处理 (syscall 函数)#

当用户空间的程序调用 trace 函数时,系统会触发一个 ecall 指令,CPU 切换到内核模式,并跳转到 syscall 处理函数。syscall 函数定义在 kernel/syscall.c 中:

void syscall(void)
{
    int num;
    struct proc *p = myproc();

    num = p->trapframe->a7;     //取出寄存器中的参数
    if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
        p->trapframe->a0 = syscalls[num](); //在这里根据参数选择对应的函数调用
        if(p->tracemask & (1 << num)) {
            printf("%d: syscall %s -> %d\n", p->pid, syscall_names[num], p->trapframe->a0);
        }
    } else {
        printf("%d %s: unknown sys call %d\n", p->pid, p->name, num);
        p->trapframe->a0 = -1;
    }
}

5. 系统调用表 (syscalls 数组)#

syscalls** 是一个函数指针数组,其中每个元素指向一个具体的系统调用实现函数。你需要在 kernel/syscall.c 中将 SYS_trace 映射到 sys_trace 函数:**

extern int sys_trace(void);

static int (*syscalls[])(void) = {
    ...
        [SYS_trace]   sys_trace,
};

6. 内核中的 sys_trace 实现#

最终,syscall 函数会调用 sys_trace 函数,该函数在 kernel/sysproc.c 中实现:

uint64
sys_trace(void)
{
    int tracemask;
    if(argint(0, &tracemask) < 0)
        return -1;
    myproc()->tracemask = tracemask;
    return 0;
}

sys_trace 使用 argint 函数从用户空间获取参数,并将其存储在当前进程的 tracemask 变量中。


Lab:System calls
https://scudays.github.io/posts/6s081/lab/labsystem-calls/
作者
Days
发布于
2024-08-31
许可协议
CC BY-NC-SA 4.0