gpt4 book ai didi

interrupt - 静态定义的 IDT

转载 作者:行者123 更新时间:2023-12-03 22:26:37 29 4
gpt4 key购买 nike

我正在处理一个启动时间要求很紧的项目。目标架构是在 32 位保护模式下运行的基于 IA-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)},

等等。

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

关于如何做到这一点的任何建议或其他想法?

谢谢,

最佳答案

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

如果您有雄心壮志,您可以创建一个 IDT 构建器脚本,该脚本执行类似(基于 Linux)的方法。我还没有测试过这个方案,无论如何它可能是一个令人讨厌的黑客,所以请谨慎行事。

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

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

第 3 步:输出一个二进制文件“idt.bin”,其中包含所有设置好的 IDT 字节并为 LIDT 指令做好准备。您的脚本显然以正确的 swizzled 形式输出 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。在您的程序集 stub 和链接器脚本中,您可以将符号 _binary_idt_bin_start 称为 IDT 的基础。例如,您的链接描述文件可以将符号 _binary_idt_bin_start 放置在您喜欢的任何地址处。

请注意,与 IDT 部分重新链接不会移动二进制文件中的任何其他内容,例如你的 isr 例程。通过将 IDT 放入它自己的专用部分,在您的链接描述文件(.ld 文件)中管理它。

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

31 16 15 0
+--------------+--------------+
|地址31-16 | |
+--------------+--------------+
| |地址 15-0 |
+--------------+--------------+

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

关于interrupt - 静态定义的 IDT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12861843/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com