静态定义的 IDT [重复]

2024-03-14

我正在开发一个启动时间要求很紧的项目。目标架构是基于 IA-32 的处理器,在 32 位保护模式下运行。已确定可以改进的领域之一是当前系统动态初始化处理器的 IDT(中断描述符表)。由于我们没有任何即插即用设备并且系统相对静态,因此我希望能够使用静态构建的IDT。

然而,这对于 IA-32 架构来说很麻烦,因为 8 字节中断门描述符分割了 ISR 地址。 ISR 的低 16 位出现在描述符的前 2 个字节中,其他一些位填充接下来的 4 个字节,最后 ISR 的最后 16 位出现在最后 2 个字节中。

我想使用 const 数组来定义 IDT,然后简单地将 IDT 寄存器指向它,如下所示:

typedef struct s_myIdt {
    unsigned short isrLobits;
    unsigned short segSelector;
    unsigned short otherBits;
    unsigned short isrHibits;
} myIdtStruct;

myIdtStruct myIdt[256] = {
    { (unsigned short)myIsr0, 1, 2, (unsigned short)(myIsr0 >> 16)},
    { (unsigned short)myIsr1, 1, 2, (unsigned short)(myIsr1 >> 16)},

etc.

显然这行不通,因为在 C 中这样做是非法的,因为 myIsr 不是常量。它的值由链接器(只能执行有限的数学运算)解析,而不是由编译器解析。

关于如何做到这一点有什么建议或其他想法吗?


您遇到了众所周知的 x86 问题。我不相信链接器可以将 isr 例程的地址填充为 IDT 条目所期望的混合形式。

如果您雄心勃勃,您可以创建一个 IDT 构建器脚本来执行类似此(基于 Linux)的方法。我还没有测试过这个方案,无论如何它可能都是一种令人讨厌的黑客行为,所以要小心行事。

第 1 步:编写一个脚本来运行“nm”并捕获标准输出。

步骤 2:在脚本中,解析 nm 输出以获取所有中断服务例程的内存地址。

步骤 3:输出一个二进制文件“idt.bin”,其中 IDT 字节已全部设置并准备好执行 LIDT 指令。您的脚本显然以正确的混合形式输出 isr 地址。

第 4 步:使用 objcopy 将其原始二进制文件转换为 elf 部分:

objcopy -I binary -O elf32-i386 idt.bin idt.elf

第 5 步:现在 idt.elf 文件包含 IDT 二进制文件,其符号如下:

> nm idt.elf
000000000000000a D _binary_idt_bin_end
000000000000000a A _binary_idt_bin_size
0000000000000000 D _binary_idt_bin_start

第 6 步:重新链接您的二进制文件,包括 idt.elf。在程序集存根和链接器脚本中,您可以引用符号 _binary_idt_bin_start 作为 IDT 的基础。例如,您的链接器脚本可以将符号 _binary_idt_bin_start 放置在您喜欢的任何地址。

请注意,重新链接 IDT 部分不会移动二进制文件中的任何其他内容,例如你的 ISR 例程。通过将 IDT 放入其自己的专用部分,可以在链接器脚本(.ld 文件)中对此进行管理。

- -编辑 - -从评论来看,这个问题似乎很混乱。 32 位 x86 IDT 期望中断服务例程的地址被分成两个不同的 16 位字,如下所示:



 31           16 15            0
+---------------+---------------+
| Address 31-16 |               |
+---------------+---------------+
|               | Address 15-0  |
+---------------+---------------+
  

因此,链接器无法像正常重定位那样插入 ISR 地址。因此,在启动时,软件必须构建这种分割格式,这会减慢启动时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

静态定义的 IDT [重复] 的相关文章

  • 如何在x86汇编编程中表示诸如FFFFFFBB之类的十六进制值?

    我正在学习 x86 内联汇编编程 我想写mov ecx FFFFFFBB 但是编译器无法识别它 像这样的十六进制数字应该如何在内联汇编代码中编写 这取决于您的汇编器的风格 美国电话电报公司 movl 0xFFFFFFBB ecx Intel
  • Linux - 嵌套中断[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Linux 是否使用嵌套中断 我的意思是 例如 当从任何设备提供中断服务时 可以允许在此例程中进一步中断吗 或者它涉及上半部和下半部 ED
  • 假设没有非时间指令,“xchg”是否包含“mfence”?

    我已经看过了这个答案 https stackoverflow com a 50279772 391161 and 这个答案 https stackoverflow com a 19099164 391161 但似乎都没有清楚明确地说明等价或
  • 如果您的程序+库不包含 SSE 指令,那么使用 VZEROUPPER 有用吗?

    我明白使用它很重要VZEROUPPER混合 SSE 和 AVX 代码时 但如果我只使用 AVX 和普通 x86 64 代码 而不使用任何旧版 SSE 指令怎么办 如果我从未在代码中使用单个 SSE 指令 是否有任何性能原因导致我需要使用VZ
  • 为什么 Linux/gnu 链接器选择地址 0x400000?

    我正在 Linux x86 64 上试验 ELF 可执行文件和 gnu 工具链 我已经链接并剥离 手动 Hello World 测试 global start text start mov 1 rax 转换为 267 字节 ELF64 可执
  • 使用 gdb 在指定的可执行文件之外单步执行汇编代码会导致错误“无法找到当前函数的边界”

    我在 gdb 的目标可执行文件之外 甚至没有与该目标对应的堆栈 无论如何 我想单步执行 以便我可以验证汇编代码中发生了什么 因为我不是 x86 汇编方面的专家 不幸的是 gdb 拒绝进行这种简单的汇编级调试 它允许我设置并停止在适当的断点上
  • 从地址获取上一条指令的开头

    我们在缓冲区中查看 x86 操作码 标记当前指针 68 0F 00 6A 90 00 找到下一条指令的开始很容易 因为电流的大小是可以确定的 但是你如何才能准确地猜出前一个的开始呢 68 0F 00 6A 90 总共 5 个字节 结束于 0
  • 源操作数和目标操作数是否需要相同大小?

    我刚刚尝试了这个问题 要求你解释一下代码行有什么问题 movl eax rdx 解决方案表明目标操作数的大小错误 仅当从较大尺寸变为较小尺寸时才 非法 还是源操作数和目标操作数对于所有指令 或至少 mov 类类型 必须具有相同的尺寸 是的
  • x86 汇编中 cmove 指令的用途?

    反汇编可执行文件时我遇到了cmove操作说明 我已经在互联网上搜索过 但我只发现这是一个有条件的移动 如果源和目的地相等mov发生 我还不明白为什么我需要它 因为它不会改变操作数 它的目的是什么 The CMOVcc指令不比较源和目标 它们
  • 如何在汇编程序中使用 C 库?

    我想知道如何用汇编语言编写文本编辑器 但现代操作系统需要 C 库 特别是对于它们的窗口系统 我找到了这个page http pengu1n is programmer com posts 8304 html 这对我有很大帮助 但我想知道是否
  • 分配内存空间的宏

    我需要让一个汇编程序员来计算帕斯卡三角形 https en wikipedia org wiki Pascal 27s triangle 这样帕斯卡三角形的每一行都与其他行分开存储在内存中 我想做一个 但我不知道如何使用宏在汇编中做到这一点
  • g++ 内联汇编括号中不匹配

    g 向我抱怨以下代码中缺少括号 1 2 3 v v v asm volatile inb 1 0 a result Nd portnumber 1 2 3 正如您所看到的 括号是匹配
  • 如何禁用浮点单元(FPU)?

    我想在 x86 系统中禁用 FPU MMX SSE 指令 并且我将为设备不可用异常实现一个处理程序 我已经提到过控制寄存器 wiki 页面 http en wikipedia org wiki Control register 看来我必须在
  • 为什么当设置为 TLS 选择器时,ES 和 DS 在 64 位内核上最终会归零?

    下面的 32 位程序调用set thread area 2 http linux die net man 2 set thread area在 GDT 中创建一个条目 该条目旨在用于 TLS 通常将结果选择器放入FS or GS并成功使用
  • 为什么这个“std::atomic_thread_fence”起作用

    首先我想谈一下我对此的一些理解 如有错误请指正 a MFENCE在x86中可以保证全屏障 顺序一致性可防止 STORE STORE STORE LOAD LOAD STORE 和 LOAD LOAD 重新排序 这是根据维基百科 https
  • 为什么不能执行 mov [eax], [ebx] [重复]

    这个问题在这里已经有答案了 我可以做这个 mov eax ebx 和这个 mov eax ebx 甚至这个 mov eax ebx 但不是这个 错误C2415 mov eax ebx 只是wtf 为什么 它与 ptr1 ptr2 相同 为什
  • 如何在汇编语言中换行打印多个字符串

    我试图在汇编中的不同行上打印多个字符串 但使用我的代码 它只打印最后一个字符串 我对汇编语言非常陌生 所以请耐心等待 section text global start start mov edx len mov edx len1 mov
  • 为什么x86分页没有特权环的概念?

    早在 1982 年 当 Intel 发布 80286 时 他们在分段方案中添加了 4 个特权级别 环 0 3 由全局描述符表 GDT 和局部描述符表 LDT 中的 2 位指定 在 80386 处理器中 Intel 添加了分页功能 但令人惊讶
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • 当IRQL下降时,Windows中如何触发软件中断?

    我知道对于硬件中断 当 KeAcquireInterruptSpinLock 调用 KeLowerIrql 时 HAL 会调整 LAPIC 中的中断掩码 这将允许自动服务排队的中断 可能在 IRR 中 但是对于软件中断 例如 ntdll d

随机推荐