For OS devers who've completed 'em
For OS devers who've completed 'em
I just wanted to know you opinion on this ISR dilemma i face. If you were going to do this how would you have done it in ASM or in C/C++ ?
Re:For OS devers who've completed 'em
The best approach is to write your handlers in assembly language using either gas(AT&T syntax) or nasm(Intel syntax) and then write the actual code for the handler be it a exception or an actual interrupt in C/C++.
Hope this helps.
Hope this helps.
Re:For OS devers who've completed 'em
Its probably easier if you can do the meat of your ISR's in C (presuming you know C reasonably well.) You'll still end up requiring a bit of asm to preserve registers and do an IRET on returning from the interrupt. You can use this assembly stub to wrap your real C handler which will do the actual interrupt-specific processing, e.g.,
Code: Select all
void kbasm(void);
__asm__
(
".text\n"
".globl kbasm\n"
"kbasm:\n"
" pusha\n"
" call kbhandler\n"
" popa\n"
" iret\n"
);
void kbhandler(void)
{
char ch = inb(0x60);
outb(0x20, 0x20);
}
...
set_idt_entry(0x21, (unsigned)kbasm);
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:For OS devers who've completed 'em
One could even automate that process:
so that you can later use
Code: Select all
#define interrupt(name) \
void name##_handler(void);
__asm__(".text\n"\
".globl" #name "\n"\
#name ":\n"\
SAVE_CPU_STATE\
"call " #name "_handler\n"\
RESTORE_CPU_STATE\
"iret\n");\
void name##_handler(void)
Code: Select all
interrupt(keyboard)
{
// do your keyboard stuff here
}
interrupt(timer)
{
// do your timer stuff here
}
install_irqs()
{
install_irq(0x20,timer);
install_irq(0x21,keyboard);
}
Re:For OS devers who've completed 'em
I'm using an assembly handler to get the IRQ and put the IRQ# on the stack, then I'm calling a C function which uses this #.
I have a static ISR-chained-list array : one list per IRQ, so my C function is calling every valid ISR of the corresponding list.
This makes IRQ sharing very easy : for each device, just add its ISR in the correct chained list.
This is also the way Linux kernels (at least until v2.4.20) work.
I have a static ISR-chained-list array : one list per IRQ, so my C function is calling every valid ISR of the corresponding list.
This makes IRQ sharing very easy : for each device, just add its ISR in the correct chained list.
This is also the way Linux kernels (at least until v2.4.20) work.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:For OS devers who've completed 'em
Yup. That's imho the smartest way to do it. Clicker works that way and also allow handlers to inform the "chain manager" whether they could successfully handle the IRQ or if the chain should be explored further...
Re:For OS devers who've completed 'em
That a good idea not to look for further ISR if the IRQ has already been managed, although there's generally not many ISR per IRQs. I think 2, maybe 3, ISR/IRQ is an accepable maximum on common computers
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:For OS devers who've completed 'em
well, that's probably also because i decided to take advantage on this as a design template. For instance, when a page fault occur, the default handler will panic the system. You can install a kind of "filter" that can recover errors by killing the faulty process, then another filter that catch "copy on write" errors or "allocate a new zero page", etc. Finally, you design a complex service as a chain of basic blocks.
The same kind of behaviour can be used for keyboard manipulation: first catch 'system escape sequences' like CTRL+ALT+printscreen, behind which you'll have shift, ctrl and other "modifiers" catcher, and finally, just defer alphanumeric keys to the scancode -> ascii/unicode/whatever translator.
It was also handy for the clock, because some filter can act as frequency divisors (deciding to defer or not the signal based on the value of an internal counter)
The same kind of behaviour can be used for keyboard manipulation: first catch 'system escape sequences' like CTRL+ALT+printscreen, behind which you'll have shift, ctrl and other "modifiers" catcher, and finally, just defer alphanumeric keys to the scancode -> ascii/unicode/whatever translator.
It was also handy for the clock, because some filter can act as frequency divisors (deciding to defer or not the signal based on the value of an internal counter)
Re:For OS devers who've completed 'em
This is a very interesting way to handle things. I will remember that for my own OS ;D