在某些时候,卡的房子开始倒下。 X86处理器架构几乎足够老化,无法秘密收集养老金。这是,不要太精细的一点,一个吱吱作响的喘息的熨斗,让微处理器建筑的神越来越慷慨,很久以前就会被吹入遗忘。
英特尔和AMD做了一个惊人的工作,让老女孩在这几十年里奔跑,但是这种紧张开始讲述。编程x86芯片很难,这是令人沮丧的,因为新功能在旧的功能永远不会消失时保持打击。这就像使用耕地,帆和豪塞尔经营火箭船一样。这是一个奇迹,它完全适用。
所以,英特尔和AMD毫不奇怪 - 在世界各地的数千名X86程序员中毫不犹豫地说 - 可能会渴望抛弃一些光栅机械,并用更少的东西更换它......古雅。
案例在点:中断处理。自从'286(CIRCA MCMLXXXII)的日子以来,世界X86处理器都使用了拜占庭系统来管理组合查找表,特权检查,界限,上下文保存和内存管理的中断,故障和例外,以便混淆许多程序员 - 但以某种方式工作。大多数时候。
毫不奇怪,中断描述符表(IDT)系统中存在一些错误,他们往往是微妙的微妙。种族条件,锁定,无限循环和特权违规通常是罕见的,但不可避免的。不是每个操作系统都有蓝屏死亡,但他们会有类似的东西。操作系统程序员已经花了很多时间阐明和修补arthane和x86中断处理的奥秘细节。
重新启动的时间?也许。 Intel和AMD独立地提出了方案,以简化X86处理器处理故障,陷阱和中断的方式。当然,这两种方法彼此不同,不相容。英特尔更雄心勃勃,但它还代表了更多的工作人员希望利用新机制。 AMD的方法更简单;它更像是一种修补程序而不是大修。
在很长一段时间内,英特尔实际上想要抛弃,而不仅仅是调整它的主要功能之一。建议的FRED(灵活返回和事件交付)系统将完全替换IDT,以及其中断描述符。它还有效地减少了从四到两个的特权级别的数量。最后,呼叫门成为过去的事情。作为回报(所以说话),中断处理将更快,更简单,更完整,更容易发生角色案例错误。对于我们许多人来说,它将是我们生命中的第一个返工X86中断处理。
FRED将是可选的,因此怀旧仍然可以使用当前的IDT方法,有或没有呼叫门。您将能够在启动时切换Fred和Off,所以更旧的操作系统可以在同一芯片上共存。使用FRED启用,处理器完全忽略并绕过IDT。或者更准确地,您不必创建一个idt或中断描述符以开始。
中断,陷阱和例外集体称为“事件”,并将这些事件路由到其适当的处理程序成为“事件传递”。所有事件处理程序(即中断处理程序,故障处理程序,异常处理程序等)在特权级别0中运行,是四个特权的最特权和最内最内心的“环”。而不是使用IDT来定位每个处理程序的入口点,因此处理器硬件将简单地计算来自固定基地址的偏移量。它不如IDT系统的灵活性,但它更简单地设置和更快地实现硬件实现。
每个处理程序都将自动没有,但两个,入口点恰好接触到64字节。第一个(最低偏移地址)是用于从非特权代码调用处理程序时的。另一个是从特权CPL0代码调用处理程序时。拆分允许您编写两个退出例程,具体取决于您是否返回特权或非特权代码。简单,但有效。
为什么只有两个特权水平? FRED将X86家族的四个特权折叠倒入两个:用户和主管。这是从20世纪80年代推出的四级方案何时引入的一大步,但干预数十年表明,很少有程序员使用了所有四个层面。大多数刚刚从非普剧中分开的特权,所以英特尔趁机弗雷德来确定每个人都在做的事情。
用户/主管区别很重要,因为它决定了你是否改变堆栈。这始终是X86中断处理的弱点,它甚至具有64位扩展和操作系统的奇迹。处理器名义上维护了四个单独的堆栈(每个特权级别一个),以及用于操作系统或管理程序的可能的“阴影堆栈”。它很棘手要知道要使用的堆栈,它要保存,它永远不会触摸。
按照惯例,64位操作系统还使用GS段寄存器来维护线程完整性,但这不是由硬件管理的。中断处理程序必须跳动GS选择器和内存段,希望保留传入的上下文,并且没有原子操作来执行此操作。
Fred将自动完成所有这些。它将40个字节推到事件处理程序的特权堆栈上,以及其他64个字节的事件信息(基本上是一个迷你核心转储)。当它调用时,事件处理程序应该具有它需要直接工作的所有上下文。
英特尔的文档说:“FRED事件传递的主要功能是建立一个新的上下文,导致戒指0中的事件处理程序,同时保存后续返回的旧上下文。新上下文的某些部分具有固定值,而其他部分则依赖于旧的上下文,所传送的事件的性质和软件配置。“
从事件处理程序返回将使用两个新的指令,ERETU和ERET(事件返回用户/主管)。用户模式版本还原所有非普遍上下文,包括堆栈,指令指针,寄存器等。 Supervisor版本更简单,因此更快,因为它不会交叉特权级边界。
同样,SYSCALL和SYSENTER指令改变行为。它们仍然能够启用系统级功能调用,但不再通过(不存在)IDT。
另一个巨大的变化是打电话给盖茨。忘了他们。可以使用呼叫门填充IDT,这两个都定义了中断处理程序的入口点及其特权级别。现在,所有事件处理程序都有预定义的入口点,它们都以最高权限级别运行。 ERGO,不需要IDT中的呼叫门。
在其他地方的电话盖茨怎么样,就像在GDT或LDT?仍然没有。 Intel说:“启用FRED转换时,引用呼叫门的任何执行呼叫或远的JMP会导致普通保护异常(#gp)。”换句话说,您仍然可以在其他段中调用/跳转到代码,但它必须处于相同的权限级别。
呼叫盖茨曾经是一个共同和官方接受的方式来提升特权,但不再是。 FRED不允许特权更改(“环线交叉”)除了通过自己的机制,这意味着刻意中断或异常。
这提出了一个有趣的副作用,我肯定是故意的。如果所有权限更改都必须走得更好,并且如果FRED仅识别两个权限级别,则不再达到特权级别1或2的任何方法。这两个中间权限级别有效地解除了并呈现了不可用的。即使您以某种方式进出CPL1或CPL2,即使是第一个中断或异常也会踢到CPL0事件处理程序,然后将您返回到CPL3退出时。 Yup,我会说这两个额外的特权级别是ProcessOra非Grata。
与英特尔的中断大修相比,AMD的方法只是轻微的唾液和抛光。该公司的拟议主管入境扩展(见)保留熟悉的IDT,呼叫门和四个特权环。它调整了现有的SYSCALL指令,将状态位添加到将中断处理程序标记为重圈,并使不可掩除中断可屏蔽(!)。
请参阅Seepely仅修补多年软件开发中未发现的一些漏洞“以正确处理在实践中的情况很少,但不能被忽视。”一个是重圈故障处理程序的问题:它们不是。这太容易获得了故障或异常,跳转到相关的故障处理程序(通过IDT)并在从第一个上保存足够的上下文之前快速获得第二个相同的故障。只需有点运气,可以丢失上下文,或者如果您在设置堆栈指针的中间,则可以创建无限循环。
通过在每个中断描述符中分配一点来说明,请参阅解决方法,“此处理程序不重新入住。”设置后,随时调用此处理程序,处理器硬件将设置另一个“忙”位,并且它不会将处理器第二次调用,直到它清除。退出处理程序后,忙碌的位会自动清除,或者如果您是勇敢的话,您可以在软件中提前清除它。
这也适用于不可掩除的中断(NMI),这似乎令人难以肆无忌惮地危险,更不用说奥克朗。如果NMI处理程序处于活动状态,则处理器将推迟,但不会忽略,进一步的NMI中断,直到处理程序准备好,处理它们。
这两个建议都是全新的,两者都相对没有被忽视,直到某种Linus Torvalds以特征性地称重的意见。他的观点?他们都是好的想法。为什么不实现它们?虽然英特尔和AMD采取了完全分开的方法,但这两者不互相排斥。在最坏的情况下,您可以想象实现它们,然后在启动时启用一个或另一个(或两者)。什么是一个配置选项?
我们不经常看到X86处理器家庭的重大变化。也许它姗姗来迟。但是在云灯中改变翅膀上的翅膀(借用旧的类比)是棘手的业务。由于其向后兼容性,X86家族在很大程度上幸存下来。两家公司都意识到这一点;这些提案是选项,而不是强制替代品。他们应该只影响OS内核代码,而不是应用程序或驱动程序,所以他们几乎所有人都会看不见。我们可能会看到任何一个。或者我们可能期待略低于略低的越野中断处理。