MIT6.s081-lab-syscall
Using gdb
如果不知道怎么运行gdb的,要先看提供的文档
1.首先在终端1中运行make qemu-gdb,结尾处会得到一个端口号,供终端2使用

2.新起一个终端,运行riscv64-unknown-elf-gdb,会进入如下所示的界面

3.输入target remote localhost: 25501,然后再输入file kernel/kernel,就可以跟着指示往下做了

问题1:Looking at the backtrace output, which function called
syscall?usertrap()

问题2:What is the value of
p->trapframe->a7and what does that value represent?
从initcode.S文件中看到a7保存的是要执行的系统调用号,从syscall.h中看到7是SYS_exec
7和exec的系统调用号

问题3:What was the previous mode that the CPU was in?
通过输入p /x $sstatus,得到0x200000022,通过查询相关文档得到之前的特权级别是user mode,其中的8这个位置SPP就表示源自什么模式(0表示用户模式)。

用户模式
问题4:Write down the assembly instruction the kernel is panicing at. Which register corresponds to the variable
num?
跟着作业的指示走,在kernel.asm文件中搜索地址可以看到:

在lw a3,0(zero)处panic,存在寄存器a3中
问题5: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
scauseabove?内核因为加载了一个未使用的地址 0 处的内存数据而崩溃(Load page fault)。地址 0 并不映射到内核空间中(从
0x80000000开始)。问题6:What is the name of the binary that was running when the kernel paniced? What is its process id (
pid)?这个二进制的名字为
initcode,其 process id 为 1.
System call tracing
建议先读几遍作业文档,这两个作业需要实现的逻辑不难,但是这个流程稍微多了些
- 首先在
Makefile中添加$U/_trace\

- 然后在
user.h文件中注册对应的函数

- 在
usys.pl文件中也添加对应的入口

- 在
syscall.h文件中添加对应的系统调用号

- 在
sysproc.c文件中实现sys_trace函数,从用户态获取到用户输入的mask,然后赋值给进程的syscall_trace成员,该成员需要在proc.h文件中的proc结构体添加


- 在
proc.c文件中修改fork函数,在父进程创建子进程的时候将该值复制过去,如下

- 最后修改
syscall.c文件中的syscall函数,在进行系统调用的时候根据mask打印相应的信息

Sysinfo
该实验流程跟前面的差不多,这里主要描述一下freemem和nproc怎么计算得到的,根据课程的作业提示我们在kalloc.c文件中创建一个count_freeMem用来返回空闲的内存字节数,至于为什么是这么计算,因为可以看出来xv6系统使用的是空闲链表法来分配内存的
1 | // 返回空闲内存的字节数=空闲页数*每页字节数 |
并且在proc.c文件中创建一个count_process用来返回不是UNUSED状态的进程数量
1 | // 返回已经分配的进程数 |
这两个函数也都很直观,应该是没什么难度,最后跑一下make grade看看得分吧~
