第一章 绪论
操作系统的基本概念
任何计算机系统都包含一个名为操作系统的而基本程序集合,在这个集合里,最重要的程序称为内核。当操作系统启动时,内核被装入到RAM中,内核中包含了系统运行所必不可少的很多核心过程。
操作系统必须完成两个主要目标:
- 与硬件部分交互,为包含在硬件平台上的所有底层可编程不见提供服务
- 为运行在计算机系统上的应用程序(即所谓用户程序)提供执行环境
类Unix操作系统把与计算机物理组织相关的所有底层细节都对用户运行的程序隐藏起来,当程序想使用硬件资源时,必须向操作系统发出一个请求。内核会对这个请求进行评估,如果允许使用这个资源,则内核代码应用程序与相关的硬件部分进行交互。
但是Linux是通过什么机制实现这种机制的呢?
硬件为CPU引入了至少两种不同的执行模式:
- 用户程序的非特权模式(用户态)
- 内核的特权模式(内核态)
多用户系统
多用户系统就是一台能并发和独立地执行分别属于两个或多个用户的若干应用程序的计算机。
多用户操作系统必须包含以下几个特点:
- 核实用户身份的认证机制
- 防止有错误的用户程序妨碍其他应用程序在系统中运行的保护机制
- 防止有恶意的用户程序干涉或监视其他用户的活动的保护机制
- 限制分配给每个用户的资源数的记账机制
用户和组
在多用户系统中,每个用户在机器上都有私用空间。
操作系统必须保证用户空间的私有部分仅仅对其拥有者是可见的。
有的用户由一个唯一的数字来标识,这个数字叫用户标识符(User ID, UID)。
为了和其他用户有选择地共享资料,每个用户是一个或多个用户组的一名成员,组由唯一的用户组标识符标识。每个文件也恰好与一个组相对应。
任何一个类Unix操作系统都有一个特殊的用户,叫做root,即超级用户。root用户几乎无所不能,因为操作系统对它不使用通常的保护机制。
进程
进程被定义为:“程序执行时的一个实例”或者一个运行程序的“执行上下文”。
传统操作系统:
进程在地址空间汇中执行一个单独的指令序列。地址空间时允许进程应用的内存地址集合。
现代操作系统:
允许具有多个执行流的进程,也就是说,在相同的地址空间可执行多个指令序列。
在单处理器系统上只有一个进程能占用CPU,所以在某一个时刻只能有一个执行流。而操作系统中叫做调度程序的部分决定哪个进程能执行。一些操作系统只允许有非抢占式进程,所以只有当进程自愿放弃CPU时,调度程序才被调用。
多用户系统中的进程必须是抢占式的,操作系统记录下每个进程占有的CPU时间,并周期性地激活调度程序。
内核体系结构
大部分的类Unix内核时单块结构:
每一个内核层都被集成到整个内核程序中,并代表当前进程在内核态下运行。
这里花点儿时间介绍下微内核:
微内核操作系统只需要内核有一个很小的函数集,通常包括几个同步原语、一个简单的调度程序和进程间通信机制。
运行在微内核之上的几个系统进程实现从前操作系统级实现的功能,如内存分配程序、设备驱动程序、系统调用处理程序等等。
缺点:
- 效率较低:
由于存在操作系统不同层次之间显式消息传递要花费一定的代价,所以微内核一般比单块内核运行效率稍低
优点:
- 促使开发者进行模块化编程
因为任何操作系统层都是一个相对独立的程序,这个程序必须通过定义明确而清晰的软件接口与其他层进行交互 - 易移植性
因为所有与硬件相关的部分都被封装进微内核代码中了 - RAM利用率高
因为操作系统可以将暂且不需要执行的进程调出或者撤销。
为了达到微内核理论上的很多优点而又不影响性能,Linux内核提供了模块。模块是一个目标文件,其代码可以在运行时链接到内核或从内核解除链接。
对于Linux使用的模块而言,主要有以下几个优点:- 模块化方法
系统开发者必须提出优良定义的软件接口以访问由模块处理的数据结构,因为任何模块都可以在运行时被链接或解除链接。 - 平台无关性
即使模块依赖于某些特殊的硬件特点,但它不依赖与某个固定的硬件平台。 - 节省内存使用
当需要模块功能时,把它链接到正在运行内核中,否则,将该模块解除链接。这种机制对于小型嵌入式系统是非常有用的。 - 无性能损失
模块的目标代码一旦被链接到内核,其作用与静态链接的内核目标代码完全等价。因此,当模块的函数被调用时,无需显式地进行消息传递。
- 模块化方法
Unix文件系统概述
文件系统有以下几个特点:
文件
Unix文件是以字节序列组成的信息载体,内核不解释文件的内容。从用户的观点来看,文件被组织在一个树结构的命名空间中。现在在脑中想象一个树形结构,除了叶节点外,树的所有节点都表示目录名。
Unix的每个进程都有一个当前工作目录,它属于进程执行上下文,标识出进程所用的当前目录。