Low Level Interrupt Handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 

Some more doubts about lowest level of Interrupt handling code.

 

-          Read on http://www.beyondlogic.org/interrupts/interupt.htm that when ever the interrupt occurs the PIC reports it to CPU. On average the system have two PICs, if the an interrupt is being reported to CPU, the 5 most significant bits (MSB) on address bus will be 00001 (in case PIC 1 is reporting this interrupt) or 01110 (in case PIC 2 is reporting the interrupt) and the 3 least significant bits (LSB) will determine the interrupt line on that particular PIC which exactly is interrupting. For example if interrupt 3 occurs, the number (data) sent to CPU will be 00001011 (0x0B), which should exactly be the address in IDT (Interrupt Descriptor Table), where the pointer to the ISR is placed.

 

a) Now my question is, that as I know IDT should start at 0x00 physical address (it can also start at other place also, but “idtr” register of CPU should point to it), but if we check the address of “idt_table” in System.map file, we see that it has “c036f000” as address. Is this address a physical address, if it is then why this discrepancy. If this is the physical base address of IDT, where in kernel are we setting the “idtr” register, so CPU has reference to IDT.

 

b) As we can see in trap.c file (http://lxr.linux.no/source/arch/x86_64/kernel/traps.c?v=2.4.21#L49), idt_table is defined as a array of structures with 256 elements and if we see the definition of that structure (gate_struct), it occupies 16 bytes, that means each element in “idt_table” array is of 16 bytes, so idt_table is of 16 * 256 bytes, i.e starting physical 4096 bytes of memory. But according to my knowledge and what I read IDT should not exceed more than 1 MB.

 

c) Read that when CPU receives the IRQ number, it multiplies that number with 4 and picks up the pointer from resulting address. So if we take it like this, if PIC 1 reported interrupt on IRQ 3, then CPU will be getting 00001011 (0x0B) and when CPU will multiply it with 4, it will get 44 physical address, which should be he base of the IDT entry having a pointer to ISR for IRQ 3. Can somebody explain how exactly things work in terms of bits. How CPU exactly interprets the IRQ number it receives from PIC.

 

d) As Intel CPU multiplies the IRQ number (which it receives from PIC) with 4 (as entry in IDT should be of 4 bytes), why linux IDT entries are of 16 bytes. Don’t they corrupt the CPU calculations for getting the actual ISR address form IDT entry ?

 

e) Taking an example of IRQ 3, if 00001011 (0x0B) is the actual bit string CPU receives for IRQ 3, then how does CPU comes to know the actual IRQ number like 3, in kernel I did not see any code which interprets the received bit string to actual IRQ number. Where this conversion is done ?

 

Please if you know some link to good article which can tell how CPU interprets the IRQ number received from PIC and map it to the IDT entry index.

 

Hope you all are not bored of my question related to low level interrupts …….

 

Some sources I referred in Linux Kernel:

http://lxr.linux.no/source/arch/i386/kernel/i8259.c?v=2.4.21#L38

http://lxr.linux.no/source/arch/i386/kernel/i8259.c?v=2.4.21#L100

http://lxr.linux.no/source/arch/i386/kernel/i8259.c?v=2.4.21#L453

http://lxr.linux.no/source/arch/i386/kernel/traps.c?v=2.4.21#L814

http://lxr.linux.no/source/arch/x86_64/kernel/traps.c?v=2.4.21#L49

http://lxr.linux.no/source/include/asm-x86_64/desc.h?v=2.4.21#L23

 

Regards,

Gaurav

 


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux