Linux操作系统基础(一)Intel32位系统架构总览(1)

来源:互联网 发布:python 简单 画图 编辑:程序博客网 时间:2024/06/08 16:16

Linux操作系统基础(一)Intel32位系统架构总览(1)

转载请注明出处:http://blog.csdn.net/rosetta

前言

         说是Linux操作系统基础,其实应该是Intel IA-32架构,但是以学习Linux操作系统为目的,故而称为《Linux操作系统基础》。本部分开始主要讲解80x86保护模式下基本概念,最主要的参考资料为Intel开发手册第三卷《系统编程指南》和赵炯的《Linux内核完全剖析》,最开始部分会直接翻译《系统编程指南》,当然不是逐字逐句的翻。

         本来想从中断开始写的,后来发现要把中断相关知识写出来必需要先明白分段机制,而分段机制和分页机制属于内存管理,内存管理之前还有一些最基本的概念比如标志寄存器、控制寄存器、内存寻址模式、地址变换、IDT、GDT等。所以先给出一个总体概念描述,然后再详细解释,循序渐进。基本概念看起来最头痛,但它是后续学习的基础,不好好理解基本概念,以后将会举步维艰,磨刀不误砍柴工。

         这一节将对Intel 32位系统架构中涉及的一些最基本的概念做概要介绍,在以后的博文中做具体阐述。如图1为Intel 32位系统架构总览。


图1

系统架构总览

全局描述符表(GDT)和局部描述符表(LDT)

       在保护模式下,所有内存访问都是通过全局描述符表(Global Descriptor Tables)或者局部描述符表(LocalDescriptor Tables)定位的,如图1所示。表的成员为段描述符(segment descriptors),段描述提供段基地址、段限长、段属性(段访问权限)、段类型和其它信息。每一个段描述符都有一个段选择符(segment select)与之对应,一个段选择符提供一个GDT或IDT的索引、一个指向标志TI(决定段选择符指向GDT还是IDT)和访问权限信息(请求特权级RPL)。

         为了访问段中的一个字节,必需提供一个段选择符和偏移值,段选择符提供了一种由段描述符到段访问的方法,处理器从段描述符中获取线性空间中的段基地址,段基地址再加上偏移值就确定了字节所在位置。访问数据段、代码段和堆栈段都是使用这种机制,提供的段必须是CPU的CPL(current privilege level)所接受的(CPL是当起可执行的代码段的保护级别)。

         GDT的线性基地址存储在GDT寄存器(GDTR)中;LDT的线性基地址存储在LDT寄存器(LDTR)中。

系统段、段描述符和门

       除了代码段、数据段和堆栈段是构成程序运行的环境外,系统架构还定义了两个系统段:任务状态段(task-state segement)和LDT。GDT不认为是段,因为它不通过段选择符或者段描述符访问。TSSs和LDTs都有相应的段描述符定义它们。

         系统架构还定义了一个特别的描述符集,称为门:调用门(call gates)、中断门(interrupt gates)、陷阱门(trap gates)和任务门(task gates)。这些门为运行在不同特权级的系统程序和处理程序提供保护。例如,一个对调用门的调用可以提供与当前代码段特权级相同或者数字更低(特权更高)的程序代码段的访问,也就是说程序的代码段特权级大于等于当前代码段特权级才可以访问。为了通过调用门访问程序,调用程序必需提供调用门选择符,然后由处理器通过调用门完成一个访问权限的检查——通过比较调用门的当前特权级和调用门指向的目标代码段的特权级。假如允许访问目标代码段,处理器从调用门中获取目标代码段的段选择符和段偏移。如果调用需要改变特权级,处理器也切换到目标特权级堆栈中。新栈的段选择符由当前运行的特务的TSS中获得。调用门使得在16位和32位代码段中转换变得更容易。

任务状态段(TSS)和任务门(taskgates)

  TSS定义了任务执行环境的状态。这些状态包括通用寄存器,段寄存器,标志寄存器,EIP寄存器以及三个堆栈段的段选择符(三个特权级0,2,3各一个)。TSS还包括一个LDT的段选择符,这个LDT把当前任务和页表基地址联系起来。

         保护模式下所有程序运行在任务上下文中(称为当前任务)。当前任务的TSS段选择符存放在任务寄存器(task register)中,最简单切换任务的方法就是通过call或jump 指令到新任务。这里新任务的TSS段选择符由call或jump指令提供。在任务切换过程中,处理器完成以下操作:

1.        在当前TSS中存储当前任务的状态。

2.        加载带有新任务段选择符的任务寄存器。

3.        通过GDT中段描述符访问新TSS。

4.        从新TSS加载新任务的状态到通过寄存器、段寄存器、LDTR、控制寄存器CR3(页表基地址)、EFLAGS标志寄存器和EIP寄存器中。

5.        开始执行新任务。

  任务也可以通过任务门访问。任务门和调用门类似,只不前者是对TSS的访问(通过段选择符),后者是对代码段的访问。

中断和异常处理

  外部中断、软中断和异常是通过IDT处理的。IDT存储提供访问中断和异常处理程序的门描述符的集合。和GDT类似,IDT也不是段。IDT的线性基地址存储在IDTR(中断门描述符表寄存器)中。

  IDT中的门描述符可分为:中断门、陷阱门和任务门。为了访问中断或异常处理程序,处理器首先接收一个中断向量(中断号),中断向量可以由内部硬件、外部中断控制器或者软件指令(比如INT,INTO,INT 3,BOUND)获得。中断向量提供IDT表的一个索引。假如选择的门描述符是中断门或陷阱门,相关的处理程序访问非常类似于通过调用门调用程序;假如选择的门描述符是任务门,处理程序是通过任务切换访问的。

内存管理

    系统架构支持直接物理寻址和虚拟内存(通过分页实现)。当使用直接物理地址时,一个线性地址就是一个物理地址;当使用分页时,所有的代码段、堆栈段、和系统段(包括GDT和IDT)可以将最近访问的页驻留在内存而分页(这句翻不太来)。物理内存中的页(有时称为页框)包含两种类型的系统数据结构:页目录和页表。两种数据结构都在物理内存中(见图1)。页目录的物理基地址存储在操作寄存器CR3中。一条页目录包含页表的物理基地址,访问权限和内存管理信息。一条页表包含页框的物理基地址,访问权限和内存管理信息。

         为了使用这种分页机制,一个线性地址被分为三部分:页目录,页表和页框。系统可以有一个或者多个页目录。例如,每个任务可以有它自己的页目录。

系统寄存器

         为了帮助处理器初始化和控制系统操作,系统架构提供存储系统标志的EFLAGS寄存器和几个系统寄存器:

l  系统标志和IOPL域在EFLAGS寄存器中,控制任务和运行模式切换、中断处理、指令跟踪他访问权限。

l  控制寄存器(CR0、CR2、CR3和CR4)包含多种标志和数据域来控制系统级操作。这些寄存器中的其它标志表示支持在操作系统和执行时的特别的处理能力。

l  debug调试寄存器允许在调试程序和系统软件时设置中断。

l  GDTR、LDTR和IDTR寄存器包括他们各自表的线性基地址和表的大小。

l  任务寄存器包含当前任务的TSS线性基地址和大小。

l  特别的模型寄存器。

其它系统资源

         除了在前面提到的系统寄存器和数据结构外,系统架构还提供以下额外的资源:

l  操作系统指令。比如LGDT、SGDT用来操作GDTR寄存器。

l  性能监控计数器。

l  内部高速缓存和缓冲区。

         性能监控计数器是用来记录处理器事件的事件计数器,比如指令解码数、中断接收数和高速缓存加载数。

         处理器提供一些内部高速缓存和缓冲区。高速缓存用来存储数据和指令,缓冲区用来存储类似于系统解码地址和应用程序段和等待执行的写操作。

 

参考:《Intel System ProgrammingGuide》

          《Linux内核完全剖析》赵炯编著

 


原创粉丝点击