Remapping the PICs is quite easy. It is done in the initialization of the PICs. We must initialize the PICs *before* using them, and this is done by sending some ICW (Initialization Commands Words) to the PICs controller. The procedure is as follow:
- send ICW1 to PIC1 (20h) and PIC2 (A0h)
- send ICW2 to 21h for the first PIC and 0A1h for the second PIC
- send ICW3 to 21h for the first PIC and 0A1h for the second PIC
- finally, send ICW4 to 21h for the first PIC and 0A1h for the second PIC
ICW2 is the thing that is important for us. It tells the PICs where to map IRQ0 and IRQ8.
ICW3 is used for telling the PICs which IRQ to use for the communication between each other
ICW4 is used for telling that we are working in a 80x86 architecture and if the interruption is handled
automatically or if it needs help from software.
May seem difficult, but it's not. If you want to understand it exactly, visit this page. But now, let's look at a
code example. This code will initialize the PICs, remap them and disable all IRQs:
#define PIC1 0x20
#define PIC2 0xA0
#define ICW1 0x11
#define ICW4 0x01
/* init_pics()
* init the PICs and remap them
*/
void init_pics(int pic1, int pic2)
{
/* send ICW1 */
outb(PIC1, ICW1);
outb(PIC2, ICW1);
/* send ICW2 */
outb(PIC1 + 1, pic1); /* remap */
outb(PIC2 + 1, pic2); /* pics */
/* send ICW3 */
outb(PIC1 + 1, 4); /* IRQ2 -> connection to slave */
outb(PIC2 + 1, 2);
/* send ICW4 */
outb(PIC1 + 1, ICW4);
outb(PIC2 + 1, ICW4);
/* disable all IRQs */
outb(PIC1 + 1, 0xFF);
So, this call will remap the PICs so that IRQ0 starts at 0x20 and IRQ8 starts at 0x28:
init_pics(0x20, 0x28);
Summary
That's it - I hope you understood the basic things, and take a look at the link I just gave you above. You will
need some knowledge of programming the PICs as a OS developer, so do not think it's not important.
best regards,
Alexander Blessing
Tidak ada komentar:
Posting Komentar