精华内容
下载资源
问答
  • 本文内容:一、概念介绍 字段和标志位二、不同的描述符 1、 存储段描述符数据段描述符代码段描述符 2、 系统段描述符GDT、LDT、TSS、TCB概念介绍LDT段描述符TSS段描述符 3、 门描述符不同的门类型门描述符段描述符...

    系列文章

    x86 - CPU架构/寄存器详解 (一)x86、8086、i386、IA-32 是什么?
    x86 - CPU架构/寄存器详解 (二) 实模式(8086模式)
    x86 - CPU架构/寄存器详解 (三) 保护模式
    x86 - 分段与分页详解
    x86 - 特权级别 CPL / RPL / DPL / IOPL
    x86 - 操作系统:中断、陷阱、异常、故障、终止
    x86 - 描述符详解:存储/系统段描述符、门描述符

    一、概念介绍

      段描述符是GDT、LDT、IDT表中(关于三个表的介绍-系统地址寄存器)的一个数据结构项,用于向处理器提供有关一个段的位置和大小信息以及访问控制的状态信息。通常由编译器、链接器、加载器、操作系统或执行体创建,但不由应用程序创建。
    在这里插入图片描述
    在这里插入图片描述
      每个段描述符的长度是8字节,含有3个主要字段:段基地址、段限长和段属性。
    在这里插入图片描述

    字段和标志位

    Limit
      段限长字段Limit(Segment limit field):用于指定段的长度。处理器会把段描述符中两个段限长字段组合成一个20位的值,并根据颗粒度标志G来指定段限长Limit值的实际含义。
      • 如果G=0,则段长度Limit范围可从1B~1MB,单位是1B。
      • 如果G=1,则段长度Limit范围可从4KB~4GB,单位是4KB。

      根据段类型中的段扩展方向标志E,处理器以两种不同方式使用段限长Limit:
      • 对于向上扩展的段(expand-up segment,简称上扩段),逻辑地址中的偏移值范围可以从0到段限长值Limit。大于段限长Limit的偏移值将产生一般保护性异常(general-protection exceptions, #GP, SS段寄存器除外)或产生栈错误异常(stack-fault exceptions, #SS)。
      • 对于向下扩展的段(expand-down segment,简称下扩段),段限长Limit的含义相反。根据默认栈指针大小标志B的设置,偏移值范围可从段限长Limit+1到0xFFFFFFFF或0xFFFF。而小于等于段限长Limit的偏移值将产生一般保护性异常或栈错误异常。对于下扩段,减小段限长字段中的值会在该段地址空间底部分配新的内存,而不是在顶部分配。IA-32架构的栈总是向下扩展的,因此这种实现方式很适合扩展堆栈。

    Base
      基地址字段Base(Base address field):该字段定义在4GB 线性地址空间中一个段字节0所处的位置。处理器会把3个分立的基地址字段组合形成一个32位的值。段基地址应该对齐16字节边界。16字节对齐不是必须的,但对齐在16字节边界上使得程序能最大化程序性能。


    TYPE
      段类型字段TYPE(Type field):指定段或门(Gate)的类型、说明段的访问类型以及段的扩展方向。该字段的解释依赖于描述符类型标志S指明是一个应用(存储段)描述符还是一个系统描述符(System)。TYPE字段的编码对代码、数据或系统描述符都不同。

    S
      描述符类型标志S(Descriptor type flag):用于指明一个段描述符是系统段描述符(当S=0)还是代码 或数据段 描述符(当S=1)。

    DPL
      描述符特权级字段DPL(Descriptor privilege level):用于指明描述符的特权级。特权级范围从0到3。0级特权级最高,3级最低。DPL用于控制对段的访问。

    P
      段存在标志P(Segment present):用于指出一个段是在内存中(P=1)还是不在内存中(P=0)。
      当一个段描述符的P标志为0时,那么把指向这个段描述符的选择符加载进段寄存器将导致产生一个段不存在异常(segment-not-present exception,#NP)。内存管理软件可以使用这个标志来控制在某一给定时间实际需要把那个段加载进内存中。这个功能为虚拟存储提供了除分页机制以外的控制。当P标志为0时,操作系统可以自由使用格式中标注为可用(Available)的字段位置来保存自己的数据,例如有关不存在段实际在什么地方的信息。
    在这里插入图片描述
    D/B标志
      D/B标志(默认操作大小/默认栈指针大小和/或上界限,Default operation size/default stack pointer size and/or upper bound):根据段描述符描述的是一个可执行代码段、下扩数据段还是一个堆栈段,这个标志具有不同的功能。(对于32位代码和数据段,这个标志应该总是设置为1;对于16位代码和数据段,这个标志被设置为0。)
      • 可执行代码段。此时这个标志称为D标志并用于指出该段中的指令引用有效地址和操作数的默认长度。如果该标志置位,则默认值是32位地址和32位或8位的操作数;如果该标志为0,则默认值是16位地址和16位或8位的操作数。指令前缀0x66可以用来选择非默认值的操作数大小;前缀0x67可用来选择非默认值的地址大小。
      • 栈段(由SS寄存器指向的数据段)。此时该标志称为B(Big)标志,用于指明隐含堆栈操作(如PUSH、POP或CALL)时的栈指针大小。如果该标志置位,则使用32位栈指针并存放在ESP寄存器中;如果该标志为0,则使用16位栈指针并存放在SP寄存器中。如果堆栈段被设置成一个下扩数据段,这个B标志也同时指定了堆栈段的上界限。
      • 下扩数据段。此时该标志称为B标志,用于指明堆栈段的上界限。如果设置了该标志,则堆栈段的上界限是0xFFFFFFFF(4GB);如果没有设置该标志,则堆栈段的上界限是0xFFFF(64KB)。

    G
      粒度标志G(Granularity):该字段用于确定段限长字段Limit值的单位。如果颗粒度标志为0,则段限长值的单位是字节;如果设置了颗粒度标志,则段限长值使用4KB单位。(这个标志不影响段基地址的颗粒度,基地址的颗粒度总是字节单位。)若设置了G标志,那么当使用段限长来检查偏移值时,并不会去检查偏移值的12位最低有效位。例如,当G=1时,段限长为0表明有效偏移值为0~4095。

    L
      64位代码段标志L(64-bits code segment):在IA-32模式,第二个双字的第21字节指示一个代码的是否包含本地64位代码。L置1表示这个代码段的指令执行在64位模式,置0表示执行在兼容模式。如果L位被设置了,那么D标志一定要置0。当不处于IA-32e模式时,和对于非代码段,这个位被保留并且总是应该被置0。

    AVL
      可用和保留位AVL(Available and reserved bits):段描述符第2个双字的第20字节可供系统软件使用。

    二、不同的描述符

    1、 存储段描述符

      TYPE字段说明了存储段描述符所描述的存储段的具体属性:
    在这里插入图片描述

    数据段描述符

      当S=1且TYPE字段的最高位(第2个双字的位11)为0时,表明是一个数据段描述符。
    在这里插入图片描述
    B位
      默认栈指针大小和上界限。
      对于栈段(由SS寄存器指向的数据段)来说,该位用来指明隐含堆栈操作(如PUSH、POP或CALL)时的栈指针大小:
        B=0:使用SP寄存器
        B=1:使用ESP寄存器
      同时,B的值也决定了栈的上部边界:
        B=0:栈段的上部边界(也就是SP寄存器的最大值)为0xFFFF;
        B=1:栈段的上部边界(也就是ESP寄存器的最大值)为0xFFFF_FFFF.

    A位
      已访问:用于表示一个段最近是否被访问过(准确地说是指明从上次操作系统清零该位后一个段是否被访问过)。
      当创建描述符的时候,应该把这位清零。之后,每当该段被访问时(准确地说是处理器把这个段的段选择符加载进段寄存器时)它就会将该位置“1”;对该位的清零是由操作系统负责的,通过定期监视该位的状态,就可以统计出该段的使用频率。当内存空间紧张时,可以把不经常使用的段退避到硬盘上,从而实现虚拟内存管理。

    W位
      可写:指示段的读写属性。
        W=0:段不允许写入,否则会引发处理器异常中断;
        W=1:允许写入。

    E位
      扩展方向:
        E=0:表示向上扩展的段(简称上扩段),逻辑地址中的偏移值范围可以从0到Limit;
        E=1:表示向下扩展的段(简称下扩段,通常是栈段),逻辑地址中的偏移范围可以从Limit到0xFFFF(当B=0时)或者0xFFFF_FFFF(当B=1时)。

    代码段描述符

      当S=1且TYPE字段的最高位(第2个双字的位11)为1时,表明是一个代码段描述符。
    在这里插入图片描述
    D位
      默认操作数大小:用于指出该段中的指令引用有效地址和操作数的默认长度。
        D=0:默认值是16位的地址和16位或者8位的操作数;
        D=1:默认值是32位的地址和32位或者8位的操作数;
      说明:指令前缀0x66可以用来选择非默认值的操作数大小,指令前缀0x67可以用来选择非默认值的地址大小。

    A位
      已访问:与数据段描述符中的A位相同。

    R位
      可读:
        R=0:代码段不可读,只能执行。
        R=1:代码段可读,可执行。
      这里的R属性并非针对处理器,而是用来限制程序的行为。当常数或者静态数据被放在了一个ROM中时,就可以使用一个可读可执行的代码段,然后通过使用带CS前缀的指令,就可以读取代码段中的数据。
      注意:在保护模式下,代码段是不可写的;堆栈段必须是可读可写的数据段。

    C位
      一致性:
        C=0:表示非一致性代码段。这样的代码段可以被同级代码段调用,或者通过门调用;
        C=1:表示一致性代码段。可以从低特权级的程序转移到该段执行(但是低特权级的程序仍然保持自身的特权级)。
      注意:所有的数据段都是非一致性的,即意味着它们不能被低特权级的程序或过程访问。然而与代码段不同,数据段可以被更高特权级的程序或过程访问,而无需使用特殊的访问门

    2、 系统段描述符

    GDT、LDT、TSS、TCB

    在这里插入图片描述

    概念介绍

    GDT(全局描述符表)
      整个系统只有一个GDT;
      通过全局描述符寄存器GDTR进行定位;

    LDT(局部描述符表)
      每个任务都配有一个LDT,LDT基地址、界限等信息存放在任务对应的TCB中;
      通过局部描述符寄存器GDTR进行定位;
      将LDT视为一种特殊的内存段,则可为每一个LDT创建一个LDT描述符,将描述符存放到GDT中;
      访问LDT时:GDT选择子==>访问GDT==>LDT描述符==>访问LDT(==>加载到LDTR);

    TSS(任务状态段)
      每个任务都配有一个TSS,TSS基地址、界限等信息可以存放在任务对应的TCB中;
      通过任务寄存器TR进行定位;
      将TSS视为一种特殊的内存段,则可为每一个TSS创建一个TSS描述符,将描述符存放到GDT中;
      访问TSS时:GDT选择子==>访问GDT==>TSS描述符==>访问TSS(==>加载到TR);
    在这里插入图片描述
    TCB(任务控制块)
      任务控制块,可以说是系统中用来管理任务的最重要的数据结构了,操作系统用来管理任务的所有信息都可以放在这里,有些书籍上也称之为 PCB(Process Control Block,进程控制块)。
      在这个结构中,一些常用的信息包括:

    • 程序的加载地址;
    • 任务的优先级;
    • 任务的当前状态;
    • 任务打开的一些资源:网络、文件设备等待;
    • ……

      需要注意的是:上面的 LDT、TSS,是 x86 处理器中设计的运行机制,是处理器要求这样的。而 TCB 不是处理器要求的,它是操作系统的实现者自己来构建的,因此可以根据自己的需要来进行设计。
      每一个应用程序需要一个 TCP 结构,所有的 TCB 结构就可以构成一个链表,便于操作系统来管理。
      比如:在发生任务切换的时候,就可以顺着链表头,一次扫描链表上的每一个 TCB 节点。如果找到了当前正在被执行(即将被中止)的任务,就把这个任务的状态标记为暂停,并移动到链表的末尾,然后把链表头部的第一个处于 ready 状态的任务加载到处理器中去执行。当然,Linux 系统中的处理过程更为复杂,它把每一个任务按照优先级放在不同的等待队列中,然后利用哈希桶算法来查找任务。

    LDT段描述符

      LDT描述符存放在GDT中,在GDT中的选择子可以存入相应的TCB中;
    在这里插入图片描述
      段基地址指示LDT在内存中的起始地址;
      段界限指示LDT的范围;
      S-TYPE固定为’0-0010’,表明为LDT描述符;

    TSS段描述符

    在这里插入图片描述
      TSS描述符存放在GDT中,指向任务的TSS。
      TYPE中’B’:忙位,刚创建时应为0,任务开始执行,挂起时为1,由硬件管理,防止切换任务切到自己;
      任务不可重入的本质是,执行任务切换时,新任务的状态不能为忙(TYPE中的B不能为1)。
      TSS描述符DPL必须为0,只有CPL为0能调用。

    3、 门描述符

    不同的门类型

      门(调用、中断、任务或陷阱)用于跨段转移执行控制,权限级别检查的完成方式取决于所使用的目标类型和指令:

    类型区别
    调用门调用门使用 CALL 和 JMP 指令。调用门将控制从较低权限代码转移到与当前特权级相同或较高权限的代码段,门 DPL 用于确定哪些权限级别可以访问门。调用门正在(或可能已经)逐渐被放弃,转而支持更快的 SYSENTER/SYSEXIT 机制。
    任务门任务门用于硬件多任务支持。硬件任务切换可以自动发生(CALL/JMP 到任务门描述符),或者在设置 NT 标志时通过中断或 IRET。它的工作方式与中断门或陷阱门相同。没有使用任务门是因为内核通常希望在任务切换时完成额外的工作。
    中断描述符中断、陷阱、任务门一起被称为中断描述符表,存储在IDT中。除了参数从一个特权堆栈到另一个特权堆栈的传输之外,它们的工作方式与调用门相同。一个区别是中断门会清除 EFLAGS 中的 IF 位,而陷阱门则不会,这使它们成为处理硬件中断的理想选择。陷阱广泛用于硬件辅助虚拟化。

    门描述符与段描述符:

    类型区别
    段描述符用于描述符内存段,比如:数据段、代码段、堆栈段,存储段基址
    门描述符用于描述可执行代码,比如:一段程序、一个过程(例程、子程序)或者一个任务,存储段选择子

    短调用与长调用

    短调用
      短调用就是我们在汇编常见的CALL指令,调用格式为:CALL 立即数/寄存器/内存。为什么是短调用,我们来看一下执行该指令时堆栈的变化:
    在这里插入图片描述
      调用CALL指令之后,CPU只将当前的EIP压入堆栈后跳转到目标地址,发生改变的寄存器只有ESP和EIP,即所谓的短调用。

    长调用
      长调用分为两种,一种提权,一种不提权,调用格式为:
        CALL CS:EIP,其中EIP是废弃的,CS为指向调用门的段选择子。
      但是值得注意的是CS一旦更换,它的EIP和SS要同时更换。在代码执行的时候,一定会用到堆栈,堆栈的段权限必须与CS匹配(代码的特权级别必须和栈的级别一致),这就是为什么SS必须更换;
      注意:JMP FAR只能跳转到同级非一致代码段,但CALL FAR可以通过调用门提权,提升CPL的权限

    长调用不提权
      当段选择子指向的调用门不提权时,发生改变的寄存器有ESP、EIP和CS,比短调用多一个CS。执行情况如下图所示:
    在这里插入图片描述
      当通过门,权限不变的时候,只会PUSH两个值:CS和返回地址,新的CS的值由调用门决定。

    长调用提权
      当段选择子指向的调用门不提权时。发生改变的寄存器有ESP、EIP、CS和SS。执行情况如下图所示:
    在这里插入图片描述
      当通过门,权限改变的时候,会PUSH四个值:SS、ESP、CS和返回地址,新的CS的值由调用门决定,新的SS和ESP由TSS提供(不同特权等级的代码段需要使用不同的栈,TSS中保存有三个特权级别下的栈指针-ESP/SS)

    不同的门描述符详解

    调用门描述符

    在这里插入图片描述
      调用门描述某个子程序的入口,只存在于GDT中;
      调用门内的选择子必须指向代码段描述符,调用门内的偏移是对应代码段内的偏移。利用段间调用指令CALL,通过调用门可实现任务内从外层特权级变换到内层特权级;
      调用门执行流程如下所示:
       • 指令格式:CALL CS:EIP (EIP是废弃的)
       • 执行步骤同长调用
       • 根据CS的值查GDT表,找到对应的段描述符且该描述符是一个调用门。
       • 在调用门描述符中存储另一个代码段的段选择子,将其加载到CS中。
       • 选择子指向的段的Base + 偏移地址就是真正要执行的地址。
       • 使用REFT返回(当发生权限切换的时候,堆栈会保存 SS ESP CS EIP(返回地址),RETF本质就是将这些堆栈值进行恢复)
    在这里插入图片描述
      通过调用门进行程序的转移控制时,CPU会检查以下这几个字段:
       1.当前代码段的CPL;
       2.调用门描述符中的DPL;
       3.调用门描述符中的RPL;
       4.目的代码描述符的DPL;
       5.目标代码段描述符中的一致性标志C

    任务门描述符

    在这里插入图片描述
      阴影部分表示空闲不用;P标志位,为1时表示在内存中;DPL描述优先级别;类型码101表示任务门。
      其他三种门相比,在任务门中不需要用段内位移,因为任务门不指向某一个子程序的入口,而是指向GDT中的TSS描述符。此外,任务门中相对于D标志位的位置永远是0。

    任务门执行过程:
      1. 通过INT N的指令进行触发任务门
      2. 查IDT表,找到任务门描述符
      3. 通过任务门描述符,查GDT表,找到TSS段描述符
      4. 使用TSS段中的值修改TR寄存器
      5. IRETD返回

    修改TR寄存器途径:
      CPL=0时,可以通过LTR指令去修改TR寄存器。
      CPL=3时,可以通过CALL FAR或者JMP FAR指令来修改。用JMP去访问一个任务段的时候,如果是TSS段描述符,先修改TR寄存器,再用TR指向的TSS中的值修改当前的寄存器。

    CALL 和 JMP 实现任务切换的不同之处:
      如果用CALL,它会在 TSS 中的 Previous Task Link填写数值,并将EFLAGS寄存器的NT位改为1。如果这个位被改为1,iret指令会被当做任务返回,从TSS里的取出Previous Task Link返回;反之则为正常的中断返回,从堆栈读值返回。而JMP指令不会做上述事情。

    中断与嵌套调用:
      当中断发生时,可以执行常规的中断处理过程,也可以进行任务切换。尽管性质不同,但它们都要使用iret 指令返回。前者是返回到同一任务内的不同代码段;后者是返回到被中断的那个任务,处理器需要区分这两种截然不同的返回类型。
      EFLAGS有NT位(位14), 意思是嵌套任务标志(Nested Task Flag)。 每个任务的TSS中都有一个任务链接域 Previous Task Link( 指向前一个任务的指针,可以填写为前一个任务的TSS描述符选择子)。如果当前任务EFLAGS寄存器的NT位是“1”,则表示当前正在执行的任务嵌套于其他任务内,并且能够通过TSS任务链接域的指针返回到前一个任务。
      可以使用iret 指令从当前任务返回(转换)到前一个任务,前提是当前任务EFLAGS寄存器的NT位必须是“1"。无论任何时候处理器碰到iret指令,它都要检查NT位:
      • 如果此位是0,表明是一般的中断过程,按一般的中断返回处理,即,中断返回是任务内的(中断处理过程虽然属于操作系统,但属于任务的全局空间);
      • 如果此位是1,则表明当前任务之所以能够正在执行,是因为中断了别的任务,因此应当返回原先被中断的任务继续执行。此时,由处理器固件把当前任务EFLAGS寄存器的NT位改成“0",并把TSS描述符的B位改成“0”(非忙)。在保存了当前任务的状态之后,接着,用新任务(被中断的任务)的TSS恢复现场。

    中断门描述符

    在这里插入图片描述
      IDT表与GDT表不同,它的第一个元素不是NULL。IDT表包含3种门描述符:任务门描述符、中断门描述符、陷阱门描述符。
      中断描述符表 - IDT 是一个系统表,它与中断或异常向量相联系。每一个中断或异常向量在这个系统表中有对应的中断或异常处理程序入口地址。中断描述符的每一项对应一个中断或异常向量,每个向量由8个字节组成。因此,最多需要 256 * 8=2048 字节来存放IDT。
      除了调用门外,中断门也可以用来提权。不提权时,INT N 会压栈CS,EFLAG EIP;提权时,会依次压栈 SS ESP EFLAG CS EIP。需要用堆栈保存EFLAG是因为中断门会将EFLAG的IF位置0。
      中断门的结构和调用门结构几乎一样,只是调用门用来写参数数目的位被清空不再使用和Type域不一样而已.

    进入中断门:
      • 指令格式:INT N (N为中断门索引号)
      • 执行步骤:
       ○ 在没有权限切换时,会向堆栈顺次压入EFLAG、CS和EIP;如果有权限切换,会向堆栈顺次压入SS、ESP、EFLAG、CS和EIP。
       ○ CPU会索引到IDT表,后面的N表示查IDT表项的下标。对比调用门,中断门没有了RPL,故CPU只会校验CPL。
       ○ 在中断门中,不能通过RETF返回,而应该通过IRET/IRETD指令返回。

    调用门和中断门的区别:
      1. 调用门通过CALL FAR指令执行,RETF返回。中断门用INT指令执行,IRET或IRETD返回。
      2. 调用门查GDT表。中断门查IDT和GDT表
      3. CALL CS:EIP中CS是段选择子,由三部分组成。INT x指令中的x只是索引,中断门不检查RPL,只检查CPL。
      4. 调用门可以传参数。中断门不能传参数。

    陷阱门描述符

    在这里插入图片描述
      陷阱门执行流程与中断门一模一样。与中断门的区别,中断门执行时,将IF位清零,但陷阱门不会(IF允许/关闭中断)。
      中断门和陷阱门在使用上的区别不在于中断是外部产生的还是有CPU本身产生的,而在于:
       ○ 通过中断门进入中断服务程序时CPU会自动将中断关闭(将EFLAGS寄存器中IF标志位置0),以防止嵌套中断产生;
       ○ 通过陷阱门进入服务程序时则维持IF标志位不变。
      这是二者唯一的区别。

    处理器在实施任务切换时的操作

      处理器用以下四种方法将控制转换到其他任务:
      ● 当前程序、任务或者过程执行一个将控制转移到GDT内某个TSS描述符的jmp或者call指令;
      ● 当前程序、任务或者过程执行一个将控制转移到GDT或者当前LDT内某个任务门描述符的jmp或者call指令;
      ● 一个异常或者中断发生时,中断号指向中断描述表内的任务门;
      ● 在EFLAGS寄存器的NT位置位的情况下,当前任务执行了一个iret指令。

      jmp、call、iret 指令或者异常和中断,是程序重定向的机制,它们所引用的TSS描述符或者任务门,以及EFLAGS寄存器NT标志的状态,决定了任务切换是否,以及如何发生。在任务切换时,处理器执行以下操作: .
      ① 从JMP或者CALL指令的操作数、任务门或者当前任务的TSS任务链接域取得新任务的TSS描述符选择子。最后一种方法适用于以iret发起的任务切换。
      ② 检查是否允许从当前任务(旧任务)切换到新任务。数据访问的特权级检查规则适用于jmp和call指令,当前(旧)任务的CPL和新任务段选择子的RPL必须在数值上小于或者等于目标TSS或者任务门的DPL。异常、中断(除了以int n指令引发的中断)和iret指令引起的任务切换忽略目标任务门或者TSS描述符的DPL。对于以int n指令产生的中断,要检查DPL。
      ③ 检查新任务的TSS描述符是否已经标记为有效(P=1), 并且界限也有效(大于或者等于0x67,即十进制的103)。
      ④ 检查新任务是否可用,不忙(B=0,对于以CALL、 JMP、 异常或者中断发起的任务切换)或者忙(B=1,对于以iret发起的任务切换)。
      ⑤ 检查当前任务(旧任务)和新任务的TSS,以及所有在任务切换时用到的段描述符已经安排到系统内存中。
      ⑥ 如果任务切换是由jmp或者iret 发起的,处理器清除当前(旧)任务的忙(B) 标志;如果是由call指令、异常或者中断发起的,忙(B)标志保持原来的置位状态。
      ⑦ 如果任务切换是由iret指令发起的,处理器建立EFLAGS寄存器的一个临时副本并清除其NT标志;如果是由call指令、jmp 指令、异常或者中发起的,副本中的NT标志不变。
      ⑧ 保存当前(旧)任务的状态到它的TSS中。处理器从任务寄存器中找到当前TSS的基地址,然后将以下寄存器的状态复制到当前TSS 中:所有通用寄存器、段寄存器中的段选择子、刚才那个EFLAGS寄存器的副本,以及指令指针寄存器EIP。
      ⑨ 如果任务切换是由call 指令、异常或者中断发起的,处理器把从新任务加载的EFLAGS寄存器的NT标志置位;如果是由iret或者jmp指令发起的,NT标志位的状态对应着从新任务加载的EFLAGS寄存器的NT位。
      ⑩ 如果任务切换是由call指令、jmp 指令、异常或者中断发起的,处理器将新任务TSS描述符中的B位置位;如果是由iret指令发起的,B位保持原先的置位状态不变。
      ⑪ 用新任务的TSS选择子和TSS描述符加载任务寄存器TR。
      ⑫ 新任务的TSS状态数据被加载到处理器。这包括LDTR寄存器、PDBR (控制寄存器CR3)、EFLAGS寄存器、EIP寄存器、通用寄存器,以及段选择子。载入状态期间只要发生一个故障,架构状态就会被破坏(因为有些寄存器的内容已被改变,而且无法撤销和回退)。所谓架构,是指处理器对外公开的那一部分的规格和构造;所谓架构状态,是指处理器内部的各种构件,在不同的条件下,所建立起来的确定状态。当处理器处于某种状态时,再施加另一种确定的条件,可以进入另一种确定的状态,这应当是严格的、众所周知的、可预见的。否则,就意味着架构状态遭到了破坏。
      ⑬ 与段选择子相对应的描述符在经过验证后也被加载。与加载和验证新任务环境有关的任何错误都将破坏架构状态。注意,如果所有的检查和保护工作都已经成功实施,处理器提交任务切换。如果在从第1步到第11步的过程中发生了不可恢复性的错误,处理器不能完成任务切换,并确保处理器返回到执行发起任务切换的那条指令前的状态;如果在第12步发生了不可恢复性的错误,架构状态将被破坏;如果在提交点(第13步)之后发生了不可恢复性的错误,处理器完成任务切换并在开始执行新任务之前产生一个相应的异常。
      ⑭ 开始执行新任务。

      在任务切换时,当前任务的状态总要被保存起来。在恢复执行时,处理器从EIP寄存器的保存值所指向的那条指令开始执行,这个寄存器的值是在当初任务被挂起时保存的。任务切换时,新任务的特权级别并不是从那个被挂起的任务继承来的。新任务的特权级别是由其段寄存器CS的低2位决定的,而该寄存器的内容取自新任务的TSS。因为每个任务都有自己独立的地址空间和任务状态段TSS,所以任务之间是彼此隔离的,只需要用特权级规则控制对TSS的访问就行,软件不需要在任务切换时进行显式的特权级检查。任务状态段TSS的任务链接域和EFLAGS寄存器的NT位用于返回前一个任务执行,当前EFLAGS寄存器的NT位是“1”表明当前任务嵌套于其他任务中。无论如何,新任务的TSS描述符的B位都会被置位,旧任务的B位取决于任务切换的方法。表15-1给出了不同条件下,B位、NT位和任务链接域的变化情况。

    三、参考资料

      https://mp.ofweek.com/ai/a756714121207
      https://www.cnblogs.com/wingsummer/tag/Win%E7%B3%BB%E7%BB%9F%E5%86%85%E6%A0%B8/default.html?page=1
      https://cloud.tencent.com/developer/article/1681295

    展开全文
  • 摘自《Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D and 4》 《Intel 中断异常处理 - 目录》 先看一下调用门:

    摘自《Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D and 4》

    Intel 中断和异常处理 - 目录

    先看一下调用门:

    展开全文
  • 操作系统_中断异常

    2021-03-07 23:19:48
    保护模式前提下处理中断过程中断描述符表(Interrupt Descriptor Table)指令LIDT和SIDT用来操作IDTRIDT gate descriptors中断处理中硬件负责...的堆栈栈变化中断处理的特权级转换门描述符=段描述符名词汇总其他参考...

    为何需要中断机制?

    操作系统需要对计算机系统中的各种外设进行管理,这就需要CPU和外设能够相互通信才行。一般外设的速度远慢于CPU的速度。如果让操作系统通过CPU“主动关心”外设的事件,即采用通常的轮询(polling)机制,则太浪费CPU资源了。所以需要操作系统和CPU能够一起提供某种机制,让外设在需要操作系统处理外设相关事件的时候,能够“主动通知”操作系统,即打断操作系统和应用的正常执行,让操作系统完成外设的相关处理,然后在恢复操作系统和应用的正常执行。
    在操作系统中,这种机制称为中断机制。中断机制给操作系统提供了处理意外情况的能力,同时它也是实现进程/线程抢占式调度的一个重要基石

    中断类型

    在操作系统中,有三种特殊的中断事件。


    • 与CPU无关

    由CPU外部设备引起的外部事件如I/O中断、时钟中断、控制台中断等是异步产生的(即产生的时刻不确定),与CPU的执行无关,我们称之为异步中断(asynchronous interrupt),也称外部中断,简称中断(interrupt)


    • 在CPU执行指令期间

    在CPU执行指令期间检测到不正常的或非法的条件(如除零错、地址访问越界)所引起的内部事件称作同步中断(synchronous interrupt),也称内部中断,简称异常(exception)


    • 请求系统调用

    在程序中使用请求系统服务的系统调用而引发的事件,称作陷入中断(trap interrupt),也称软中断(soft interrupt)系统调用(system call)简称trap


    名词总结

    异步中断(asynchronous interrupt) = 外部中断 = 中断(interrupt)
    同步中断(synchronous interrupt)= 内部中断 = 异常(exception)
    陷入中断(trap interrupt) = 软中断(soft interrupt)
    系统调用(system call) = 陷入(trap)

    ------分割线------保护模式前提下处理中断过程

    当CPU收到中断(通过8259A完成)或者异常的事件时,它会暂停执行当前的程序或任务,通过一定的机制跳转到负责处理这个信号的相关处理例程中,在完成对这个事件的处理后再跳回到刚才被打断的程序或任务中。

    过程图
    在这里插入图片描述

    中断向量和中断服务例程的对应关系主要是由IDT(中断描述符表)负责。操作系统在IDT中设置好各种中断向量对应的中断描述符,留待CPU在产生中断后查询对应中断服务例程的起始地址。而IDT本身的起始地址保存在idtr寄存器中。

    中断描述符表(Interrupt Descriptor Table)

    中断描述符表(Interrupt Descriptor Table) 中断描述符表把每个中断或异常编号和一个指向中断服务例程的描述符联系起来。同GDT一样,IDT是一个8字节的描述符数组,但IDT的第一项可以包含一个描述符。CPU把中断(异常)号乘以8做为IDT的索引

    IDT可以位于内存的任意位置,CPU通过IDT寄存器(IDTR)的内容来寻址IDT的起始地址

    指令LIDT和SIDT用来操作IDTR

    指令LIDT和SIDT用来操作IDTR。两条指令都有一个显示的操作数:一个6字节(48位)表示的内存地址。指令的含义如下:

    • LIDT(Load IDT Register)指令:使用一个包含线性地址基址和界限的内存操作数来加载IDT。操作系统创建IDT时需要执行它来设定IDT的起始地址。这条指令只能在特权级0执行。

    • SIDT(Store IDT Register)指令:拷贝IDTR的基址和界限部分到一个内存地址。这条指令可以在任意特权级执行。


    在保护模式下,最多会存在256个Interrupt/Exception Vectors。范围[0,31]内的32个向量被异常Exception和NMI使用(前32个已被使用),但当前并非所有这32个向量都已经被使用,有几个当前没有被使用的,请不要擅自使用它们,它们被保留,以备将来可能增加新的Exception。范围[32,255]内的向量被保留给用户定义的Interrupts。Intel没有定义,也没有保留这些Interrupts。用户可以将它们用作外部I/O设备中断(8259A IRQ),或者系统调用(System Call 、Software Interrupts)等。

    IDT gate descriptors

    Interrupts/Exceptions应该使用Interrupt Gate和Trap Gate,它们之间的唯一区别就是:当调用Interrupt Gate时,Interrupt会被CPU自动禁止;而调用Trap Gate时,CPU则不会去禁止或打开中断,而是保留它原来的样子。

    补充
    所谓“自动禁止”,指的是CPU跳转到interrupt gate里的地址时,在将EFLAGS保存到栈上之后,清除EFLAGS里的IF位,以避免重复触发中断。在中断处理例程里,操作系统可以将EFLAGS里的IF设上,从而允许嵌套中断。但是必须在此之前做好处理嵌套中断的必要准备,如保存必要的寄存器等。

    在访问Trap Gate的目的是为了实现系统调用。用户进程在正常执行中是不能禁止中断的,而当它发出系统调用后,将通过Trap Gate完成了从用户态(ring 3)的用户进程进了核心态(ring 0)的OS kernel。如果在到达OS kernel后禁止EFLAGS里的IF位,第一没意义(因为不会出现嵌套系统调用的情况),第二还会导致某些中断得不到及时响应,所以调用Trap Gate时,CPU则不会去禁止中断。总之,interrupt gate和trap gate之间没有优先级之分,仅仅是CPU在处理中断时有不同的方法,供操作系统在实现时根据需要进行选择。


    在IDT中,可以包含如下3种类型的Descriptor:

    • Task-gate descriptor
    • Interrupt-gate descriptor (中断方式用到)
    • Trap-gate descriptor(系统调用用到)

    下图图显示了80386的任务门描述符、中断门描述符、陷阱门描述符的格式:

    在这里插入图片描述

    中断处理中硬件负责完成的工作(两个过程)

    中断服务例程包括具体负责处理中断(异常)的代码是操作系统的重要组成部分。需要注意区别的是,有两个过程由硬件完成:

    硬件中断处理过程1(起始)

    从CPU收到中断事件后,打断当前程序或任务的执行,根据某种机制跳转到中断服务例程去执行的过程。其具体流程如下:

    • CPU在执行完当前程序的每一条指令后,都会去确认在执行刚才的指令过程中中断控制器(如:8259A)是否发送中断请求过来,如果有那么CPU就会在相应的时钟脉冲到来时从总线上读取中断请求对应的中断向量;

    • CPU根据得到的中断向量(以此为索引)到IDT中找到该向量对应的中断描述符,中断描述符里保存着中断服务例程的段选择子

    • CPU使用IDT查到的中断服务例程的段选择子从GDT中取得相应的段描述符,段描述符里保存了中断服务例程的段基址和属性信息,此时CPU就得到了中断服务例程的起始地址,并跳转到该地址;


    注解关系:
    CPU根据中断向量到IDT中找到对应的中断描述符(中断描述符中保存着段选择子) + 通过段选择子从GDT中获得的相应的段描述符 = 中断服务例程的起始地址(段基址 + 属性信息)


    • CPU会根据CPL和中断服务例程的段描述符的DPL信息确认是否发生了特权级的转换。比如当前程序正运行在用户态,而中断程序是运行在内核态的,则意味着发生了特权级的转换,这时CPU会从当前程序的TSS信息(该信息在内存中的起始地址存在TR寄存器中)里取得该程序的内核栈地址,即包括内核态的ss和esp的值,并立即将系统当前使用的栈切换成新的内核栈。这个栈就是即将运行的中断服务程序要使用的栈。紧接着就将当前程序使用的用户态的ss和esp压到新的内核栈中保存起来;

    • CPU需要开始保存当前被打断的程序的现场(即一些寄存器的值),以便于将来恢复被打断的程序继续执行。这需要利用内核栈来保存相关现场信息,即依次压入当前被打断程序使用的eflags,cs,eip,errorCode(如果是有错误码的异常)信息;

    • CPU利用中断服务例程的段描述符将其第一条指令的地址加载到cs和eip寄存器中,开始执行中断服务例程。这意味着先前的程序被暂停执行,中断服务程序正式开始工作。

    硬件中断处理过程2(结束)

    每个中断服务例程在有中断处理工作完成后需要通过iret(或iretd)指令恢复被打断的程序的执行。CPU执行IRET指令的具体过程如下:

    • 程序执行这条iret指令时,首先会从内核栈里弹出先前保存的被打断的程序的现场信息,即eflags,cs,eip重新开始执行;

    • 如果存在特权级转换(从内核态转换到用户态),则还需要从内核栈中弹出用户态栈的ss和esp,这样也意味着栈也被切换回原先使用的用户态的栈了;

    • 如果此次处理的是带有错误码(errorCode)的异常,CPU在恢复先前程序的现场时,并不会弹出errorCode。这一步需要通过软件完成,即要求相关的中断服务例程在调用iret返回之前添加出栈代码主动弹出errorCode。

    下图显示了从中断向量到GDT中相应中断服务程序起始位置的定位方式:

    在这里插入图片描述

    中断产生后的堆栈栈变化

    下图显示了给出相同特权级和不同特权级情况下中断产生后的堆栈栈变化示意图:

    在这里插入图片描述

    中断处理的特权级转换

    中断处理得特权级转换是通过门描述符(gate descriptor)相关指令来完成的。

    门描述符=段描述符

    一个门描述符就是一个系统类型的段描述符,一共有4个子类型:
    调用门描述符(call-gate descriptor),
    中断门描述符(interrupt-gate descriptor),
    陷阱门描述符(trap-gate descriptor),
    任务门描述符(task-gate descriptor)。

    与中断处理相关的是中断门描述符和陷阱门描述符。这些门描述符被存储在中断描述符表(Interrupt Descriptor Table,简称IDT)当中。CPU把中断向量作为IDT表项的索引,用来指出当中断发生时使用哪一个门描述符来处理中断。中断门描述符和陷阱门描述符几乎是一样的。中断发生时实施特权检查的过程如下图所示:

    在这里插入图片描述
    门中的DPL和段选择符一起控制着访问,同时,段选择符结合偏移量(Offset)指出了中断处理例程的入口点内核一般在门描述符中填入内核代码段的段选择子。 产生中断后,CPU一定不会将运行控制从高特权环转向低特权环,特权级必须要么保持不变(当操作系统内核自己被中断的时候),或被提升(当用户态程序被中断的时候)。 无论哪一种情况,作为结果的CPL必须等于目的代码段的DPL。如果CPL发生了改变,一个堆栈切换操作(通过TSS完成)就会发生。如果中断是被用户态程序中的指令所触发的(比如软件执行INT n生产的中断),还会增加一个额外的检查:门的DPL必须具有与CPL相同或更低的特权。这就防止了用户代码随意触发中断。如果这些检查失败,会产生一个一般保护异常(general-protection exception)。

    名词汇总

    中断描述符表(Interrupt Descriptor Table)
    IDT寄存器(IDTR)
    LIDT(Load IDT Register)指令
    SIDT(Store IDT Register)指令
    门描述符(gate descriptor)

    其他参考

    8259A
    中断分析
    中断+源码分析

    展开全文
  • 在上一篇文章中,我们已经了解了中断异常的一些概念,对于中断异常也有了大概的理解。那么,系统中硬件到底是如何处理中断异常的呢?本文我们就以常见的X86架构为例,看看中断异常的硬件工作原理。1 高级可...

    在上一篇文章中,我们已经了解了中断和异常的一些概念,对于中断和异常也有了大概的理解。那么,系统中硬件到底是如何处理中断和异常的呢?本文我们就以常见的X86架构为例,看看中断和异常的硬件工作原理。

    1 高级可编程中断控制器-APIC

    之前,我们主要考虑的单处理器系统,如果是多处理器系统,主PIC控制器的INTR管脚是如何接到CPU上的?我们接下来讨论这个话题。

    我们知道,多核处理系统的价值在于 并行处理。所以,如何把中断分配到每一个CPU上就至关重要了。基于这个原因,Intel从奔腾III开始,引入一个新的高级可编程中断控制器(I/O-APIC)。这个控制器是8259A中断控制器的加强版。为了兼容旧版本的操作系统,有些主板包含这两种芯片。x86架构中,每个处理器包含自己的APIC,每个APIC具有32位的寄存器,内部时钟,内部定时器以及2个额外的IRQ线,LINT0和LINT1,用作APIC的中断。所有私有的APIC都连接到I/O-APIC,组成一个多APIC系统。

    图4-1展示了一个多APIC系统的原理图。I/O-APIC通过APIC总线和各个APIC连接在一起。I/O-APIC相等于一个中继的角色。

    图4-1 多APIC系统

    I/O-APIC由24条中断线,中断重定向表,可编程寄存器和一个通过APIC总线收发数据的消息单元组成。与8259A中断控制器不同,管脚编号不再具有优先级:重定向表中的每一项都可以被独立设置中断向量和优先级,目的处理器以及处理器如何处理该中断。也就是说,中断重定向表就是外部IRQ到私有APIC的映射关系。

    中断请求被分配到CPU上的方式有两种:

    静态分配

    按照重定向表中的定义把IRQ请求分配到相应的私有APIC高级可编程中断控制器上。中断可以指定给单个CPU,或者一组CPU,或者所有的CPU(相当于广播)。

    动态分配

    IRQ请求被发送给正在运行低优先级进程的处理器的私有APIC中断控制器上。通俗地说,就是哪个处理器正在运行低优先级任务,IRQ请求就发送给谁。

    每个私有APIC都有一个可编程任务优先级寄存器,用来保存当前运行任务的优先级。Intel期望每次进程切换的时候,操作系统内核修改这个寄存器。

    如果有多个CPU拥有相同的最低任务优先级,则使用仲裁技术分配中断请求。根据仲裁,每个CPU被分配一个不同的优先级(0-15,数字越小,优先级越大),这个优先级存储在私有APIC的任务优先级寄存器中。

    分配策略是,每当分配一个中断请求给一个CPU,则它对应的仲裁优先级被自动设为0,而其它CPU的仲裁优先级则被增加。当优先级寄存器中的值大于15时,则设为1。因为具有相同任务优先级的CPU的中断分配使用循环方式进行。

    动态分配的策略就是负载均衡的一种手段。关于负载均衡的算法以后再研究。

    除了CPU与外设之间的中断,多APIC系统还允许CPU产生CPU之间的中断。当一个CPU想给另一个CPU发送中断时,它就会把目标CPU的私有APIC的标识符和中断号存储到自己APIC的中断命令寄存器(ICR)中。然后通过APIC总线发送给目标APIC,该APIC就会给自己的CPU发送一个相应的中断。

    CPU间的中断(简称IPI)是多核系统一个重要组成部分。Linux有效地利用它们,在CPU之间传递消息。

    目前,大部分的单核系统也都包含一个I/O-APIC芯片,可以使用两种不同的方式配置它:

    当一个标准的8259A类型的外部PIC使用。私有APIC被禁止,LINT0和LINT1这两个IRQ请求线被分别配置为INTR和NMI管脚。

    作为标准的I/O-APIC使用,只不过只有一个CPU而已。

    2 异常

    x86架构大约有20种不同的异常。内核必须为每种异常提供专用的处理函数。对于某些异常,CPU控制单元也会产生硬件错误码,并将其压入内核态栈,然后再启动异常处理函数。

    下表是异常列表,列出了异常号,名称,类型等等。更多信息请参考Intel技术手册。

    #

    异常

    类型

    异常处理函数

    信号

    0

    除法错误

    fault

    divide_error()

    SIGFPE

    1

    Debug

    trap/fault

    debug( )

    SIGTRAP

    2

    NMI

    -

    nmi( )

    -

    3

    断点

    trap

    int3( )

    SIGTRAP

    4

    溢出

    trap

    overflow( )

    SIGSEGV

    5

    边界检查

    fault

    bounds( )

    SIGSEGV

    6

    非法操作码

    fault

    invalid_op( )

    SIGILL

    7

    设备不可用

    fault

    device_not_available( )

    -

    8

    串行处理

    异常错误

    abort

    doublefault_fn()

    -

    9

    协处理器

    错误

    abort

    coprocessor_segment_overrun( )

    SIGFPE

    10

    非法TSS

    fault

    invalid_TSS( )

    SIGSEGV

    11

    段引用错误

    fault

    segment_not_present( )

    SIGBUS

    12

    栈段错误

    fault

    stack_segment( )

    SIGBUS

    13

    通用保护

    fault

    general_protection( )

    SIGSEGV

    14

    页错误

    fault

    page_fault( )

    SIGSEGV

    15

    Intel保留

    -

    -

    -

    16

    浮点错误

    fault

    coprocessor_error( )

    SIGFPE

    17

    对齐检查

    fault

    alignment_check( )

    SIGBUS

    18

    机器检查

    abort

    machine_check()

    -

    19

    SIMD

    浮点异常

    fault

    simd_coprocessor_error()

    SIGFPE

    Intel保留20-31未来使用。如上表所示,每个异常都有一个专门的处理函数处理,并给造成异常的进程发送一个信号。

    3 中断描述符表

    IDT表中,每一项对应一个中断或者异常,大小8个字节。因而,IDT需要256x8=2048个字节大小的存储空间。

    IDT表包含三种类型的描述符,使用Type位域表示(40-43位)。下图分别解释了这三种描述符各个位的意义。

    三种描述符分别为:

    任务门

    包含中断发生时要替换当前进程的新进程的TSS选择器。

    中断门

    包含段选择器和在段中的偏移量。设置了正确的段后,处理器清除IF标志,禁止可屏蔽中断。

    陷阱门

    同中断门类似,只是不会修改IF标志。

    4 中断和异常的硬件处理

    现在,我们来探究一下CPU控制单元是如何处理中断和异常的。我们假设内核已经完成初始化,CPU工作在保护模式下。

    CPU控制单元,在取指令之前,检查控制单元在执行前一条指令的时候是否有中断或异常发生。如果发生中断,控制单元就会做如下处理:

    确定中断或异常的编号N;

    读取IDT表中的第N项;(在后面的描述中,假设包含的是中断门或陷阱门)

    确保中断合法性。

    首先比较cs寄存器中的CPL(当前特权等级)和包含在GDT中的段描述符的DPL(描述符特权等级),如果CPL小于DPL,产生 通用保护 异常,因为中断处理程序的特权等级不能比造成中断的程序的低。对于可编程异常,还会做进一步的安全检查:比较当前特权等级(CPL)和IDT表中包含的描述符的DPL,如果DPL小于CPL,则产生通用保护的异常。后一项检查,可以阻止用户应用程序访问特定的trap或中断门。

    检查特权等级是否发生变化。如果CPL与描述符中的DPL不同,控制单元应该使用新特权等级下的堆栈。

    其实对于Linux来说,只使用了supervisor和user两种特权等级。所以中断应该都是在supervisor特权等级下运行。

    读取tr寄存器,访问运行中的进程的TSS段;

    使用新特权等级对应的堆栈段和堆栈指针加载ss和esp寄存器;(这些值存储在TSS中)

    在新的堆栈中,保存旧任务的ss和esp寄存器值。(处理完中断或异常后,还要恢复到旧任务执行)

    保存eflags、cs和eip到堆栈中;

    如果异常携带异常错误码,将其保存在堆栈中;

    根据IDT表中的第N项内容,加载cs和eip寄存器。

    至此,CPU控制单元跳转到中断或异常处理程序处开始执行。等到中断或异常处理完成后,把CPU的使用权让给之前被中断的进程,使用iret指令,该指令强迫控制单元执行下面步骤:

    加载被中断进程的cs,eip和eflags寄存器。(如果压栈过异常错误码,应该在执行iret指令之前弹出)

    检查CPL是否等于cs寄存器中的CPL,如果相等,则iret指令结束执行;否则,继续。

    加载旧特权等级的ss和esp寄存器值。

    或者添加QQ号

    982285361

    展开全文
  • 中断:可屏蔽中断:所有有I/O设备请求的中断都是,被屏蔽的中断会一直被CPU 忽略,直到屏蔽位被重置。不可屏蔽中断:非常危险的事件引起(如硬件失败)。...中断描述符表(IDT):256项,其中的每一项关联一个中断...
  • 中断向量表 / 中断描述符中断程序执行方式 向量中断 非向量中断实模式 - 中断向量表 IVT保护模式 - 中断描述符表 IDT 通过不同的门进行处理中断异常处理程序的保护 权限检查 中断处理参考资料 广义分类 ...
  • 补充:事件不仅包含中断异常,还包含系统调用,这个属于用户主动请求的事件。 上一节,只有一个溢出异常,那么,如果很多异常中断呢?(中断向量表) 另外,之前0号地址只能存储两条指令,如果需要更多指令...
  • 目录 1. 中断概述 1.1 什么是中断 1.2 为什么引入中断 ...4. 中断向量与中断描述符表 4.1 中断向量 4.1.1 中断向量的概念 4.1.2 中断向量的分配 4.2 中断描述符表(IDT) 4.2.1 实模式中断向量表
  • Linux Kernel arm64中断向量表的定义 (linux/arch/arm64/kernel/entry.S) /* * Exception vectors. */ .pushsection ".entry.text", "ax" .align 11 SYM_CODE_START(vectors) kernel_ventry 1, sync_invalid ...
  • 中断异常

    2021-04-25 21:19:04
    1.cpu会自动根据中断/异常向量,从中断描述IDT表中找到当前中断异常描述符,然后根据描述符中的IST,从Tss表中选出对应的栈指针将其赋值给RSP,完成栈的切换;然后,cpu会自动保存rsp,ss,cs,rip寄存器值到新...
  • 初始化门描述符2.1 早期异常处理2.2 start_kernel中的异常向量初始化一2.3 idtentry宏(DB异常为例)2.4 start_kernel中的异常初始化二-trap_init()2.5 初始中断描述符2.5.1 IRQ2.5.2 early_irq_init2.5.3 init_...
  • 2. 异常如上所述,在8088中的内部中断,如除法、单步、溢出、软件中断(INTn),均被列入异常中。有人也将它们称之为陷阱。7.5.2 中断异常的响应过程1.优先级前面已经提到80386之后的处理器有许多中断异常发生,...
  • Linux0.12-内存寻址

    2021-05-17 17:27:15
    一、分段与分页的比较1.逻辑地址 -----(分段机制)----->...逻辑地址 = 选择(16位) : 偏移值(32位),逻辑地址是二维的线性地址和物理地址都是32位,是一维的3.分段的原因:隔绝各个任务的代码、...
  • 中断向量表

    2021-05-13 14:16:19
    因此为了让CPU由中断号查找到对应的中断向量,就需要在内存中建立一张查询表,即中断向量表(在32位保护模式下该表称为中断描述符表)。80x86微机支持256个中断,对应每个中断需要安排一个中断服务程序。在80x86实模式...
  • 目录 1. 中断异常概述 1.1 中断的分类 1.1.1 中断(Interrupt) ...2.2.2 中断描述符表的构成 2.2.3 中断门与陷阱门 2.3 保护模式下中断控制转移过程 2.4 中断异常发生时的特权级检查 2.4.1 不检查RP
  • 文件描述符2. 系统调用和库函数的区别2.1 系统调用2.2 库函数2.3 区别2.4 内核态和用户态的区别 file 1. 文件描述符 是一个非负的索引值(一般从3开始,0,1,2已经被使用),指向内核中的“文件记录表”, 当...
  • 基于 ARM Linux 中断异常的处理分析本文是基于ARM S3C2410X 系统的Linux 2.6 中断异常和系统调用的处理分析。主要有以下几个部分:1. ARM 的硬件中断机制2. Linux 2.6 对 ARM 中断向量表的初始化3. Linux 2.6 对...
  • 1、中断的作用:中断信号提供了一种方式,使处理器转而去运行正常控制流之外的代码。...2、异常又分为三种类型:(1)、故障(Fault):保存在eip中的值是引起故障的指令地址,因此,当异常处理程序终止...
  • _vectors_start的vendor_irq,然后最终走到了irq_desc(中断例程描述符表),里面就定义了irqaction,irqaction链表指向了irq_handler_t中断服务程序,即reques_irq注册的中断服务程序 而对于其他类型的异常,如RESET...
  • 中断中断处理流程

    千次阅读 2020-12-20 04:41:20
    1. 中断概念中断是指由于接收到来自外围硬件(相对于中央处理器和内存)的异步信号或来自软件的同步信号,而进行相应的硬件/软件处理。发出这样的信号称为进行中断请求(interrupt request,IRQ)。硬件中断导致处理器...
  • 中断异常与并发

    2021-01-29 21:26:47
    title: 中断异常与并发 date: 2019-12-29 22:19:12 文章目录0. 前言1.... 中断描述符表(Interrupt Descriptor Table,IDT)3. 并发3.1. 并发的本质3.2. 定时器中断3.3. 浅析多进程并发 0. 前言 记.
  • Linux内核深入理解中断异常(4):不可屏蔽中断NMI、浮点异常和SIMD rtoax 2021年3月 本文介绍一下几种trap: //* External hardware asserts (外部设备断言)the non-maskable interrupt [pin] on the CPU. //...
  • Intel 8086是16为的CPU,有16为的寄存器、16位的数据总线以及20位的地址总线,因此它有1M的寻址空间,一个地址是又和偏移两部分组成的,物理地址计算方法是:Physical Address = (Segment) * 16 + Offset (S...
  • 7.中断门(Interrupt Gate)

    千次阅读 2021-09-20 19:06:17
    目录 0.Interrupt Descriptor Table <1>.Windbg查找IDT <2>....1.中断描述符 ...2.中断门执行 ....中断门执行流程 ....中断门堆栈 .......在分析中断门之前首先得了解IDT表(中断描述符表) IDT同
  • TSS任务状态 一个内核一个,存在于内存中,不存在与cpu;可以让cpu同时执行多个任务。...从GDT表中找到tr寄存器,selector记录着TSS段描述符,base记录TSS表位置,limit记录TSS大小 2.tr寄存器 3. TSS
  • 异步中断分为:IO中断,时钟中断,处理器之间中断。下面重点学习linux的IO中断处理。所有中断处理程序都执行四个相同的工作。(1)在内核态保存IRQ的只和寄存器的值(2)应答中断(3)执行这个IRQ的所有中断服务例程。(4)...
  • 第一周 进程和进程的上下文切换第一周小测验1、以下有关计算机程序和进程的描述中,错误的是( )。A、用高级语言编写的程序必须转换为机器代码才能在计算机中运行B、机器代码通常以可执行目标文件或共享库文件形式...
  • 初期中断异常处理 在上一个 部分 我们谈到了初期中断初始化。目前我们已经处于解压缩后的Linux内核中了,还有了用于初期启动的基本的 分页 机制。我们的目标是在内核的主体代码执行前做好准备工作。 我们已经在 本...
  • STM32网络之中断

    千次阅读 2021-02-05 15:29:15
    之前的推文已经将STM32网络的三大件讲完了 ①PHY接口,《STM32网络电路设计》 ②MAC控制器,《STM32网络之MAC控制器》 ...第一个网络中断保留为MAC和DMA产生的中断,正如在MAC中断和DMA中断部分。 第二个中断保.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,967
精华内容 17,986
关键字:

中断异常段描述符