转载一篇关于linux内核栈的问题
来源:互联网 发布:剑灵人族捏脸数据分享 编辑:程序博客网 时间:2024/06/04 07:38
进程的堆栈
每个进程都有自己的堆栈,内核在创建一个新的进程时,在创建进程控制块task_struct的同时,也为进程创建自己堆栈。一个进程有2个堆栈,用户堆栈和系统堆栈;用户堆栈的空间指向用户地址空间,内核堆栈的空间指向内核地址空间。当进程在用户态运行时,CPU堆栈指针寄存器指向的用户堆栈地址,使用用户堆栈,当进程运行在内核态时,CPU堆栈指针寄存器指向的是内核栈空间地址,使用的是内核栈;
进程用户栈和内核栈之间的切换
当进程由于中断或系统调用从用户态转换到内核态时,进程所使用的栈也要从用户栈切换到内核栈。系统调用实质就是通过指令产生中断,称为软中断。进程因为中断(软中断或硬件产生中断),使得CPU切换到特权工作模式,此时进程陷入内核态,进程进入内核态后,首先把用户态的堆栈地址保存在内核堆栈中,然后设置堆栈指针寄存器的地址为内核栈地址,这样就完成了用户栈向内核栈的切换。
当进程从内核态切换到用户态时,最后把保存在内核栈中的用户栈地址恢复到CPU栈指针寄存器即可,这样就完成了内核栈向用户栈的切换。
这里要理解一下内核堆栈。前面我们讲到,进程从用户态进入内核态时,需要在内核栈中保存用户栈的地址。那么进入内核态时,从哪里获得内核栈的栈指针呢?
要解决这个问题,先要理解从用户态刚切换到内核态以后,进程的内核栈总是空的。这点很好理解,当进程在用户空间运行时,使用的是用户栈;当进程在内核态运行时,内核栈中保存进程在内核态运行的相关信息,但是当进程完成了内核态的运行,重新回到用户态时,此时内核栈中保存的信息全部恢复,也就是说,进程在内核态中的代码执行完成回到用户态时,内核栈是空的。
理解了从用户态刚切换到内核态以后,进程的内核栈总是空的,那刚才这个问题就很好理解了,因为内核栈是空的,那当进程从用户态切换到内核态后,把内核栈的栈顶地址设置给CPU的栈指针寄存器就可以了。
X86 Linux内核栈定义如下(可能现在的版本有所改变,但不妨碍我们对内核栈的理解):
在/include/linux/sched.h中定义了如下一个联合结构:
union task_union {
struct task_struct task;
unsigned long stack[2408];
};
从这个结构可以看出,内核栈占8kb的内存区。实际上,进程的task_struct结构所占的内存是由内核动态分配的,更确切地说,内核根本不给task_struct分配内存,而仅仅给内核栈分配8K的内存,并把其中的一部分给task_struct使用。
这样内核栈的起始地址就是union task_union变量的地址+8K 字节的长度。例如:我们动态分配一个union task_union类型的变量如下:
unsigned char *gtaskkernelstack
gtaskkernelstack = kmalloc(sizeof(union task_union));
那么该进程每次进入内核态时,内核栈的起始地址均为:(unsigned char *)gtaskkernelstack + 8096
疑问:那么关于内核进程或线程的栈呢?应该是和普通的进程一样,放在PCB块里的,切换进程的时候直接就处理了,这点没有验证。
- 转载一篇关于linux内核栈的问题
- 转载一篇解决vmware不支持新内核linux的问题
- 转载一篇学习Linux内核的文章
- 转载的一篇关于Linux方向的材料
- 转载一篇关于linux 监视进程的文章...
- 遇到的Linux反汇编问题 & 转载一篇好文章
- 转载的关于安装Oracle时调整Linux内核参数
- 关于linux内核的几个面试问题
- 关于Linux内核的一些问题
- 【转载】linux内核移植中遇到CRC错误的问题
- 写给Linux内核新手-关于Linux内核学习的误区(转载)
- 写给Linux内核新手-关于Linux内核学习的误区(转载)
- 转载的一篇关于vld的文章
- 关于ntfs和内核问题(转载)
- (转载)关于Linux内核学习
- 转载一篇关于庄子的文章
- (转载)关于module的一篇文章
- 转载一篇关于视频水印的综述
- OJ收集
- 我必须让自己很靠谱
- 扫雷的启示
- 串的模式匹配算法 穷举与KMP
- java Thread编程(一)如何创建线程
- 转载一篇关于linux内核栈的问题
- ADO.NET连接SQL Server数据库
- EFM32片内外设--LETimer One-short Mode
- 检测题3.1
- 完全卸载xcode的命令
- zoj 2176 Speed Limit
- 360需要的,不是打工者
- logSvr的日志打印函数
- ruby on Rails:动作视图纵览