syscall trace finished
This commit is contained in:
18
answers-syscall.txt
Normal file
18
answers-syscall.txt
Normal 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
0
grade-lab-syscall
Normal file → Executable 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;
|
||||
}
|
||||
|
||||
|
||||
@ -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]; // 每个系统调用的调用次数
|
||||
};
|
||||
|
||||
@ -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",
|
||||
|
||||
Reference in New Issue
Block a user