Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1132784
  • 博文数量: 254
  • 博客积分: 1242
  • 博客等级: 少尉
  • 技术积分: 1581
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-03 21:49
文章分类

全部博文(254)

文章存档

2017年(16)

2016年(4)

2013年(94)

2012年(140)

分类:

2012-07-26 11:40:15

  内核空间和用户空间是现代操作系统的两种工作模式,内核模块运行在内核空间,而用户态应用程序运行在用户空间。它们代表不同的级别,而对系统资源具有不同的访问权限。内核模块运行在最高级别(内核态),这个级下所有的操作都受系统信任,而应用程序运行在较低级别(用户态)。在这个级别,处理器控制着对硬件的直接访问以及对内存的非授权访问。内核态和用户态有自己的内存映射,即自己的地址空间。

  系统的两种不同于行状态,才有了上下文的概念。用户空间的应用程序,如果想请求系统服务,比如操作某个物理设备,映射设备的地址到用户空间,必须通过系统调用来实现。(系统调用是操作系统提供给用户空间的接口函数)。如下图所示:

 

  通过系统调用,用户空间的应用程序就会进入内核空间,由内核代表该进程运行于内核空间,这就涉及到上下文的切换,用户空间和内核空间具有不同的地址映射,通用或专用的寄存器组,而用户空间的进程要传递很多变量、参数给内核,内核也要保存用户进程的一些寄存器、变量等,以便系统调用结束后回到用户空间继续执行,所谓的进程上下文,就是一个进程在执行的时候,CPU的所有寄存器中的值、进程的状态以及堆栈上的内容,当内核需要切换到另一个进程时,它需要保存当前进程的所有状态,即保存当前进程的进程上下文,以便再次执行该进程时,能够恢复切换时的状态,继续执行。

  同理,硬件通过触发信号,向CPU发送中断信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理,中断上下文就可以理解为硬件传递过来的这些参数和内核需要保存的一些环境,主要是被中断的进程的环境。

  Linux内核工作在进程上下文或者中断上下文。提供系统调用服务的内核代码代表发起系统调用的应用程序运行在进程上下文;另一方面,中断处理程序,异步运行在中断上下文。中断上下文和特定进程无关。

  运行在进程上下文的内核代码是可以被抢占的(Linux2.6支持抢占)。但是一个中断上下文,通常都会始终占有CPU(当然中断可以嵌套,但我们一般不这样做),不可以被打断。正因为如此,运行在中断上下文的代码就要受一些限制,不能做下面的事情:

1. 睡眠或者放弃CPU。

  由于中断上下文不属于任何进程,它与current没有任何关系(尽管此时current指向被中断的进程),所以中断上下文一旦睡眠或者放弃CPU,将无法被唤醒。所以也叫原子上下文(atomic context)。

2. 尝试获得信号量

  为了保护中断句柄临界区资源,不能使用mutexes。如果获得不到信号量,代码就会睡眠,会产生和上面相同的情况,如果必须使用锁,则使用spinlock。

3. 执行耗时的任务

  中断处理应该尽可能快,因为内核要响应大量服务和请求,中断上下文占用CPU时间太长会严重影响系统功能。在中断处理例程中执行耗时任务时,应该交由中断处理例程底半部来处理。

4. 访问用户空间的虚拟地址

  因为中断上下文是和特定进程无关的,它是内核代表硬件运行在内核空间,所以在终端上下文无法访问用户空间的虚拟地址

5. 中断处理例程不应该设置成reentrant(可被并行或递归调用的例程)。因为中断发生时,preempt和irq都被disable,直到中断返回。所以中断上下文和进程上下文不一样,中断处理例程的不同实例,是不允许在SMP上并发运行的。

6. 中断处理例程可以被更高级别的IRQ中断。如果想禁止这种中断,可以将中断处理例程定义成快速处理例程,相当于告诉CPU,该例程运行时,禁止本地CPU上所有中断请求。这直接导致的结果是,由于其他中断被延迟响应,系统性能下降。

阅读(624) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~