进程内存布局
理解这一张图是理解 xv6 的关键。
用户虚拟地址空间 (User Virtual Address Space)
从 0 开始向上生长:
- Text (Code): 代码段。
- Data: 全局变量。
- Stack: 用户栈。动态生长。
- Heap: 堆。通过
sbrk()系统调用向上生长。 - Trampoline & Trapframe: 在极高地址处(虚拟地址顶部),映射了用于处理中断跳板代码。这部分对用户是不可读写的(PTE_U 位未置位),但必须在页表里。
两个栈 (The Two Stacks)
这是初学者最容易晕的地方:一个进程有两个栈。
- 用户栈 (User Stack): 当你在用户态执行
call function时用。 - 内核栈 (Kernel Stack): 当你执行
syscall陷入内核后,CPU 的sp寄存器会切换指向这里。内核代码(如sys_open)的局部变量存在这里。
隔离性: 用户程序无法直接访问内核栈。如果用户栈爆了,只是程序崩;如果内核栈爆了,OS 崩。