Search code examples
assemblyx86kernelosdevirq

Setting up IRQ mapping


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?


Solution

  • 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.