我正在将NetBSD 5.1用于x86系统。在研究一些与驱动程序相关的代码时,我发现我们使用 splraise 和 spllower 来阻止或允许中断。我在互联网上搜索了一些机制,以了解这些机制在现实中是如何工作的。没有得到任何真正的信息。
当我反汇编时,我得到了机制,但仍然不明白所有这些汇编指令如何产生结果。我个人知道x86指令,但不了解整个过程是如何工作的。
需要您的帮助来了解x86系统的原理。我了解我们需要禁用中断启用(IE)位,但是该程序集似乎不仅仅在完成这项工作。需要帮助。
(gdb) x/50i splraise
0xc0100d40: mov 0x4(%esp),%edx
0xc0100d44: mov %fs:0x214,%eax
0xc0100d4a: cmp %edx,%eax
0xc0100d4c: ja 0xc0100d55
0xc0100d4e: mov %edx,%fs:0x214
0xc0100d55: ret
0xc0100d56: lea 0x0(%esi),%esi
0xc0100d59: lea 0x0(%edi,%eiz,1),%edi
(gdb) p spllower
$38 = {<text variable, no debug info>} 0xc0100d60
0xc0100d60: mov 0x4(%esp),%ecx
0xc0100d64: mov %fs:0x214,%edx
0xc0100d6b: cmp %edx,%ecx
0xc0100d6d: push %ebx
0xc0100d6e: jae,pn 0xc0100d8f
0xc0100d71: mov %fs:0x210,%eax
0xc0100d77: test %eax,%fs:0x244(,%ecx,4)
0xc0100d7f: mov %eax,%ebx
0xc0100d81: jne,pn 0xc0100d91
0xc0100d84: cmpxchg8b %fs:0x210
0xc0100d8c: jne,pn 0xc0100d71
0xc0100d8f: pop %ebx
0xc0100d90: ret
0xc0100d91: pop %ebx
0xc0100d92: jmp 0xc0100df0
0xc0100d97: mov %esi,%esi
0xc0100d99: lea 0x0(%edi,%eiz,1),%edi
0xc0100da0: mov 0x4(%esp),%ecx
0xc0100da4: mov %fs:0x214,%edx
0xc0100dab: cmp %edx,%ecx
0xc0100dad: push %ebx
0xc0100dae: jae,pn 0xc0100dcf
0xc0100db1: mov %fs:0x210,%eax
0xc0100db7: test %eax,%fs:0x244(,%ecx,4)
0xc0100dbf: mov %eax,%ebx
0xc0100dc1: jne,pn 0xc0100dd1
0xc0100dc4: cmpxchg8b %fs:0x210
0xc0100dcc: jne,pn 0xc0100db1
0xc0100dcf: pop %ebx
0xc0100dd0: ret
0xc0100dd1: pop %ebx
0xc0100dd2: jmp 0xc0100df0
0xc0100dd7: mov %esi,%esi
0xc0100dd9: lea 0x0(%edi,%eiz,1),%edi
0xc0100de0: nop
0xc0100de1: jmp 0xc0100df0
该代码似乎正在使用辅助功能 cx8_spllower ,从地址 0xc0100da0 开始。
答案 0 :(得分:2)
使用以下命令清除[E|R]FLAGS.IE
CLI
禁用CPU上的所有(可屏蔽的)中断。
出于多种原因,这可能是不可取的(例如,您希望允许某些,或者您不希望在VM中虚拟化CLI
的开销)。
实现该目标的另一种方法是告诉中断控制器(旧的8259 PIC或Pentium APIC / IOAPIC)您不希望服务优先级低于特定级别的中断。为此,您需要与控制器进行通信,这本身可能会产生额外的开销(与真实硬件和虚拟硬件的通信速度都很慢)。
后者的一种变体是将当前中断级别/优先级保留在变量中,并允许中断进入,但仅真正服务那些其级别/优先级不低于该变量中当前中断/优先级的中断。那些未服务的设备将被标记为待处理,并且在当前级别/优先级下降到足够低时将得到全面的服务。这就是splraise()
比spllower()
简单得多的原因。
此级别/优先级变量在代码的不同位置和版本中似乎使用不同的名称:CPL
(不要与CPU的当前特权级别混淆),{{1} }(?),SPL
。
这是我目前对实现的有限理解。还有更多细节。
以下是我找到并用于答案的一些线索: