LKD 3rd 读书笔记——第1章/Overview of Operating System and Kernels

Overview of Operating Systems and Kernels

由于操作系统的特性不断地增长,加上某些商业操作系统的不合理设计,导致操作系统的准确概念不被世人所知。很多用户认为他们在屏幕上所看到的部分,就是操作系统。从技术的角度,在本书中,操作系统是指负责整个系统的基本操作和管理的部分。包括:内核、设备驱动程序、引导程序、命令Shell、其他用户接口以及基本的文件和系统工具。而系统则是操作系统和运行在其之上的所有应用程序:

系统 = 操作系统 + 应用程序

 

当然,本书的主题是内核。用户接口是操作系统的最外层,内核则是其最里层。内核向系统的其他部分提供基本的服务、管理硬件、分配系统资源。内核有时也被称为操作系统的监控者(supervisor)、核心(core)、或内部体(internals)。内核通常由以下部分组成:负责处理中断请求的中断处理程序、负责在多进程间分配CPU时间的进程调度器、负责管理进程地址空间的内存管理系统、以及系统服务(如网络服务和进程间通信等)。在具有内存保护模式的现代操作系统中,相比于用户程序,内核通常驻留在更高的系统状态下。这个状态包括被保护的内存空间(指用户程序无法访问这些内存)、对硬件的完全访问能力。这个系统状态和内存空间,被称为内核空间。因此,用户程序在用户空间中执行,它们只能看到机器可用资源的一个子集,只能执行特定的系统函数,直接的操纵硬件或访问不是由内核分配的内存,都是非法的行为。当执行内核代码时,系统运行在内核空间里的内核态中,当运行常规的程序时,系统运行在用户空间的用户态中。

应用程序通过系统调用(System calls)与内核进行通信(如Figure 1.1所示)。应用程序通常通过库来调用函数——例如C库——而库函数则通过系统调用接口通知内核代表用户程序去执行特定的任务。某些库函数有很多系统调用所不具有的功能,故而,触发系统调用只是某些大的库函数的其中一个步骤。例如,考虑一下熟悉的printf()函数,它提供格式化和缓存数据的功能(系统调用不具备这些功能),而它通过系统调用write()把数据写到控制台中只是函数的其中一步。相反地,有一些库函数与系统调用有一对一的关系,例如C库函数open(),只是系统调用open()的简单封装。此外,有一些库函数,例如strcpy(),则完全没有调用内核。当一个程序执行一个系统调用时,我们称之为:内核代表应用程序在执行,进一步,应用程序则被称为:正在内核空间里执行一个系统调用,这种情况我们称之为:内核运行在进程上下文中(process context)。

 

内核还负责管理系统的硬件。几乎所有硬件架构,包括所有Linux支持的架构,都有中断的概念。当硬件想与系统通信时,它向系统发送一个中断请求,这个请求先传达给CPU,然后再转交给内核。每个中断都会用一个特定的号码来标识,内核根据这个号码找到对应的中断处理程序并执行它们,以便响应这个中断请求。例如,当你敲击键盘的时候,键盘控制器发送一个中断请求让系统知道键盘缓冲区中有了新的数据,内核注意到的新来的中断请求的中断号,然后根据这个中断号执行正确的中断处理程序。中断处理程序处理掉键盘的数据,然后就通知键盘控制器它已经准备好处理更多的数据。为了提供同步操作,内核可以禁止中断,包括禁止所有中断或只是某个特定的中断。在很多操作系统中,包括Linux,中断处理程序不运行在进程上下文中,而是运行在一个特殊的中断上下文(interrupt context)中不与任何进程相关联。这个特殊的上下文是为了让中断处理程序更快的执行然后退出。

 

这些上下文反映了内核活动的范围。事实上,在Linux中,我们可以归纳出,每个处理器在任一个时间点,都处于以下三个事务(activities)之一:

1、在用户空间,在进程中执行用户代码
2、在内核空间,在进程上下文中,代表进程执行一个系统调用
3、在内核空间,在中断上下文中,不依赖于任何进程,响应一个中断

 

以上这个列表是完备的,任何边角的例子都满足这三个事务:例如,当处理器处于空闲状态(idle)时,内核就在内核空间、在进程上下文中,执行idle进程。

 

展开阅读全文

没有更多推荐了,返回首页