接:深入学习LINUX内核之二
本文介绍的Linux作业系统是以Intel公司80X86及相关週边硬体组成的PC系统为基础的。有关80X86 CPU系统程式设计的最佳参考书籍当然是Intel公司发行的一套三卷的英文版《IA-32 Intel体系结构软体发展者手冊》,尤其足其中第3卷:《系统程式设计指南》是理解使用80X86 CPU的作业系统工作原理或进行系统程式设计必不可少的参考资料,实际上本章內容就主要取自於该书。这些资料可以从Intel公司的网站上免费下载。本章主要概要描述80X86 CPU的体系结构以及保护模式下程式设计的一些基础知识,为準备閱读基於80X86CPU的Linux內核原始码打下扎实基础。主要包括:1. 80X86基础知识:2. 保护模式记忆体管理:3. 各种保护措施:4. 中断和異常处理;5. 任务管理:6. 保护模式程式设计的初始化;7. 一个简单的多工內核例子。本章最后部分介绍的一个简单多工內核足以Linux 0.12內核为基础的一个简化实例。该实例用於演示记忆体分段管理和任务管理的实现方法,沒有包括分页机制內容。但若能彻底理解这个实例的运作机制,那麼在随后閱读Linux內核原始码时就不应该再会碰到什麼大问题了。若读者对这部分內容已经比较熟悉,那麼可以直接閱读本章最后给出的一个可执行的內核实例。当然,在閱读內核原始码时读者可以随时回过头来参考本章内容。因此並不勉強读者需要完全理解本章內容之后才开始閱读后续章节中的Linux內核代码。4.180X86系统寄存器和系统指令为了协助处理器执行初始化和控制系统操作,80X86提供了一个标志寄存器ELAGS和几个系统寄存器,除了一些通用状态标志外,EFLAGS中还包含几个系统标志。这些系统标志用於控制任务切換、中断处理、指令追蹤以及存取许可权。系统寄存器用於记忆体管理和控制处理器操作,含有分段和分页处理机制系统表的基底位址、控制处理器操作的Bit标志位元。4.1.1 标志寄存器标志寄存器EFLAGS中的系统标志和IOPL栏位用於控制I/O存取,可遮罩硬体中断,除错、任务切換以及虛拟-8086模式,见图4-l所示。通常只允许作业系统代码有权修改这些标志。EFLAGS中的其他标志是一些通用标志(进位元CF、奇偶PF、辅助进位元AF、零标志ZF、负号SF、方向DF、溢出OF)。这里我们仅对EFLAGS中的系统标志进行说明。TF 位元8是追蹤标志(Trap Flag)。当设置该位时可为除错操作啟动单步执行方式;复位时则禁止单步执行。在单步执行方式下,处理器会在每个指令执行之后產生一个除错異常,这樣我们就可以观察执行程式在执行每条指令后的状态。如果程式使用POPF、POPFD或IREF指令设置了TF标志,那麼在随后指令之后处理器就会產生一个除错異常。IOPL 位元13-12是I/O特权级(I/O Privilege Level)栏位。该栏位指明当前执行程式或任务的I/O特权级IOPL。当前执行程式或任务的CPL必须大於等於这个IOPL才能存取I/O位址空间。只有当CPL为特权级0时,程式才可以使用POPF或IRET指令修改这个栏位。 IOPL也是控制对IF标志修改的机制之一。NT 位元14是巢状任务标志(Nested Task) 。它控制著被中断任务和呼叫任务之间的链结关系。在使用CALl+指令、中断或異常执行任务呼叫时,处理器会设置该标志。在透过使用IRET指令从一个任务返回时,处理器会检查並修改这个NT标志,使用POPF/POPFD指令也可以修改这个标志,但是在应用程式中改变这个标志的状态会產生不可意料的異常。RF 位元16足恢复标志(Resume Flag) 。该标志用於控制处理器对中断点指令的回应。当设置时,这个标志会临时禁止中断点指令產生的除错異常;当该标志重定时,则中断点指令将会產生異常。RF标志的主要功能是允许在除错異常之后重新执行一条指令。当除错软体使用IRETD指令返回被中断程式之前,需要设置堆栈上EFLAGS內容中的RF标志,以防止指令中断点造成另一个異常。处理器会在指令返回之后自动地清除该标志,从而再次允许指令中断点異常。VM 位元17是虛拟-8086方式(Virtual-8086 Mode)标志,当设置该标志时,就开啟虛拟一8086方式:当重定该标志时,则回到保护模式。4.1.2 记忆体管理寄存器处理器提供了4个记忆体管理寄存器(GDTR、LDTR、IDTR和TR) ,用於指定记忆体分段管理所用系统表的基底位址,见图4-2所示。处理器为这些寄存器的载入和保存提供了特定的指令。有关系统表的作用请参见下一节“保护模式记忆体管理”中的详细说明。GDTR、LDTR、IDTR和TR都是段基址寄存器,这些段中含有分段机制的重要资讯表。GDTR、IDTR和LDTR用与定址存放描述呼号表的段。TR用于定址一个特殊的任务状态段TSS(Task State Segment)。TSS段中包含着当前执行任务的重要资讯。1. 全域描述符号表寄存器GDTRTDTR寄存器中用于存放全域描述符号表GDT的32位元的线性基底位址和16位元的表限长值。基底位址指定GDT表中位元组0在線性位址空间中的位址,表长度指明GDT表的位元组长度值。指令LTDT和SGDT分別用於载入和保存GDTR寄存器的內容。在机器刚加电或处理器复位后,基底位址被预设地设置为0,而长度值被设置成0xFFFF。在保护模式初始化行程中必须给GDTR载入一个新值。2. 中断描述符号表寄存器IDTR与GDTR的作用类似,IDTR寄存器用於存放中断描述符号表IDT的32位元線性基底位址和16位元表长度值,指令LIDT和SIDT分別用於载入和保存IDTR寄存器的內容。在机器刚加电或处理器复位后,基底位址被预设地设置为0,而长度值被设置成0xFFFF。3. 区域描述符号表暂存器LDTR LDTR寄存器中用於存放区域描述符号表LDT的32位元線性基底位址、16位元段限长和描述符号属性值。指令LLDT和SLDT分別用於载入和保存LDTR寄存器的段描述符号部分。包含LDT表的段必须在GDT表中有一个段描述符号项。当使用LLDT指令把含有LDT表段的选择符号载入进LDTR时,LDT段描述符号的段基底位址、段限长度以及描述符号属性会被自动地载入到LDTR中。当进行任务切換时,处理器会把新任务LDT的段选择符号和段描述符号自动地载入进LDTR中。在机器加电或处理器复位后,段选择符号和基底位址被预设地设置为0,而段长度被设置成0xFFFF。
本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.站长QQ:397422079 E_mail:riechelr_hl@unix5.com转载本站内容请注明原作者名.谢谢!