




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Minix进程实现2.52.6概述:本部分内容主要从两个部分介绍进程在Minix中的实现的:第一部分是介绍整个Minix的系统结构的,其中包括了Minix的内部结构以及各种头文件,其主要是对于各个头文件以及进程有关的数据结构的介绍的;第二部分讲的是Minix中进程的实现,其中包括Minix的系统初始化、中断处理、进程间的通信和进程调度。Minix系统结构介绍:包括Minix内部结构以及各种头文件。Minix内部四层结构最底层捕获所有的中断和陷入,完成进程调度,并向高层提供一个采用消息进行通信的独立顺序进程模型。包含完成以下功能的函数:系统初始化、中断、消息传递以及进程调度。第二层包括了I/O进程,每类设备都有一个I/O进程,我们称之为任务(task)。只有一个任务,即系统任务与众不同,它不对应于任何I/O设备。第三层包含向用户进程提供有用服务的进程。这些服务器进程在低于内核和任务的特权级上运行,不能直接访问I/O端口,也不能访问属于自己段以外的内存。第四层包含了所有的用户进程shell、编译器、编辑器以及用户的a.out 程序。Minix四层结构之间的联系:操作系统主要完成的两件事情:管理资源和通过系统调用方式提供扩展的计算机。其中,资源管理主要是在内核(第一、二层)完成的,系统调用的解释在第三层。第三层的各种服务进程被单独的设计成“服务器”,这样可以增加整个系统的可扩展性。如果要是加入一个新的服务器进程,需要重新编译内核。Minix源代码的组织源代码从逻辑上分成两个目录:/usr/include/和/usr/src/,记做:include/和/src/。include/目录包含了许多符合POSIX标准的头文件,它又包含了三个子目录:1. sys/包含POSIX头文件2. minix/包含操作系统使用的头文件3. ibm/包含IBMPC特有定义的头文件。src/目录包含了三个重要的子目录,其中包括了操作系统的源代码1. kernel/第一层和第二层的(进程、消息和驱动程序)2. mm/内存管理器代码3. fs/文件系统代码公共头文件其中,编译用户程序时可能用到的头文件放在include/目录下,而传统上include/sys/目录放那些编译系统程序和程序所用的头文件。include/目录:主控头文件src/kernel/kernel.h、src/mm/mm.h以及src/fs/fs.h分别对应于MINIX的三个主要部分,而这三个部分必定包含在MINIX的每一个编译版本中。1. include/ansi.h:这是编译MINIX系统任何一部分都要处理的第二个文件。其作用是测试编译器是否符合ISO规定的标准C的要求。其中重要的一个宏是_PROTOTYPE。2. include/limits.h:间接包含在每一个MINIX源文件中的头文件。定义了许多基本的大小值。3. include/errno.h:被所有的主控头文件包含。它包含了系统调用失败时从全局变量errno返回给用户程序的错误码。同时,errno也用来标识一些内部错误。4. include/unistd.h、include/string.h、include/signal.h:没有包含在每一个主控头文件中,但是在MINIX三个部分的许多源文件中使用。unistd.h定义了许多常量,其中多数是POSIX需要的,也包含了许多函数原型,其中包括了所有用于进行系统调用的C函数原型;string.h包含了许多用于串操作的C函数原型;signal.h定义了标准信号名,同时包含一些与信号相关的函数原型。5. include/fcntl.h:采用符号方式定义了文件控制操作使用的许多参数。6. include/stdlib.h:定义了大多数C程序(除最简单的以外)编译时要用到的类型、宏和函数原型。它是编译用户程序时使用最频繁的头文件之一。7. include/termios.h:定义了控制终端类型的I/O设备所用到的常量、宏和函数原型。最重要的数据结构是termios。8. include/a.out.h:定义了可执行文件在磁盘上的存储格式,包括启动文件执行的文件头结构和编译产生的符号表。只有文件系统引用。include/sys/目录1. sys/types.h:定义了许多MINIX使用的数据类型。使用这里提供的定义可以避免对特定情况下所使用的基本数据结构的理解错误而导致的故障。2. sys/ioctl.h:没有被主控头文件包含,其中还是定义了许多用于设备控制的宏。在这里需要注意的是include/termios.h和ioctl.h之间的区别和联系。3. sys/sigcontext.h:定义了一些结构,这些结构用来在信号处理例程执行前后保存和恢复正常的系统操作。该文件用于内核和内存管理器。4. sys/ptrace.h:定义了使用PTRACE系统调用的各种可能操作。5. sys/stat.h:定义了我们在图1.12中看到的结构,它由STAT和FSTAT系统调用返回。同时定义了stat、fstat以及其他一些用来对文件进行操作的函数原型。在文件系统和内存管理器中有几处引用该文件。6. sys/dir.h:定义了MINIX的目录项结构。它定义了一个文件名最长有多少个字符。7. sys/wait.h:定义了WAIT和WAITPID系统调用所使用的宏。它们本身在内存管理器中实现。Minix头文件include/minix和include/ibm/目录包含了MINIX特有的头文件。Include/minix/中的文件对任何平台上的MINIX实现都是需要的(尽管其中一些文件里有与平台相关的替代定义)。include/ibm/中定义了IBM类型机器上的MINIX实现所特有的数据结构和宏。minix/目录:1. include/minix/config.h:这是编译MINIX系统任何一部分都要处理的第一个文件。在许多情况下,当因硬件差异或对操作系统的使用方式不同而需要对MINIX的配置进行修改时,只需要编辑该文件并对系统重新编译即可。用户可以设置的参数放在该文件的第一部分。2. include/minix/const.h:在这里定义了一些常量,可以防止发生变量在多处定义不一致的错误。注意。在内核中使用的定义包含在src/kernel/const.h中,内存管理器将src/mm/const.h用于其局部定义。只有那种在MINIX系统一个以上部分中用到的定义放在include/minix/const.h中。3. include/minix/type.h:是另一个通过主控头文件被包含在每一个编译版本中的文件。它包括了许多重要的类型定义,以及相关的数量值。该文件中最重要的定义是message(31353146)。4. include/minix/syslib.h:包含了在操作系统内部调用以访问操作系统其他访问的C库函数原型。其中引用的C函数显然是特定于MINIX的,并且,当MINIX移植到一个带有不同编译器的新系统将需要移植这些库函数。5. include/minix/callnr.h:当一个进程需要执行一条MINIX系统调用时,它向内存管理器或文件系统发送一条消息。每条消息中含有所要求的系统调用序号。这些序号就在这个文件中定义。6. include/minix/com.h:包含从MM和FS发送到I/O任务的消息中所使用的公共定义,其中也定义了任务序号。为了和进程分开,任务号是负数。还定义了可被发送到每个系统任务的消息类型(函数代码)。7. include/minix/boot.h:被内核和文件系统用来定义设备,以及访问从boot程序传入系统的参数。8. include/minix/keymap.h:定义了若干结构,这些结构用来实现不同语言所需的字符集对应的特殊键盘不就。它也被那些生成和加载这些表格的程序使用9. include/minix/partition.h:只被内核使用,而不被文件系统或内存管理器使用。此处要注意为什么这个头文件放在了include/目录树下,没有放在src/kernel/下。include/ibm/目录:1. include/ibm/diskparm.h:被软盘系统任务使用。2. include/ibm/partition.h:定义了IBM兼容机上使用的硬盘分区表和相关的常量。有助于将MINIX移植到其他系统平台上。进程数据结构和头文件在这里,主要是要看src/kernel/下的代码。1. src/kernel/kernel.h:它一开始定义了三个宏。宏_POSIX_SOURCE是POSIX标准自行定义的特征检测宏;宏_MINIX将为MINIX所定义的扩展而重载_POSIX_SOURCE的效果;而在编译系统代码时,如果要做与用户代码不同的事情,则可以对_SYSTEM宏进行检测。而后包含了include/及其子目录include/sys/和include/minix/下的其他头文件,最后包含了本地目录下的四个头文件2. src/kernel/const.h:包含许多机器相关的值,这些值用于Intel的CPU芯片,但在别的硬件上编译时则可能不同。其中一些是与机器相关的,例如重要的中断向量和用在每次中断后复位中断控制器芯片的一些域的值。其他的定义是与机器无关的,但它们被内核代码的许多部分用到。最后的printf被定义成一个宏。3. src/kernel/type.h:定义了所有MINIX实现都要用到的几个原型和结构,tasktab结构和memory结构。(此处要注意为什么要是用vir_clicks)。还包含了几个机器相关的类型定义、数据结构定义(stackframe_s结构,定义了如何将寄存器值保存到堆栈上,在进程被投入运行态或被脱开运行态时非常重要,用来保存和恢复CPU的内部状态)4. src/kernel/proto.h:包括的都是必须能在其定义文件之外使用的函数的原型。它们都使用了前一节提到的_PROTOTYPE宏。5. src/kernel/glo.h:其中包含了内核的全局变量。其中要注意的是EXTERN的使用、held_head、held_tail、proc_ptr、sig_procs、extern的使用6. src/kernel/proc.h:将一个进程表项定义为一个结构proc,将进程表本身定义为proc结构的数组。其中各个变量的含义和作用需要特别注意。7. src/kernel/protect.h:该文件中几乎所有的内容都与支持保护模式的Intel处理器体系结构细节有关。8. src/kernel/sconst.h:它包含了汇编代码所使用的常量。这些常量是相对进程表项中stackframe_s部分的偏移。9. src/kernel/assert.h:可以用来进行运行时测试。10. src/kernel/table.c:其编译生成的目标文件将包含所有的内核数据结构。11. src/kernel/mpx.s:分配全局空间。Minix进程的实现一个进程投入运行的方式如下:通过将其进程表项的地址装入其堆栈指针,然后从该结构中弹出全部的CPU寄存器值。当发送消息进程由于目标进程未处在等待状态而无法完成一个SEND操作时,它被送到一个队列中,这个队列由目标进程的一个p_callerq域指向。于是当目标进程最终执行RECEIVE操作时,它很容易找到等待向其发送消息的所有进程,p_sendlink用于将队列中的成员链接起来。当一个进程执行RECEIVE时,如果没有任何消息在等待它接收,那么该进程将阻塞,同时将它期望接收消息的源进程序号保存在p_getfrom中。消息缓冲区的地址保存在p_messbuf中。每一个进程表项的最后三个域是p_nextready,用于将进程链接在调度程序队列中;p_pending是一个位图,用于记录那些尚未被传到内存管理器的信号(因为内存管理器没有在等待一条消息);p_pendcount是这些信号的计数值。引导Minix将MINIX引导扇区写入硬盘时,要对它进行修改,修改的内容是将添加一个扇区号以便在其分区或子分区中找到boot程序。该添加操作以及向硬盘写引导扇区的操作由一个特殊的程序installboot完成。boot是MINIX的次级装入程序,它不仅可以装入操作系统,而且作为一个监控程序,它允许用户改变、设置和保存不同的参数。Boot不是操作系统的一部分,但它可以使用文件系统的数据结构来找到操作系统映象。被boot装入的MINIX映象是这样的:先对内核、内存管理器、文件系统和init程序分别进行编译,然后将所产生的各个文件链接而成。系统初始化MINIX执行代码的第一部分是用汇编语言写的,并且针对16位或32位编译器必须使用不同的源文件。初始化代码的32位版本位于文件mpx386.s中,对应的16位系统则位于mpx88.s中。MINIX的启动牵涉到几次控制权的转移,它们发生在mpx386.s中的汇编语言例程和start.c及main.c中的C语言例程之间。引导进程将操作系统装入内存后,控制权便跳转到标号MINIX(6051)1. 一个跳转指令,跳过几个字节2. 建立一个堆栈框架以便为C编译器编译的代码提供适当的环境3. 复制处理器所使用的表格来定义存储器段4. 建立各种处理器寄存器。5. 调用cstart(6109)继续运行。cstart调用另一个例程初始化全局描述符表以及中断描述符表。6. 从cstart返回之后,向寻址寄存器中装入一些值来激活相应表格。7. 跳转指令强制使用刚刚被激活的结构。8. 跳入内核的main入口点(6131)cstart进行的操作(6521)1. 调用prot_init来建立CPU的保护机制和中断表2. 将引导参数复制到内存的内核部分并将其转换成数值。3. 确定显示器的型号、内存大小、机器类型、处理器操作模式(实模式还是保护模式),以及是否可能返回到引导监控程序。main函数(6721):完成初始化,然后开始系统的正常运行。1. 调用intr_init配置中断控制硬件(8259,其代码见7621)。该调用重的参数1指示这是在为MINIX进行初始化,如果使用0则指示为再次初始化硬件,使其回到原始状态。2. 调用mem_init,初始化一个数组,该数组定义了系统中每个可用内存块的地址和大小。3. 进程表的所有表项都被标志为空闲,代码的6745至6749行初始化了pproc_addr数组4. 一个循环,对进程表初始化,使其拥有足够的信息来运行系统任务、服务器进程和init。这些进程在启动时必须存在,而且在整个正常操作过程中任何一个都不会结束。rp赋值为一个进程表项的地址,填写进程表中的各项。由于任务被编译进内核,因此每个任务的空间大小域都填入内核本身的长度。进程则是根据size数组中的值进行填写。保证高端内存的使用被记录在进程表中。所有其他进程被放置在适当的队列中。(这里要注意两个不同的进程。一个是IDLE,一个是HARDWARE,注意它们的作用。)调用alloc_segments将各进程使用的内存段的位置、大小及运行特权级设置到适当的域中。5. 选择下一个可执行的程序。lock_pick_proc6. 调用restart,启动第一个任务,控制权从此不再回到main。intr_init函数(7621): 1. 向每个中断控制器芯片中写入一个字节,以使其无法响应外部中断2. 用来访问设备相关的中断处理程序的表格中所有表项都填入一个例程的地址,该例程在收到一个伪中断时将打印出一条信息。其后在每个I/O任务运行自己的初始化代码时,这些表项被逐个重填以指向相应的中断处理例程。3. 每个系统任务复位中断控制器芯片中的一个二进制位以激活自己的中断信号输入。restart函数(6322):是在mpx386.s中的一个汇编语言例程。它是一个更大的过程的中间入口。在这里,restart只是进行上下文切换,这样就将运行proc_ptr指向的进程。第一个排队的任务,总是控制台任务,它一直运行到因试图接收一条消息而阻塞;然后运行下一个系统任务,一直到它因同样的原因阻塞;所有的任务都将被阻塞,这样内存管理器和文件系统便可以运行,它们也同样被阻塞;最后init为每个终端创建一个getty进程,这些进程一直阻塞,直到终端有键入的输入。另外,在main.c中,还有一个过程panic,是当系统发现无法继续运行下去的故障时将调用它。 Minix的中断处理在Minix系统主要包括两种中断。一种是由硬件引起的中断,称之为硬中断;一种是由系统调用引起的中断,称之为软中断。对于这两种中断的处理过程需要进行的操作,见教材图2.34。 32位Intel处理器响应中断时的任务切换机制很复杂,改变程序计数器以执行另一个函数只是其中很少的一部分。我们以下面的流程图来简单看看这个处理过程。 对硬件中断的处理由硬件设备产生的中断是一些电信号,它们首先由中断控制器进行处理,被中断控制器检测,并在处理器的数据总线上被转换成唯一的数据格式。当硬件中断发生时,中断信号出现在IRQn信号线上,连到CPU INT管脚的连接线通知CPU发生了中断,从CPU发出的INTA信号使负责中断的控制器芯片将数据放在系统数据总线上,并通知处理器应执行哪个服务例程。 在系初始化期间,对中断控制器进行编程。这种编程内容决定了对应于各条输入线的信号将向CPU送出什么样的数据,也决定了中断控制器操作所用的其他参数。 在MINIX的中断处理中,应当注意中断门描述符这样一个数据结构。每个中断门描述符是一个含有若干域的8字节的结构。其中最重要的一个域指向服务例程可执行代码段和其中的起始地址。中断响应时,CPU执行被选中的描述符所指向的代码。其结果与执行汇编语言指令int 完全相同。 MINIX内核中只有很小一部分能够感知到硬件中断。其中每个中断都有一个入口。从_hwint00到_hwint07(6164到6193行),调用hwint_master宏(6143);从_hwint08到_hwint15(6222到6251)调用hwint_slave宏(6199)。 Hwint_master:1、 调用save(6144),该子例程将以后重启动被中断进程所需要的所有其他寄存器值入栈。2、 操作中断控制器,以防止从产生当前中断的中断源接收到另一个中断(61456147)。主要是屏蔽了中断控制器对某一特定输入的响应能力。3、 将中断控制器复位,然后使CPU再次能够从其他中断源接收中断(6148至6150)。4、 使用当前正被服务的中断编号来对一张与设备相关的低层例程地址表进行索引。5、 从设备相关代码返回时,处理器响应全部中断的能力再次被屏蔽(6154)。6、 中断再次被打开(6157到6159)时,对激发当前中断的设备做出响应。7、 以ret指令结束(6160)在这一部分,要注意的是书中提到的“多进程并发执行机制的中心内容”这一部分以及如何实现的中断嵌套。 Hwint_slave:和Hwint_master基本相似,一些细微的差别请参照教材相关内容。 save函数: 它主要是围绕堆栈进行操作。将一个中断进程的上下文保存在CPU提供的堆栈上,该堆栈是进程表中的一个stackframe结构。 1、用变量_k_rernter来计算和确定中断的嵌套级数。2、如果当前中断发生时,一个进程正在运行,则切换到内核栈,随后将_restart的地址压栈(6275)。否则,内核栈已在使用中,则将restart1(6128)的地址压栈。3、两个结束save的出口点(6277和6282),使用调用save时压进栈的地址。 对软中断的处理_s_call时中断处理机制在系统调用中的对应物。在一软件中断,即执行一条int nnn的指令后,控制权转交给_s_call。不同之处在于用int nnn指令中的nnn作为对中断描述符表的索引,而不是中断控制芯片提供的一个数字。这样,进入_s_call时,CPU已经切换到了进程表(由TSS提供)中的栈,并且几个寄存器的值已经被压入该栈。而且,和硬中断一样,该指令将启动proc_ptr此时指向的进程。 _s_call 还有一个名字叫做_p_s_call。1、 和save中的一样,开始将其余必须保存的寄存器值保存下来。2、 切换到内核栈,同时重新开中断3、 调用_sys_call(构造一条消息,并且发送,将进一步引发调度程序运行),其返回时,proc_ptr有可能指向了引发本系统调用的进程之外的另一个进程。4、 关中断以保护即将再次启动的进程的stackframe结构。 异常除了硬件和软件中断之外,CPU内部的各种错误条件可能激发异常。尽管标准的MINIX并未实现这些服务,但是异常发生时不应将其忽略。异常采用和中断相同的处理机制,使用中断描述符表中的描述符。表中的表项指向16个异常处理入口(6350到6412行)。根据是否将一个错误码压栈,这些入口分别跳到exception(6420)和errexception(6431)。还有另外的一个入口点像中断处理一样,即_level0_call(6458)。它被int指令调用。和异常处理例程一样,它也调用save,最终以ret指令结束,而这条ret指令将发展到调用_restart。 MINIX的进程间通信MINIX中的进程使用消息进行通信,这里使用到进程会合的原理。 当一个进程执SEND时,内核的最低层检查目标进程是否在等待从发送者(或任一发送者)送来的消息。如果是,则该消息从发送者的缓冲区复制到接受者的缓冲区,同时,这两个进程都被标记为就绪态。如果目标进程没有在等待消息,则发送者被标记为阻塞,并被挂入一个等待将消息发送到接收进程的进程队列中。 当一个进程RECEIVE时,内核检查该队列中是否存在向它发送消息的进程。若有,则消息从被阻塞的进程复制到接收进程,并将两者均标记为就绪;若不存在这样的进程,则接收进程被阻塞,知道一条消息到达。 进程间通信的高层代码在proc.c中。内核的任务是将一个硬件中断或软件中断转换为一条消息,前者有硬件产生,后者则是请求系统服务的途径。这两者很类似,可以用同一个函数处理,但将其分为两个专门的函数会更高效。 下表列出了几个主要的函数及其功能描述:功能参数操作步骤Interrupt(6938)将中断转换成向该设备所对应的系统任务发送一条消息1、 通过变量k_reenter(6962)检查在接收当前中断时是否已经有过一个中断正在被处理。如果是,则将当前中断排队,同时interrupt返回。当前中断在以后调用unhold时被处理。2、 检查该任务是否在等待一个中断(69786981)。如果任务未做好接收中断的准备,则其p_int_blockd标志被置位,不发送消息。如果通过这个测试,则消息被发送:在目标任务的消息缓冲区的源和类型域中填入内容,将目标进程的RECEIVE标志复位并将该任务解除阻塞。Sy_call将软件中断转换为一个消息 1 调用isoksrc_des。检查并保证该消息制定的源进程和目标进程合法2 如果需要发送消息,调用mini_send(7031)。3 如果需要接收消息,调用mini_rec(7039)。Mini_send发送消息调用进程、目标进程、指向消息所在缓冲区的指针1、 确认用户进程只能向文件系统或内存管理器发送消息。有两个宏来分别完成对调用进程和目标进程的检测。2、 确认消息的目标进程是一个活动进程。如果不是,则返回错误3、 对一个可能发生的死锁进行测试。4、 测试目标进程是否正阻塞在RECEIVE上。如果是,则接着问“它在等谁?”如果正在等待这一消息的发送者或任一进程,则执行CopyMess来复制消息,然后将接收者的RECEIVE复位使其解除阻塞。如果接受者没有阻塞或者在等待其他进程的消息,则阻
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 新解读《HG-T 2033-1999工业乙酸锑》新解读
- 新解读《CB-T 3918-1999船用水幕喷头》新解读
- 历史●海南卷丨2023年海南省普通高中学业水平选择性考试高考历史真题试卷及答案
- 路基喷播植草防护施工方案
- 油桐外植体诱导体细胞胚胎发生的研究
- 汽车传感器与检测技术电子教案:光电式车辆高度位置检测传感器
- 工贸企业重大事故隐患判定标准试卷
- 介绍家乡活动方案
- 物理中考一轮复习教案 第十六讲《力与运动的关系》
- 介绍营销活动方案
- 会议记录(空白)
- GB/T 20624.2-2006色漆和清漆快速变形(耐冲击性)试验第2部分:落锤试验(小面积冲头)
- GB/T 11881-2006羽毛球
- 化工环境保护与及安全技术概论考试题及答案
- GB 11120-2011涡轮机油
- 挡土墙搭设脚手架专项方案
- 血管肉瘤临床诊疗指南
- 锂电池知识点
- 暂时进出口协议范本样本
- 2022年公务员年度考核测评表
- 2022届高考英语考前最后一课课件(10张)
评论
0/150
提交评论