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 |