进程的内核栈
来源:互联网 发布:mac给iphone充电 编辑:程序博客网 时间:2024/06/05 21:50
1.进程的堆栈
内核在创建进程的时候,在创建task_struct的同事,会为进程创建相应的堆栈。每个进程会有两个栈,一个用户栈,存在于用户空间,一个内核栈,存在于内核空间。当进程在用户空间运行时,cpu堆栈指针寄存器里面的内容是用户堆栈地址,使用用户栈;当进程在内核空间时,cpu堆栈指针寄存器里面的内容是内核栈空间地址,使用内核栈。
2.进程用户栈和内核栈的切换
当进程因为中断或者系统调用而陷入内核态之行时,进程所使用的堆栈也要从用户栈转到内核栈。
进程陷入内核态后,先把用户态堆栈的地址保存在内核栈之中,然后设置堆栈指针寄存器的内容为内核栈的地址,这样就完成了用户栈向内核栈的转换;当进程从内核态恢复到用户态之行时,在内核态之行的最后将保存在内核栈里面的用户栈的地址恢复到堆栈指针寄存器即可。这样就实现了内核栈和用户栈的互转。
那么,我们知道从内核转到用户态时用户栈的地址是在陷入内核的时候保存在内核栈里面的,但是在陷入内核的时候,我们是如何知道内核栈的地址的呢?
关键在进程从用户态转到内核态的时候,进程的内核栈总是空的。这是因为,当进程在用户态运行时,使用的是用户栈,当进程陷入到内核态时,内核栈保存进程在内核态运行的相关信心,但是一旦进程返回到用户态后,内核栈中保存的信息无效,会全部恢复,因此每次进程从用户态陷入内核的时候得到的内核栈都是空的。所以在进程陷入内核的时候,直接把内核栈的栈顶地址给堆栈指针寄存器就可以了。
3.内核栈的实现
内核栈在kernel-2.6里面的实现是(kernel-2.6.32):
Union thread_union {
Struct thread_info thread_info;
Unsigned long stack[THREAD_SIZE/sizeof(long)];
};
其中THREAD_SIZE的大小可以是4K,也可以是8K,thread_info占52bytes。
当内核栈为8K时,Thread_info在这块内存的起始地址,内核栈从堆栈末端向下增长。所以此时,kernel-2.6中的current宏是需要更改的。要通过thread_info结构体中的task_struct域来获得于thread_info相关联的task。更详细的参考相应的current宏的实现。
struct thread_info {
struct task_struct *task;
struct exec_domain *exec_domain;
__u32 flags;
__u32 status;
__u32 cpu;
… ..
};
注意:此时的task_struct结构体已经不在内核栈空间里面了。
- 进程的内核栈
- 进程的用户栈和内核栈
- 进程的内核栈和用户栈
- 进程的用户栈和内核栈
- 进程的用户栈和内核栈
- 进程的用户栈和内核栈
- 进程的用户栈和内核栈
- 进程的用户栈和内核栈
- 进程的用户栈和内核栈
- 进程的用户栈和内核栈
- 进程的用户栈和内核栈
- 进程的内核栈和用户栈
- 进程的用户栈和内核栈
- 进程的用户栈和内核栈
- 进程的用户栈和内核栈
- 内核进程的堆栈
- 内核进程的复制
- 内核进程的堆栈
- 中国手游IP年 开发者的机遇和挑战
- scrollTo、scrollBy、getScrollX、getScrollY
- Android UI自适应屏幕大小
- Java自学视频整理
- [LeetCode-12]Validate Binary Search Tree
- 进程的内核栈
- ultraedit 正则表达式
- [LeetCode-15]Binary Tree Zigzag Level Order Traversal
- MOS管的导通特性
- Pomelo在windows下环境搭建遇到的问题
- html标签中id和name的区别
- 《C++ Primer第四版》学习笔记(三)变量和基本类型 之 基本内置类型
- Sneak Preview: The 14 Leading Java Tools & Technologies for 2014
- AlertDialog,当点击按钮时,能够根据界面上输入的数据,弹出对话框,显示界面中输入的相关信息