用户态/内核态、用户栈/内核栈
一、用户态和内核态
内核态和用户态是操作系统的两种运行级别,用于区分不同程序的不同权利。
内核态就是拥有资源多的状态,或者说访问资源多的状态,也称为特权态。相对来说,用户态就是非特权态,访问的而资源将受到限制。如果一个程序运行在特权态,该程序就可以访问计算机的任何资源,它的资源访问权限不受限制。如果一个程序运行在用户态,其资源需求将受到各种限制。如:要访问操作系统的内核数据结构,如进程表,则需要在特选态下才能办到。如果要访问用户程序里的数据,在用户态即可。
二、用户栈和内核栈
内核在创建进程的时候,在创建task_struct的同时,会为进程创建相应的堆栈。每一个进程都有两个栈,一个用户栈,存在于用户空间;一个内核栈,存在于内核空间。当进程在用户空间运行时,CPU堆栈指针寄存器里面的内容都是用户栈地址,使用用户栈;当进程在内核空间时,CPU堆栈指针寄存器里面的内容是内核栈空间地址,使用内核栈。
当进程因为中断或者系统调用陷入到内核态时,进程所使用的堆栈也要从用户栈转到内核栈。进程陷入到内核态后,先把用户态堆栈的地址保存在内核栈之中,然后设置堆栈指针寄存器的内容为内核栈的地址,这样就完成了用户栈向内核栈的转换;当进程从内核态恢复到用户态之后时,在内核态之后的最后将保存在内核栈里面的用户栈的地址恢复到堆栈指针寄存器即可。这样就实现了用户栈和内核栈的互转。
那么,知道从内核转到用户态时,用户栈的地址是在陷入内核的时候保存在内核栈里面的,但是在陷入内核的时候,如何知道内核栈的地址?关键在进程从用户态转到内核态的时候,进程的内核栈总是空的。这是因为当进程在用户态运行时,使用的用户栈,当进程陷入到内核态时,内核保存进程在内核态运行的相关信息,但是一旦进程返回到用户态后,内核栈中保存的信息无效,会全部恢复,因此每次进程从用户态陷入内核的时候得到的内核栈都是空的。所以在进程陷入内核的时候,直接把内核栈的栈顶地址给堆栈指针寄存器就可以了。
相关文章
- windows内核编程基础知识
- 戴文的Linux内核专题:19 配置内核 (15)
- Linux内核I/O系统报错日志与硬盘故障对应关系:
- 用户态与内核态之间切换详解
- 一个linux内核编译时遇到的perl语法导致的编译问题解决
- Linux内核部件分析 原子性操作atomic_t
- 阿里数据库内核月报:2016年05月
- 深入理解Linux网络技术内幕(三)——用户空间与内核的接口
- 内核线程与用户线程的一点小总结 《程序员的自我修养》·笔记
- 操作系统: 用户级线程和内核级线程
- 三种线程——内核线程、轻量级进程、用户线程
- 用户空间实现线程 内核实现线程 线程的调度
- ZeroMQ接口函数之 :zmq - 0MQ 轻量级消息传输内核
- 用户态线程和内核态线程的区别
- OpenHarmony的多内核
- 讲解Linux用户态和内核态通信比较好的博客
- Linux内核kfifo
- 安全吗?甲骨文企业版内核实时更新补丁
- Linux内核模块编程可以使用的内核组件