【xv6-labs】02 Lab: system calls

GDB

如何启动gdb

  • 启动 make CPUs=1 qemu-gdb
  • 在另一个终端启动 gdb-multiarch kernel/kernel
  • 进入gdb后输入 target remote localhost:26000

GDB 的一些命令

  • shell clear # 清屏
  • layout src # 显示源码
  • layout regs # 显示寄存器
  • layout split # 同时显示源码和寄存器
  • backtrace # 显示函数调用栈

在XV6 如何添加系统调用

  1. user/user.h 中添加系统调用函数的定义. 比如:
struct stat;

// system calls
int fork(void);
int exit(int) __attribute__((noreturn));
int wait(int*);
int pipe(int*);
int write(int, const void*, int);
int read(int, void*, int);
int close(int);
  1. user/usys.pl 中添加入口, 这个文件会在 make 后生成 user/usys.S 文件, 在该汇编文件中,每个函数就只有三行,将系统调用号通过 li(load imm) 存入 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("fork");
entry("exit");
  1. kernel/syscall.h中定义系统调用号
#define SYS_mkdir  20
#define SYS_close  21
#define SYS_trace  22
  1. kernel/syscall.csyscalls 函数指针数值中添加对应的函数。
// An array mapping syscall numbers from syscall.h
// to the function that handles the system call.
// 这里的static uint64 (*syscalls[])(void)
// 表示定义一个 静态函数指针的数组
// 函数指针参数是void, 返回值是 uint64
// [SYS_fork]    sys_fork, 表示将第 SYS_fork 设置为 sys_fork
static uint64 (*syscalls[])(void) = {
[SYS_fork]    sys_fork,
[SYS_exit]    sys_exit,
[SYS_wait]    sys_wait,
[SYS_pipe]    sys_pipe,
[SYS_read]    sys_read,
[SYS_kill]    sys_kill,
[SYS_exec]    sys_exec,
[SYS_fstat]   sys_fstat,
[SYS_chdir]   sys_chdir,
[SYS_dup]     sys_dup,
[SYS_getpid]  sys_getpid,
[SYS_sbrk]    sys_sbrk,
[SYS_sleep]   sys_sleep,
[SYS_uptime]  sys_uptime,
[SYS_open]    sys_open,
[SYS_write]   sys_write,
[SYS_mknod]   sys_mknod,
[SYS_unlink]  sys_unlink,
[SYS_link]    sys_link,
[SYS_mkdir]   sys_mkdir,
[SYS_close]   sys_close,
[SYS_trace]   sys_trace,
};
  1. syscall 函数中,先读取 trapframe->a7 获取系统调用号之后,根据系统调用号查找syscalls数组中的对应的处理函数并调用。
  2. 获取传入的参数。

你可能感兴趣的:(xv6-labs,python,开发语言)