《操作系统课程设计》实验指导手册苏州大学计算机科学与技术学院2009年9月《操作系统课程设计》实验指导手册目录目录一、实验环境二、实验内容三、准备知识四、实验步骤实验一安装Red Hat Linux实验二编译Linux内核实验三观察Linux行为实验四系统调用一、实验环境硬件平台:普通PC机硬件环境。
操作系统:Linux环境,Red Hat Linux 9.0以上版本,启动管理器使用LILO。
编译环境:伴随着操作系统的默认gcc环境。
工作源码环境:一个调试的内核源码,版本不低于2.4.18。
二、实验内容本实验侧重于Linux操作系统的认识、应用,并对Linux内核进行初步探索。
实验分为四个部分,每个部分大约2次实验。
所有实验完成后,将在计算机上安装一个可用的Linux操作系统,并完成至少一个的可调试内核。
1.安装Red Hat Linux2.编译Linux内核3.观察Linux行为4.系统调用三、准备知识1.Linux的内核Unix操作系统家族将功能分为两类。
首先,内核执行时CPU处于管态;其次,所有其他操作系统部件执行时CPU处于用户态。
内核负责抽象与管理一台机器的硬件资源以及这些资源在执行程序之间的共享。
因为Linux实现的是一种UNIX方式的接口,资源抽象和共享模型的通用定义已经被确定了。
资源抽象(Resource abstraction)是指编写软件(通常情况)来简化必须应用于硬件的操作以使该硬件能恰当的工作。
Linux将计算机部件抽象为进程和资源。
一个进程是执行一个目标程序的CPU操作的一个抽象。
进程抽象使得操作系统能够控制一个程序中的每个实例的执行。
操作系统中的所有执行进程抽象的所有方面称为进程管理。
资源管理是创建资源抽象以及在进程执行时为它们分配和回收系统资源的过程。
RAM是一种系统资源。
另一种系统资源是CPU。
内核的其他资源包括系统的所有设备,它们具有各自的抽象模型。
UNIX 试图将除CPU和可执行内存之外的每一种资源视为一个文件。
Linux中,一个进程使用资源时,通常需要对该资源的独占使用。
资源管理有两个关键的方面:对获得资源的竞争和对独占使用的确保。
对资源的竞争由资源管理程序控制。
操作系统必须包含一个部件来负责接收使用每个资源的请求、为一个进程分配资源,以及当一个进程释放资源时进行回收。
如不能满足进程的资源请求,则阻塞该进程。
Linux和其他现代操作系统用模式位来确保对系统资源,包括CPU、内存和设备的独占使用。
模式位使系统可以工作在管态(supervisor mode)或用户态(user mode)。
在一些情况下,两个或更多进程需要共享一个资源,Linux采用有控制的共享策略。
2.内核的组织结构Linux内核被设计和实现为单内核。
硬件设备日益发展,不断包括更新的设备,完全在一个设备驱动程序中提供适当的内核支持变得日益困难。
Linux通过一个新的“容器”,称为模块(module),来解决这个问题,在模块中执行内核主要部分的扩展。
2.1 Linux的中断机制同i386体系结构中的中断机制,使用cli()和sti()两个内核函数来清除和设置中断启用标志。
2.2 使用Linux的内核服务用户将内核看作一个大的抽象数据类型(ADT),它保持状态并在其公共接口——系统调用接口上提供大量函数。
在Linux中,系统调用接口名义上由POSIX.1规范定义。
一个系统调用发生时,用户进程执行内核代码。
存在一个问题,如何由用户进程(处在用户态)切换到内核代码(处在管态)?具有模式位的CPU通常也具有硬件陷阱指令。
陷阱指令(trap instruction)是一条用于将CPU转移到一个预定地址(有时作为一个指令操作数的函数)并将其自身切换为管态的指令。
陷阱指令并不是一条特权指令,因此任何程序都可以执行一条陷阱指令。
对于系统调用F,stub过程用于调用F。
stub被链接到用户空间正调用的程序。
一个进程在运行期间执行对F的调用,控制被转换到stub过程而不是直接转换到内核。
利用陷阱指令和stub过程可以实现由用户空间向内核空间的安全转换。
2.3 串行执行Linux的内核函数执行时处在一个临界区,即,一旦进程调用一个系统函数,该函数通常要运行到结束并在CPU分配给不同的进程之前返回,但是中断除外。
这种类型的内核是单线程(single-threaded)的,因为在任何时刻(忽略ISR)在内核中只允许一个执行线程在执行。
这至少有两个重要的意义:1.一个内核函数可以更新各种内核数据结构而不用担心另一个进程会中断它的执行并改变相同的数据结构。
竞争状态不会发生。
2.在编写一个新的内核函数时,始终注意不能编写可能阻塞并等待消息或其他只有某些另外的进程才能释放的资源的代码。
这类代码可能在内核中导致死锁。
2.4 守护进程当一台Linux机器启动时,几个称作守护进程(daemon)的对用户透明的进程也被启动,并且它们的存在对操作系统的正确运行是必需的。
习惯上,守护进程是执行名字以字符―d‖结尾的程序。
通过在shell里敲入以下命令来观察哪些守护进程正在Linux机器上运行:ps aux | more典型情况下,将发现syslogd、klogd、crond和lpd在系统上运行。
2.5 引导过程一台i386计算机可以通过一张引导记录包含Linux引导程序而不是Windows操作系统引导程序的Linux引导盘来引导Linux。
对于一个分区的硬盘来说,装载处于不同分区的不同操作系统是可能的。
Windows操作系统可以通过标识一个分区为活动分区来处理多分区磁盘,系统总是从活动分区引导。
Linux提供一个可以存放在系统引导记录中的特殊Linux装载程序(LILO)使用户在引导时可以选择活动分区。
在这种情况下,LILO将会被载入到引导记录中以使BIOS在POST之后运行它。
在POST之后,引导记录已经被读取,并且装载程序已经将操作系统放入主存,引导过程开始运行内核代码以初始化计算机硬件。
计算机通过设置CPU为管态并转移到在内核中的主入口点准备启动内核。
内核初始化陷阱列表、中断处理程序、调度程序等,并初始化管理程序。
然后硬件进程创建初始进程(initial process)。
初始进程创建第一个有用的Linux 进程来运行init程序并开始执行一个空闲周期。
在内核初始化完成以后,初始进程的唯一职责就是使用空闲CPU时间。
也就是说,当没有其他进程想要使用CPU时它将占用CPU。
初始进程有时也称为空闲进程(idle process)。
2.6 登录到机器在初始化时,内核在每个可以用于支持用户登录的通信端口创建一个进程。
这些进程将运行getty程序的一个拷贝。
getty进程初始化自身后等待用户使用这个端口。
当用户开始使用该端口时,getty运行login程序,期望一个用户标识出现在第1行并且一个口令出现在第2行。
一旦端口的login程序得到了标识和口令,它通过系统的/etc/passwd文件确认用户的身份。
如果本次验证成功,那么login进程改变当前目录到用户主目录并执行指定的shell 程序以便用户通过shell直接与login进程进行交互。
一个登录到UNIX机器的用户只是使用一个在机器启动时创建的进程。
因此用户进程通过该shell数据段和堆栈段的唯一拷贝执行一个shell程序。
3.进程与资源管理进程管理程序负责创建程序员使用的进程抽象并提供措施以便一个进程可以创建、销毁、同步和保护其他进程。
类似的,资源管理程序涉及创建合适的抽象来代表一个进程可能请求的实体(并在资源不可得时阻塞它们的执行)。
除抽象外,资源管理程序必须提供一个进程用来请求、获得和释放资源的接口。
Linux内核负责处理进程调度的程序(像内核中的所有其他部分一样)只有在一个进程或者因为系统调用或者因为中断开始以管态执行时才能执行。
Linux中父进程通过fork()系统调用创建一个新的任务/进程。
当然,execve()系统调用也将极大的影响进程描述符的内容,因为这样会加载进程并执行一个与调用execve()时所执行程序不同的程序。
Linux内核还包括一个系统调用clone()来支持线程。
Linux的调度程序负责在内存中选择处于TASK_RUNNING状态的进程,为之分配CPU。
schedule()内核函数可以通过中断来调用,它也作为ret_from_sys_call代码块的一部分来调用,所以它总是作为一个与用户进程或中断相关的任务来运行。
Linux中使用两种不同的同步机制,一种在内核代码自身内部,另一种为用户进程提供同步机制。
内核中的同步主要是保证在当前内核代码处于临界部分时不会产生中断。
外部同步机制是基于事件模型。
用户可以通过以下四种方式使用内核来执行IPC:管道(和命名管道),System V IPC,System V共享内存,套接字。
保护机制有两种形式:地址空间隔离和文件保护。
4.存储管理Linux使用请求分页虚拟内存模型作为内存管理设计的基础。
在该模型中,每个进程分配其自身的虚拟地址空间。
进程引用虚拟地址,系统在访问内存地址之前将每个这种引用映射成一个主(也称为物理)内存地址。
内核和硬件一起保证了虚拟内存地址的内容被放入到物理内存,并且保证相应的虚拟地址在被进程引用时绑定到正确的物理内存。
内存管理程序履行如下一些常见职责:·以物理内存页框为单位进行块的分配和回收。
·保护机制以单页为基础。
·内存共享基于页。
·通过内存层次,在辅存和主存之间向前向后移动页面来自动控制移动。
虚拟地址空间被划分成段:3GB的用户段和1GB的内核段。
每个内核和用户段又进一步划分为代码段和数据段。
每当进程执行时,它的状态包括一个段选择器。
如果进程在用户空间执行,那么段选择器被设置为user;如果在内核段执行,则选择器被设置为kernel。
缺页处理。
当进程引用一个缺页时,存储管理程序将该页从辅存拷贝到主存中。
装入一页到内存页框中时,存储管理程序首先试图通过调用一个内部内核函数__get_free_pages()来为进程获得一块新的页框。
如果没有可用的块,页面管理程序试图释放空间。
首先是否存在可以从缓冲区中回收的块,下一步试图回收为System V共享内存保留的页框。
如果仍不能满足块请求,页面管理程序就开始通过使用近似的全局最近最少使用(LRU)替代算法查看所有分配用于容纳虚拟地址空间的用户空间部分的页框。
从物理内存中移出一个页面时,页面管理程序需要查看它是否是脏(dirty)的。
地址变换。
Linux超越当今的CPU和内存管理单元(MMU)定义了一个独立于体系结构的存储模型,因此它包含没有用于i386实现的部件。