1

我正在尝试在64 位 Intel Atom处理器 ( x86_64 )上学习基本操作系统开发。我无法让中断处理程序正常工作——我认为它没有在中断向量表中正确注册。

这是我加载到引导扇区的全部代码:

; The code in the boot sector of the disk is loaded by the BIOS at 0000:7c00 
mov ax, 0x07c0
mov ds, ax

; Set es register to 0x0000
xor ax, ax
mov es, ax

; Register IRQ 0x69 handler in the Interrupt Vector Table
cli
mov dx, int_prog
mov [es:0x69*4], dx
mov ax, cs
mov [es:0x69*4+2], ax
sti

; Call interrupt handler for IRQ 0x69
nop
int 0x69

; Busy loop to allow time for human to look at screen
hang:
    jmp hang

; Interrupt Handler
int_prog:
    pusha

    ; Print red 'A' to screen
    mov ax, 0xB800
    mov es, ax
    mov [es:0], word 0x441

    popa
    iret

; Pad with zeroes and add signature at end
times 510-($-$$) db 0
dw 0x55AA

我预计屏幕左角会出现一个红色的“A”,但什么也没有出现。将红色“A”打印到屏幕上的部分在中断处理程序之外工作正常,所以这不是问题。

我所能假设的是处理器永远不会进入中断处理程序——但我明确地用int 0x69.

我的代码中是否缺少某种特定于 x86 的设置?

4

2 回答 2

2

我对你的org. 如果你不说,Nasm 将默认为org 0. 这和你加载的方式是一致的ds。但int_prog将被评估为...一些小值,而不是 0x7C00 + 一些小值。您cs输入中断表地址的第二个字。我们知道cs是什么吗?“可能”为零。您已ds设置为 0x7C0。尝试使用ds而不是cs那里。或者,把整个事情都做为org 0x7C00并使两者都ds为零espusha并且popa不保留段寄存器。由于您更改es了 ISR,因此您可能还想保存和恢复它(尽管我认为目前这不是问题)。

好的,编辑:修正了“of”的拼写。而且...好吧,你的代码在哪里?在 0x7C00 - 这是您的 BIOS(或假 BIOS)加载它的位置。这可以作为段 0 偏移量 0x7C00 或段 0x7C0 偏移量 0 来解决。可以肯定的是,您已经跳转到 0:0x7C00,但 0x7C0:0 也可以,并且有传言说某个 Compaq 中的 BIOS Presario 模型就是这样做的。我们真的不应该指望它。

那么,您的中断服务程序的代码在哪里?在 0:0x7Cxx 或 0x7C0:xx。您想将其中一个段:偏移量组合放入您的中断向量表中(我们知道它在段 0 中 - 您完全正确地理解了该部分) Jesus Ramos 教授的建议是正确的,但他正在考虑稍后我们'已切换到保护模式。

因为您没有使用org指令,Nasm 假设org 0,即它仅将地址评估为文件偏移量。如果您说org 0x7C00Nasm 会将地址评估为文件偏移量加上 0x7C00。就是org这样。在您的情况下,Nasm 已将地址(地址的偏移部分)评估为“xx”......这就是您在 IVT 中输入的内容。因此,在 IVT(第二个词)的段部分中,您需要 0x7C0。0:xx 不会找到您的代码。由于您已将已知值 0x7C0 放入ds,因此效果很好。

如果我还没有回答您的问题,请再问...

于 2013-09-18T19:27:02.877 回答
1

在 x86 中,您需要设置中断描述符表才能使中断工作。看看https://github.com/jesus-ramos/not-a-good-os/tree/master/kernelinterupt.s,这些文件desc_tables.c将提供一些相关信息。这是我编写的一个小内核,用于教授 x86 和操作系统的基础知识,因此您可以随意从中获取所需的任何内容。

基本上你需要设置 IDT(中断描述符表)。在此之前,您必须执行一系列指令来重新映射 IRQ 表(一些outportb指令具有正确的值),用值填充 IDT,最后发出lidt指令将描述符表加载到适当的位置。

在实模式下,IDT 位于地址中0x0000 - 0x03FF,由 4 个字节条目组成(不确定 64 位上是否有 8 个字节,但这意味着地址范围的上限是 2048 而不是 1024)。只需将您的实模式指针写入表中的正确条目(看起来就像您正在做的那样)。dx问题可能是由于使用vs而放置了不正确的值edx

于 2013-09-18T18:30:07.513 回答