[mit6.1810]Lab2: system calls

【写在前面】

这是2023-2024春季学期操作系统课程有关xv6 lab部分的实验报告,参考了很多网络资源,解释也不一定正确,仅作为留档,参考需谨慎。

Lab 地址:6.1810 / Fall 2023

参考:

MIT 6.S081_Zheyuan Zou的博客-CSDN博客

【露说xv6】Lab2-Basic and Optional(985男大的初学案例分享)_哔哩哔哩_bilibili

Using gdb

Q1: Looking at the backtrace output, which function called syscall?

A1: usertrap()调用了syscall

Q2: What is the value of p->trapframe->a7 and what does that value represent?

A2: p /x p->trapframe->a7 = 0x7 由此可知,在syscall.h中找到#define SYS_exec 7,在 user/initcode.S查看:xv6 启动的第一个用户程序为SYS_exec

Q3: What was the previous mode that the CPU was in?

A3: sstatus = 0x200000022,将sstatus转化为二进制表示,其中第八位为0(0表示用户态,1表示核心态),所以CPU处于用户态。

kerneltrap

Q4: Write down the assembly instruction the kernel is panicing at. Which register corresponds to the variable num?

A4:instruction: lw a3,0(zero)#0<entry-0x80000000>;register: a3

0-13

Q5: Why does the kernel crash? Hint: look at figure 3-3 in the text; is address 0 mapped in the kernel address space? Is that confirmed by the value in scause above?

A5: 访问0地址时超出列表出错;0地址不会被映射到空间;由输出scause 0x000000000000000d可知,对应RISC-V表中0/13,显示 “Load page fault" 表示加载列表出现错误,相符。

p_name_pid

Q6: What is the name of the binary that was running when the kernel paniced? What is its process id (pid)?

A6: name of the binary: initcode 000\000\000\000\000\000\000'pid = 1

System call tracing

  1. 添加一个系统调用:

    user.h中添加:int trace(int);

    usys.pl中添加:entry("trace");

    syscall.h中添加:#define SYS_trace 23

    syscall.c中添加函数声明extern uint64 sys_trace(void);和函数列表[SYS_trace] sys_trace,

  2. 加入一个表示用于进程追踪的掩码

    proc.c中新增变量声明int traceMask;用于接受参数mask。在生成proc时会调用函数allocproc,严谨地在该函数中初始化变量p->traceMask=0;

  3. 在sysproc.c的文件中真正地实现sys_trace的逻辑

    sysproc.c中添加函数定义:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    uint64
    sys_trace(void)
    {
      int flag;
      argint(0, &flag); // 将trapframe->a0读入(详细查看argraw())
      struct proc* p=myproc();
      p->traceMask=flag;
      return 0; 
    }
    
  4. 在函数fork()中添加np->traceMask = p->traceMask; 将参数复制到子进程中

  5. syscall.c中还需要加一个系统调用号到名称的映射表:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    static char* SyscallName[] = {
    [SYS_fork]    "fork",
    [SYS_exit]    "exit",
    [SYS_wait]    "wait",
    [SYS_pipe]    "pipe",
    [SYS_read]    "read",
    [SYS_kill]    "kill",
    [SYS_exec]    "exec",
    [SYS_fstat]   "fstat",
    [SYS_chdir]   "chdir",
    [SYS_dup]     "dup",
    [SYS_getpid]  "getpid",
    [SYS_sbrk]    "sbrk",
    [SYS_sleep]   "sleep",
    [SYS_uptime]  "uptime",
    [SYS_open]    "open",
    [SYS_write]   "write",
    [SYS_mknod]   "mknod",
    [SYS_unlink]  "unlink",
    [SYS_link]    "link",
    [SYS_mkdir]   "mkdir",
    [SYS_close]   "close",
    [SYS_trace]   "trace",
    };
    
  6. 测试结果

2484996991@qq.com
使用 Hugo 构建
主题 StackJimmy 设计