做ppt会去什么网站找图,网页制作与网站建设试题,墨猴seo排名公司,建什么网站比较好当一个任务#xff08;进程#xff09;执行系统调用而陷入内核代码中执行时#xff0c;我们就称进程处于内核运行态#xff08;或简称为内核态#xff09;。此时处理器处于特权级最高的#xff08;0级#xff09;内核代码中执行。当进程处于内核态时#xff0c;执行的内…当一个任务进程执行系统调用而陷入内核代码中执行时我们就称进程处于内核运行态或简称为内核态。此时处理器处于特权级最高的0级内核代码中执行。当进程处于内核态时执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码时则称其处于用户运行态用户态。即此时处理器在特权级最低的3级用户代码中运行。当正在执行用户程序而突然被中断程序中断时此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。这与处于内核态的进程的状态有些类似。 内核态与用户态是操作系统的两种运行级别,跟intel cpu没有必然的联系, intel cpu提供Ring0-Ring3三种级别的运行模式Ring0级别最高Ring3最低。Linux使用了Ring3级别运行用户态Ring0作为 内核态没有使用Ring1和Ring2。Ring3状态不能访问Ring0的地址空间包括代码和数据。Linux进程的4GB地址空间3G-4G部 分大家是共享的是内核态的地址空间这里存放在整个内核的代码和所有的内核模块以及内核所维护的数据。用户运行一个程序该程序所创建的进程开始是运 行在用户态的如果要执行文件操作网络数据发送等操作必须通过writesend等系统调用这些系统调用会调用内核中的代码来完成操作这时必 须切换到Ring0然后进入3GB-4GB中的内核地址空间去执行这些代码完成操作完成后切换回Ring3回到用户态。这样用户态的程序就不能 随意操作内核地址空间具有一定的安全保护作用。至于说保护模式是说通过内存页表操作等机制保证进程间的地址空间不会互相冲突一个进程的操作不会修改另一个进程的地址空间中的数据。 1. 用户态和内核态的概念区别 究竟什么是用户态什么是内核态这两个基本概念以前一直理解得不是很清楚根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上先看一个例子 1例子 void testfork(){if(0 fork()){printf(“create new process success!\n”);}printf(“testfork ok\n”);} 这段代码很简单从功能的角度来看就是实际执行了一个fork()生成一个新的进程从逻辑的角度看就是判断了如果fork()返回的是0则打印相关语句然后函数最后再打印一句表示执行完整个testfork()函数。代码的执行逻辑和功能上看就是如此简单一共四行代码从上到下一句一句执行而已完全看不出来哪里有体现出用户态和进程态的概念。 如果说前面两种是静态观察的角度看的话我们还可以从动态的角度来看这段代码即它被转换成CPU执行的指令后加载执行的过程这时这段程序就是一个动态执行的指令序列。而究竟加载了哪些代码如何加载就是和操作系统密切相关了。 2特权级 熟悉Unix/Linux系统的人都知道fork的工作实际上是以系统调用的方式完成相应功能的具体的工作是由sys_fork负责实施。其实无论是不是Unix或者Linux对于任何操作系统来说创建一个新的进程都是属于核心功能因为它要做很多底层细致地工作消耗系统的物理资源比如分配物理内存从父进程拷贝相关信息拷贝设置页目录页表等等这些显然不能随便让哪个程序就能去做于是就自然引出特权级别的概念显然最关键性的权力必须由高特权级的程序来执行这样才可以做到集中管理减少有限资源的访问和使用冲突。 特权级显然是非常有效的管理和控制程序执行的手段因此在硬件上对特权级做了很多支持就Intel x86架构的CPU来说一共有0~3四个特权级0级最高3级最低硬件上在执行每条指令时都会对指令所具有的特权级做相应的检查相关的概念有CPL、DPL和RPL这里不再过多阐述。硬件已经提供了一套特权级使用的相关机制软件自然就是好好利用的问题这属于操作系统要做的事情对于Unix/Linux来说只使用了0级特权级和3级特权级。也就是说在Unix/Linux系统中一条工作在0级特权级的指令具有了CPU能提供的最高权力而一条工作在3级特权级的指令具有CPU提供的最低或者说最基本权力。 3用户态和内核态 现在我们从特权级的调度来理解用户态和内核态就比较好理解了当程序运行在3级特权级上时就可以称之为运行在用户态因为这是最低特权级是普通的用户进程运行的特权级大部分用户直接面对的程序都是运行在用户态反之当程序运行在0级特权级上时就可以称之为运行在内核态。 虽然用户态下和内核态下工作的程序有很多差别但最重要的差别就在于特权级的不同即权力的不同。运行在用户态下的程序不能直接访问操作系统内核数据结构和程序比如上面例子中的testfork()就不能直接调用sys_fork()因为前者是工作在用户态属于用户态程序而sys_fork()是工作在内核态属于内核态程序。 当我们在系统中执行一个程序时大部分时间是运行在用户态下的在其需要操作系统帮助完成某些它没有权力和能力完成的工作时就会切换到内核态比如testfork()最初运行在用户态进程下当它调用fork()最终触发sys_fork()的执行时就切换到了内核态。 2. 用户态和内核态的转换 1用户态切换到内核态的3种方式 a. 系统调用 这是用户态进程主动要求切换到内核态的一种方式用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作比如前例中fork()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现例如Linux的int 80h中断。 b. 异常 当CPU在执行运行在用户态下的程序时发生了某些事先不可知的异常这时会触发由当前运行进程切换到处理此异常的内核相关程序中也就转到了内核态比如缺页异常。 c. 外围设备的中断 当外围设备完成用户请求的操作后会向CPU发出相应的中断信号这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序如果先前执行的指令是用户态下的程序那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成系统会切换到硬盘读写的中断处理程序中执行后续操作等。 这3种方式是系统在运行时由用户态转到内核态的最主要方式其中系统调用可以认为是用户进程主动发起的异常和外围设备中断则是被动的。 2具体的切换操作 从触发方式上看可以认为存在前述3种不同的类型但是从最终实际完成由用户态到内核态的切换操作上来说涉及的关键步骤是完全一致的没有任何区别都相当于执行了一个中断响应的过程因为系统调用实际上最终是中断机制实现的而异常和中断的处理机制基本上也是一致的关于它们的具体区别这里不再赘述。关于中断处理机制的细节和步骤这里也不做过多分析涉及到由用户态切换到内核态的步骤主要包括 [1] 从当前进程的描述符中提取其内核栈的ss0及esp0信息。 [2] 使用ss0和esp0指向的内核栈将当前进程的cs,eip,eflags,ss,esp信息保存起来这个 过程也完成了由用户栈到内核栈的切换过程同时保存了被暂停执行的程序的下一 条指令。 [3] 将先前由中断向量检索得到的中断处理程序的cs,eip信息装入相应的寄存器开始 执行中断处理程序这时就转到了内核态的程序执行了。 转载于:https://www.cnblogs.com/likui360/p/6224633.html