task:
- task 保存了内核栈的地址
- Linux 给每个 task 都分配了内核栈
struct thread_info thread_info;
void *stack;
用户态函数栈
- 被调用函数栈保存了调用者的栈基址
- 以上的栈操作,都是在进程的内存空间里面进行的。
内核态函数栈
内核栈是一个非常特殊的结构,如下图所示:
- 与体系结构有关的,都放在 thread_info 里面
- 在内核中,CPU 的寄存器 ESP 或者 RSP,已经指向内核栈的栈顶,在内核态里的调用都有和用户态相似的过程。
从上面的过程来看, 如果当前是用户态的代码, 在进行各种函数调用时, 栈会不断的增长. 而切到内核态时, 并不是继续在当前栈增长, 而是跳到了另一个栈, 也就是内核栈中执行.
当系统调用从用户态到内核态的时候,首先要做的第一件事情,就是将用户态运行过程中的 CPU 上下文保存起来,其实主要就是保存在这个结构的寄存器变量里。这样当从内核系统调用返回的时候,才能让进程在刚才的地方接着运行下去。