设置 IRQ 映射

发布于 2024-07-08 02:15:37 字数 758 浏览 16 评论 0原文

我正在遵循一些教程和参考文献来尝试设置我的内核。 我在教程中遇到了一些不熟悉的代码,但根本没有解释它。 我被告知该代码将 16 IRQ (0-15) 映射到 ISR 位置 32-47

void irq_remap(void)
{
    outportb(0x20, 0x11);
    outportb(0xA0, 0x11);
    outportb(0x21, 0x20);
    outportb(0xA1, 0x28);
    outportb(0x21, 0x04);
    outportb(0xA1, 0x02);
    outportb(0x21, 0x01);
    outportb(0xA1, 0x01);
    outportb(0x21, 0x0);
    outportb(0xA1, 0x0);
}

outportb() 的代码如下,但我已经清楚地掌握了它的作用:

void outPortB(unsigned short port, unsigned char data)
{
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (data));
}

我应该提到这是在保护模式下的 x86 架构上。 这个源代码工作正常,我明白它的作用,但我不明白它是如何做到的。 有人可以向我解释一下这里发生了什么,以便在我需要扩展此内容时我会知道我在做什么吗?

I'm following several tutorials and references trying to get my kernel set up. I've come across some unfamiliar code in a tutorial that isn't explaining it at all. It's code that I'm told maps the 16 IRQs (0-15) to ISR locations 32-47:

void irq_remap(void)
{
    outportb(0x20, 0x11);
    outportb(0xA0, 0x11);
    outportb(0x21, 0x20);
    outportb(0xA1, 0x28);
    outportb(0x21, 0x04);
    outportb(0xA1, 0x02);
    outportb(0x21, 0x01);
    outportb(0xA1, 0x01);
    outportb(0x21, 0x0);
    outportb(0xA1, 0x0);
}

The code for outportb() is as follows, but I already have a clear grasp of what its doing:

void outPortB(unsigned short port, unsigned char data)
{
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (data));
}

I should mention that this is on x86 architecture in protected mode. This source code works fine and I understand what it does, but I don't understand how it does it. Can someone explain to me what's going on here, so that in case I need to expand on this I will know what I'm doing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

变身佩奇 2024-07-15 02:15:38

outb 类似,写入硬件IO端口。 基本上,与设备通信有两个主要选项。 您可以将设备映射到内存或 IO 端口。

至于这段代码是如何工作的,我会为你评论一下:

ICW代表“初始化命令词”

outportb(0x20, 0x11); /* write ICW1 to PICM, we are gonna write commands to PICM */
outportb(0xA0, 0x11); /* write ICW1 to PICS, we are gonna write commands to PICS */

outportb(0x21, 0x20); /* remap PICM to 0x20 (32 decimal) */
outportb(0xA1, 0x28); /* remap PICS to 0x28 (40 decimal) */

outportb(0x21, 0x04); /* IRQ2 -> connection to slave */ 
outportb(0xA1, 0x02);

outportb(0x21, 0x01); /* write ICW4 to PICM, we are gonna write commands to PICM */
outportb(0xA1, 0x01); /* write ICW4 to PICS, we are gonna write commands to PICS */

outportb(0x21, 0x0); /* enable all IRQs on PICM */
outportb(0xA1, 0x0); /* enable all IRQs on PICS */

希望这有帮助

欢迎来到操作系统开发的世界:)我还建议你访问:http://forum.osdev.org/,对于新的业余爱好操作系统开发人员来说,这是一个宝贵的资源。

outb and similar, write to hardware IO ports. Basically, there are 2 primary options for communicating with a device. You can have the device mapped to memory or IO ports.

As for how this code works, i'll comment it for you:

ICW stands for "Initialization Commands Words"

outportb(0x20, 0x11); /* write ICW1 to PICM, we are gonna write commands to PICM */
outportb(0xA0, 0x11); /* write ICW1 to PICS, we are gonna write commands to PICS */

outportb(0x21, 0x20); /* remap PICM to 0x20 (32 decimal) */
outportb(0xA1, 0x28); /* remap PICS to 0x28 (40 decimal) */

outportb(0x21, 0x04); /* IRQ2 -> connection to slave */ 
outportb(0xA1, 0x02);

outportb(0x21, 0x01); /* write ICW4 to PICM, we are gonna write commands to PICM */
outportb(0xA1, 0x01); /* write ICW4 to PICS, we are gonna write commands to PICS */

outportb(0x21, 0x0); /* enable all IRQs on PICM */
outportb(0xA1, 0x0); /* enable all IRQs on PICS */

hope this helps

Welcome to the world of OS dev :) I also recommend that you visit: http://forum.osdev.org/, it is an invaluable resource for a new hobby OS developer.

攀登最高峰 2024-07-15 02:15:38

简单的答案是,在保护模式下,第一个可编程中断控制器使用的中断是保护模式异常,这意味着它们必须重新映射。

令人高兴的答案是,只有第一个 PIC 需要重新映射(第二个 PIC 的重新映射只是为了方便,因为它从 int 70h 开始)。
这是原始 AT BIOS 的引用。

INTA00    equ  020h        ; 8259 port
INTA01    equ  021h        ; 8259 port
INTB00    equ  0A0h        ; 2nd 8259
INTB01    equ  0A1h
INT_TYPE  equ  070h        ; start of 8259 interrupt table location

;---------------------------------------------------------
;    re-initialize the 8259 interrupt #1 controller chip :
;---------------------------------------------------------
  mov  al, 11h             ; icw1 - edge, master, icw4
  out  INTA00,al
  jmp  $+2                 ; wait state for i/o
  mov  al, 8               ; setup icw2 - int type 8 (8-f)
  out  INTA01, al
  jmp  $+2
  mov  al, 4               ; setup icw3 - master lv 2
  out  INTA01, al
  jmp  $+2
  mov  al, 1               ; setup icw4 - master, 8086 mode
  out  INTA01, al
  jmp  $+2
  mov  al, 0FFh            ; mask all ints. off
  out  INTA01, al          ; (video routine enables interrupts)
;---------------------------------------------------------
;    re-initialize the 8259 interrupt #2 controller chip  :
;---------------------------------------------------------
  mov  al, 11h             ; icw1 - edge, slave icw4
  out  INTB00, al
  jmp  $+2
  mov  al, INT_TYPE        ; setup icw2 - int type 70 (70-7f)
  out  INTB01, al
  mov  al, 2               ; setup icw3 - slave lv 2
  jmp  $+2
  out  INTB01, al
  jmp  $+2
  mov  al, 1               ; setup icw4 - 8086 mode, slave
  out  INTB01, al
  jmp  $+2
  mov  al, 0FFh            ; mask all ints. off
  out  INTB01, al
;--------------------------------------------------------------------------------

技术参考 AT BIOS (c) 1984 IBM

注:

jmp $+2 ; 当前 PC 不需要 I/O 等待状态。

icw1 清除中断屏蔽寄存器,从而启用该 PIC 上的中断。

8259A芯片早已不复存在,但编程接口仍在使用。
8259A 可编程中断控制器

The simple answer is that in protected mode the interrupts used by the 1st Programmable Interrupt Controller are protected mode exceptions, which means that they have to be remapped.

The happy answer is that only the first PIC needs to be remapped ( the remapping of the second is only for convenience since it begins at int 70h).
Here's a quote from the original AT BIOS.

INTA00    equ  020h        ; 8259 port
INTA01    equ  021h        ; 8259 port
INTB00    equ  0A0h        ; 2nd 8259
INTB01    equ  0A1h
INT_TYPE  equ  070h        ; start of 8259 interrupt table location

;---------------------------------------------------------
;    re-initialize the 8259 interrupt #1 controller chip :
;---------------------------------------------------------
  mov  al, 11h             ; icw1 - edge, master, icw4
  out  INTA00,al
  jmp  $+2                 ; wait state for i/o
  mov  al, 8               ; setup icw2 - int type 8 (8-f)
  out  INTA01, al
  jmp  $+2
  mov  al, 4               ; setup icw3 - master lv 2
  out  INTA01, al
  jmp  $+2
  mov  al, 1               ; setup icw4 - master, 8086 mode
  out  INTA01, al
  jmp  $+2
  mov  al, 0FFh            ; mask all ints. off
  out  INTA01, al          ; (video routine enables interrupts)
;---------------------------------------------------------
;    re-initialize the 8259 interrupt #2 controller chip  :
;---------------------------------------------------------
  mov  al, 11h             ; icw1 - edge, slave icw4
  out  INTB00, al
  jmp  $+2
  mov  al, INT_TYPE        ; setup icw2 - int type 70 (70-7f)
  out  INTB01, al
  mov  al, 2               ; setup icw3 - slave lv 2
  jmp  $+2
  out  INTB01, al
  jmp  $+2
  mov  al, 1               ; setup icw4 - 8086 mode, slave
  out  INTB01, al
  jmp  $+2
  mov  al, 0FFh            ; mask all ints. off
  out  INTB01, al
;--------------------------------------------------------------------------------

Technical Reference AT BIOS (c) 1984 IBM

Note:

The jmp $+2 ; wait state for i/o is not required on a current PC.

The icw1 clears the interrupt mask register, which enables the interrupts on that PIC.

The 8259A chip is long since gone but the programming interface is still used.
8259A Programmable Interrupt Controller

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文