我正在学习如何设置内核的几个教程和参考资料。我在一个没有解释它的教程中遇到了一些不熟悉的代码。这是我告诉的代码将16 IRQs (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架构上。这个源代码工作正常,我理解它的作用,但我不明白它是如何做到的。有人可以向我解释这里发生了什么,所以如果我需要扩展这个,我会知道我在做什么吗?
答案 0 :(得分:12)
outb
和类似的,写入硬件IO端口。基本上,与设备通信有2个主要选项。您可以将设备映射到内存或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 */
希望这会有所帮助
欢迎来到OS开发世界:)我还建议您访问:http://forum.osdev.org/,它是新爱好操作系统开发人员的宝贵资源。
答案 1 :(得分:1)
简单的答案是,在保护模式下,第一个可编程中断控制器使用的中断是保护模式异常,这意味着它们必须重新映射。
快乐的答案是只需要重新映射第一个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
注意:
当前PC上不需要jmp $+2 ; wait state for i/o
。
icw1
清除中断屏蔽寄存器,该寄存器启用该PIC上的中断。
8259A芯片早已消失,但仍在使用编程接口。 8259A Programmable Interrupt Controller