我正在开发一个具有严格启动时间要求的项目。目标架构是一个基于IA-32的处理器,运行在32位保护模式下。确定可以改进的一个领域是当前系统动态初始化处理器的IDT(中断描述符表)。由于我们没有任何即插即用设备,并且系统相对静态,因此我希望能够使用静态构建的IDT。静态定义的IDT
但是,由于8字节的中断门描述符拆分了ISR地址,这对IA-32拱门来说很麻烦。 ISR的低16位出现在描述符的前2个字节中,其他一些位填充接下来的4个字节,最后ISR的最后16位出现在最后2个字节中。
我想用一个常量数组定义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不是常量。它的值由链接器(只能进行有限的数学运算)而不是由编译器解决。
任何建议或其他想法如何做到这一点?
谢谢,
我的建议是确保你的IDT和ISR在同一个模块中(显然ISR是在一个固定位置加载的)然后使用标签。我试着用GCC做这件事,但它不喜欢在函数外部使用'&& myIsr0'语法,而且我没有使用'__asm__'语法来声明IDT的内联汇编技巧。我可能只是使用NASM(个人偏好)编译这个模块,ISR是C函数的存根调用。这将是我的建议,但我绝对不能声称是一个专家:) – Justin
这是一种讨厌的建议,我会给:使用程序集。当使用非常特定的处理器功能或极低级别的构造时,请调用一些程序集。它使它更容易。 – Linuxios
这不是我的特长;有人可以简单地解释或指出我为什么这是非法的吗? – taz