syscall trace finished

This commit is contained in:
2025-03-25 10:35:06 +08:00
parent d92eea9e49
commit a087b429df
5 changed files with 26 additions and 1 deletions

18
answers-syscall.txt Normal file
View File

@ -0,0 +1,18 @@
在xv6中当执行到地址 `0x3ffffff11c` 处的 `sret` 指令时,特权级和执行流程的变化如下:
1. **特权级变化**
- **执行前**核心态S模式特权级 `1`
- **执行后**用户态U模式特权级 `0`
`sret` 指令会从 `sstatus` 寄存器中恢复之前的特权级(由 `SPP` 位决定)。在进入陷阱处理时,处理器已自动将用户态的特权级(`0`)保存到 `sstatus.SPP`,因此 `sret` 会将特权级切换回用户态。
2. **恢复点地址**
恢复点地址由 `sepc` 寄存器指定。在进入陷阱处理时,`sepc` 被设置为触发 `ecall` 的下一条指令地址(即 `0x14`)。因此,`sret` 执行后,程序会跳转到 `0x14` 处继续执行用户代码。
3. **执行的函数**
`sret` 返回后,用户程序会从 `0x14` 处继续执行。根据 `initcode.S` 的代码,`0x14` 是 `ecall` 指令的下一条地址。若 `exec` 系统调用成功,用户地址空间会被替换为新程序(如 `init`),此时 `sret` 返回后直接进入新程序的入口点。若 `exec` 失败(理论上不会发生),则会继续执行 `initcode.S` 中 `ecall` 后的代码(但实际代码中 `ecall` 后无其他指令)。
**总结**
- **特权级**:核心态(`1`)→ 用户态(`0`
- **恢复点地址**`0x14`(用户代码中 `ecall` 的下一条指令)
- **执行函数**:若 `exec` 成功,执行新程序(如 `init`);否则继续 `initcode.S` 的后续代码(实际无后续指令)。

0
grade-lab-syscall Normal file → Executable file
View File

View File

@ -146,6 +146,9 @@ found:
p->context.ra = (uint64)forkret;
p->context.sp = p->kstack + PGSIZE;
// 初始化计数器
memset(p->syscall_counts, 0, sizeof(p->syscall_counts));
return p;
}

View File

@ -1,3 +1,4 @@
#include "defs.h"
// Saved registers for kernel context switches.
struct context {
uint64 ra;
@ -105,4 +106,5 @@ struct proc {
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
int syscall_counts[24]; // 每个系统调用的调用次数
};

View File

@ -147,7 +147,9 @@ syscall(void)
// and store its return value in p->trapframe->a0
p->trapframe->a0 = syscalls[num]();
if (p->tracemask & (1 << num)) {
printf("%d: syscall %s -> %d\n",p->pid, syscalls_name[num], p->trapframe->a0);
p->syscall_counts[num]++;
printf("%d: syscall %s(trace counts: %d) -> %d\n",
p->pid, syscalls_name[num], p->syscall_counts[num], p->trapframe->a0);
}
} else {
printf("%d %s: unknown sys call %d\n",