Hi. I saw a tutorial in osdever.net about interrupts. In document 3, author creating ISR codes as:
isr0:
pusha
push ds
...
...
pop ds
popa
iret
after this, creating idt items. But all items are same. I don't understand that when interrupt 0 triggered, how the processor understand where is the interrupt 0 code? Is the document wrong? Thanks.
IDT and ISRs
Re:IDT and ISRs
Code: Select all
From what I can see from part3 of that example, he's not using individual isr handlers for each interrupts. The first and last dw for each interrupt together define the offset in the code segment, which he is setting to 0x200000 for all of them. This means that all of those interrupts will cause the same ISR to run.
Typically, you will want to change this offset to be the offset of your ISR that you want executed for a particular interrupt, such as (modified from the FAQ):
isr0:
iret
isr1:
; do soemthing else...
iret
idt0 dw (BASE_OF_SECTION isr0 - $$) & 0xFFFF
dw 0x10
dw 0x8E00
dw (BASE_OF_SECTION isr0 - $$) >> 16
Code: Select all
idt1 dw (BASE_OF_SECTION isr1 - $$) & 0xFFFF
dw 0x10
dw 0x8E00
dw (BASE_OF_SECTION isr1 - $$) >> 16
Re:IDT and ISRs
Hmm. You are saying that;
isr0 base address = idt0 base address
isr1 base address = idt1 base address
isr2 base address = idt2 base address
...
...
...
isr0 base address = idt0 base address
isr1 base address = idt1 base address
isr2 base address = idt2 base address
...
...
...
Re:IDT and ISRs
Each 8-byte entry in the IDT (helpfully ignoring the fact that it's encoded so as to be a nightmare (why is it?)) has a section for the base address of the handler for that interrupt.
When the CPU receives an interrupt, it does:
INT Number * 8 to find the IDT entry for that INT, then decodes the base address and uses that to handle the interrupt.
When the CPU receives an interrupt, it does:
INT Number * 8 to find the IDT entry for that INT, then decodes the base address and uses that to handle the interrupt.
Regards,
Angus [Óengus] 'Midas' Lepper
Angus [Óengus] 'Midas' Lepper
Re:IDT and ISRs
I'm not sure exactly what you mean, but you want:Tolga wrote: Hmm. You are saying that;
isr0 base address = idt0 base address
isr1 base address = idt1 base address
isr2 base address = idt2 base address
...
...
...
"offset" stored in idt0 = offset of isr0
"offset" stored in idt1 = offset of isr1
etc..
Unfortunately the offset is stored split up into two chunks, so you have to wave your hands a little to get it to put the right address in there, but thats the idea. You are saying in each entry in the IDT what code segment to use and what offset in that code segment to jump to when the associated interrupt occurs.
Re:IDT and ISRs
The best way of doing this is via a table of handlers, if you can deal with the tentacles:
handlers.S
The above is written for GAS but it is simpler with NASM's %rep construct.
Now the setup code for the IDT is simply:
handlers.S
The above is written for GAS but it is simpler with NASM's %rep construct.
Now the setup code for the IDT is simply:
Code: Select all
void i_interrupt_gate(uint nr,
uint16_t selector,
uint32_t addr,
uint dpl,
bool is32bit);
Code: Select all
uint addr = (uint) &g_handlers;
/* load interrupt handlers */
for (i = 0; i < NR_IDT_ENTRIES; i++) {
i_interrupt_gate(i, KERNEL_CS, addr, 0, true);
addr += HANDLER_SIZE;
}
Re:IDT and ISRs
Mine is more like this:
To point to these:
This is from Dex4u full source available here:
http://www.dex4u.com/download.htm
To answer your ?, it must times the int number by 8, that why it start at 0 .
Code: Select all
;====================================================;
; Idt. ;
;====================================================;
idt:
;0 interrupt 0h
???dw div_error?????? ; div error
???dw sys_code
???db 0
???db sys_interrupt
???dw 0
;1 interrupt 1h
???dw debug_exception??? ; debug exception
???dw sys_code
???db 0
???db sys_interrupt
???dw 0
;2 interrupt 2h
???dw nmi_interrupt??? ; non maskable interrupt
???dw sys_code
???db 0
???db sys_interrupt
???dw 0
;3 interrupt 3h
???dw int3_trap?????? ; int3 trap
???dw sys_code
???db 0
???db sys_interrupt
???dw 0
;4 interrupt 4h
???dw into_trap?????? ; into trap
???dw sys_code
???db 0
???db sys_interrupt
???dw 0
;5 interrupt 5h
???dw bound_trap?????? ; bound trap
???dw sys_code
???db 0
???db sys_interrupt
???dw 0
;6 interrupt 6h
???dw invalid_instruction??? ; invalid instruction
???dw sys_code
???db 0
???db sys_interrupt
???dw 0
; More here ...................................................
Code: Select all
;----------------------------------------------------;
; unhandled int. ;
;----------------------------------------------------;
unhandled_int:
pushad
push es
push ds
mov ax,8h
???mov es,ax
???mov byte [es:0xB809E], "U"
pop ds
pop es
popad
???iret
;----------------------------------------------------;
; nmi interrupt. ;
;----------------------------------------------------;
nmi_interrupt:
pushad
push es
push ds
mov ax,8h
???mov es,ax
???mov byte [es:0xB809E], "N"
???jmp $
pop ds
pop es
popad
iret
;----------------------------------------------------;
; ;
;----------------------------------------------------;
page_fault:
pushad
push es
push ds
mov ax,8h
???mov es,ax
???mov byte [es:0xB809C], "P"
pop ds
pop es
popad
???iret
;----------------------------------------------------;
; ;
;----------------------------------------------------;
div_error:
pushad
push es
push ds
mov ax,8h
???mov es,ax
???mov byte [es:0xB809C], "D"
pop ds
pop es
popad
???iret
;----------------------------------------------------;
; ;
;----------------------------------------------------;
debug_exception:
pushad
push es
push ds
mov ax,8h
???mov es,ax
???mov byte [es:0xB809C], "d"
pop ds
pop es
popad
???iret
;----------------------------------------------------;
; ;
;----------------------------------------------------;
int3_trap:
pushad
push es
push ds
mov ax,8h
???mov es,ax
???mov byte [es:0xB809C], "3"
pop ds
pop es
popad
???iret
;----------------------------------------------------;
; ;
;----------------------------------------------------;
into_trap:
pushad
push es
push ds
mov ax,8h
???mov es,ax
???mov byte [es:0xB809C], "O"
pop ds
pop es
popad
???iret
http://www.dex4u.com/download.htm
To answer your ?, it must times the int number by 8, that why it start at 0 .