Page 1 of 1

Changing IRS's for a specified interrupt

Posted: Sat Dec 13, 2003 12:49 pm
by xxchrisxx
I am not sure how to implement a way to set the appropriate ISR for specified interrupts and exceptions. I am no assembly expert, so I was wondering whats the simplest way to implement this.

Re:Changing IRS's for a specified interrupt

Posted: Sat Dec 13, 2003 1:19 pm
by Ozguxxx
In pmode:
Set up an appropriate IDT with enough entries. For more information check 80386 programmers reference manual.
Im rmode:
Bios interrupts are set by default but if you want to hook your own interrupts then check a 8086 book to see how ivt entries are set. OR do google.
Good luck.

Re:Changing IRS's for a specified interrupt

Posted: Sat Dec 13, 2003 2:18 pm
by Neo
you could write a function to load interrupts which acepts arguments as the ISR handler address, settings(user/kernel etc..) and the int no and then update the IDT using this

Re:Changing IRS's for a specified interrupt

Posted: Sat Dec 13, 2003 3:46 pm
by xxchrisxx
Hmm well I have this function that changes IRS's from the Flick OS.

Code: Select all

; boot/setup.asm
; Copyright (C) 2002 by Alexander Blessing <[email protected]>
;
; sets up the ISRs for various interrupts

[BITS 32]   ; protected mode
[global changeISR]   ; called by an extern function
[extern idt]   ; the IDT table

; this function changes the Interrupt Service Routine 
; for a specified interrupt
changeISR:
   push ebx   ; save
   push edx   ; registers
   push eax   ; that will
   push ebp   ; be changed

   mov ebp, esp
   mov ebx, [ss:ebp + 20]   ; interrupt number
   mov eax, [ss:ebp + 24]   ; interrupt handler
   mov edx, idt   ; idt location

   shl ebx, 3   ; need to multiply by 8
   mov [edx + ebx], ax   ; low offset
   shr eax, 16
   mov [edx + ebx + 6], ax   ; high offset

   pop ebp   ; restore
   pop eax   ; registers
   pop edx   ; that
   pop ebx   ; were changed   
   
   ret   ; return to caller
Would anybody be able to breifly explain it?

Re:Changing IRS's for a specified interrupt

Posted: Sat Dec 13, 2003 4:12 pm
by Curufir

Code: Select all

; boot/setup.asm
; Copyright (C) 2002 by Alexander Blessing <[email protected]>
;
; sets up the ISRs for various interrupts

[BITS 32]???; protected mode
[global changeISR]???; called by an extern function
[extern idt]???; the IDT table

; this function changes the Interrupt Service Routine 
; for a specified interrupt
changeISR:
???push ebx???; save
???push edx???; registers
???push eax???; that will
???push ebp???; be changed

???mov ebp, esp
Standard beginning, store the registers that will be used throughout the function, the 'mov ebp, esp' instruction is to maintain compatibility with standard C afaik. The global and extern pre-processor instructions are there to export the relevant linking information when assembling to object format.

Code: Select all

???mov ebx, [ss:ebp + 20]???; interrupt number
???mov eax, [ss:ebp + 24]???; interrupt handler
???mov edx, idt???; idt location
Some assumptions have to be made here since you've given only the assembly routine. The fairly obvious one is that the variables to the function are being passed on the stack and that they consist of one 4 byte integer representing the number of the idt entry to alter (ebx), one 4 byte integer representing a pointer to the entry point of the new ISR (eax), and that the external variable idt points to the base of the idt.

Code: Select all

???shl ebx, 3???; need to multiply by 8
Each idt entry is 8 bytes long, so to determine the memory address of the idt entry to change you need to use:

[pre](idt base address) + (idt entry)*8[/pre]
This presupposes that DS for both the calling code and IDT have the same base address.

Code: Select all

   mov [edx + ebx], ax   ; low offset
???shr eax, 16
???mov [edx + ebx + 6], ax???; high offset
idt entries have the entry point of the ISR split into high and low words (For backwards compatibility purposes afaik). These two moves simply perform that split and alter the idt entry to point to the entry point of the new ISR.

Code: Select all

???pop ebp???; restore
???pop eax???; registers
???pop edx???; that
???pop ebx???; were changed???
???
???ret???; return to caller
Clean up and return. Since eax is unchanged I'm guessing the return type of this function in C is void.

Note:
I can't remember offhand if the IDT gets cached in the TLBs, if it does you'll need to invalidate the cached entries in a paged memory environment before the new IDT is used. Perhaps one of the gurus could answer that question.

Re:Changing IRS's for a specified interrupt

Posted: Sat Dec 13, 2003 8:31 pm
by xxchrisxx
Thanks, I understand that alot better now. One more question though; is that the most common way to change ISR's?

Re:Changing IRS's for a specified interrupt

Posted: Sat Dec 13, 2003 8:49 pm
by Curufir
xxchrisxx wrote: Thanks, I understand that alot better now. One more question though; is that the most common way to change ISR's?
You have 2, and only 2 possibilities for changing an ISR.
  • Change address of the entry point indicated in the IDT
  • Have your code replace that which appears at the existing entry point
Which you use is entirely up to you, although IMO altering the IDT itself is the more flexible method.

Re:Changing IRS's for a specified interrupt

Posted: Sun Dec 14, 2003 3:53 am
by Candy
Curufir wrote:
xxchrisxx wrote: Thanks, I understand that alot better now. One more question though; is that the most common way to change ISR's?
You have 2, and only 2 possibilities for changing an ISR.
  • Change address of the entry point indicated in the IDT
  • Have your code replace that which appears at the existing entry point
Which you use is entirely up to you, although IMO altering the IDT itself is the more flexible method.
Strictly speaking you could also alter the GDT so the code pointer points to a different section of code, which is not changing the IDT entry nor changing the code which appears at the existing point (since you do not modify that which is there) :P

Re:Changing IRS's for a specified interrupt

Posted: Sun Dec 14, 2003 7:14 am
by Curufir
Candy wrote: Strictly speaking you could also alter the GDT so the code pointer points to a different section of code, which is not changing the IDT entry nor changing the code which appears at the existing point (since you do not modify that which is there) :P
Err, nope, changing the GDT base address IS changing the code that appears at the address indicated by the IDT, that's why I specifically used the word "appears" ;).