IDT Loading in C
IDT Loading in C
In my previous OSes I've always loaded the IDT from assembly and routed all the ints through one global handler which sorted them out but this time I'd like to use the IDT through C and my code doesn't work. I think I've loaded my IDT right because the code doesn't reboot when I leave my IRQ0 handler blank. I know you have to push everything and then pop it and my old assembly code did this fine but whenever I try and transfer it into inline it doesn't work. I think this is down to my lack of experience with AT&T. With the -masm=intel option described in another post I could leave the operands the "right" way round and leave off the % on the registers couldn't I. I'll try that now. Any other ideas or example code?
Thanks
Pete
Thanks
Pete
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:IDT Loading in C
to be honest, i never dared to move my IDT setup code to C because of the kind of reasons you're evoking.
Having inline assembly for ISR prolog & epilog is not (imho) a good idea at all, because you cannot prevent the compiler to add its *own* prolog/epilog and you cannot (afaik) control what's put in it...
this means if you do something like
the compiler may be issuing
which is obviously wrong :-p
note that according to "info gcc, optimize options", you could do
Having inline assembly for ISR prolog & epilog is not (imho) a good idea at all, because you cannot prevent the compiler to add its *own* prolog/epilog and you cannot (afaik) control what's put in it...
this means if you do something like
Code: Select all
isr_timer() {
asm("pushad;push %%ds; push %%es");
kprint("*clock*\n");
outb(0x20,0x20);
asm("pop %%es; pop %%ds; popad");
asm("iretd");
}
Code: Select all
isr_timer:
push ebp
mov ebp,esp
pushad
....
popad
iretd
mov esp,ebp
pop ebp
ret
note that according to "info gcc, optimize options", you could do
and hope it will solve your problem. Your ISR may not have any argument or local variable if you want that trick to work (imho -- never tried) and it sounds *very* hackish to my limited senses ... but if you really want to give it a try ...-fomit-frame-pointer'
Don't keep the frame pointer in a register for functions that
don't need one. This avoids the instructions to save, set up and
restore frame pointers; it also makes an extra register available
in many functions. *It also makes debugging impossible on some
machines.*
Re:IDT Loading in C
The reason I've switched is that I need to have the task scheduler as the real ISR. Before I had a NASM macro which I used to make all the stubs which did all the pushing, poping,etc and then pushed the INT number onto the stack and called a generic C function int_hand(int intno);. But now with the Page Fault Handler, Task Scheduler etc. I need to go direct.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:IDT Loading in C
why so ?? the "page fault" can be processed like any other interrupt (i do it) and the task switching (even software stack-switch) can be handled by a "stack_switc()" function called from the C-based ISR handler rather than relying on some dark magic performed by the stub (like expecting the handler to return the new ESP value or something like this ...)
Re:IDT Loading in C
The way I want to do task switching is quicker because it doesn't store everything. Just the ESP. On entering the ISR it will push everything to the stack and then store the ESP value. Then it will restore the ESP value for a different task and pop everything off the stack.
For more info read my OS Plans thread.
Pete
For more info read my OS Plans thread.
Pete
Re:IDT Loading in C
Ok I've transfered it back to assembly but as I don't want them all going through the same function (3 different handlers - exceptions, irqs and scheduler) I've had to change it a bit. And it doesn't work yet doesn't crash. I think I've got the entries a bit out of place by one but I'm not sure. I have attached the assembly file (NASM). Please could someone check my numbers. AFAIK there are 32 exceptions 0->31, 16 IRQs which I want mapped straight after the exceptions 32->48, but the task switcher takes IRQ0 (32). All numbers in decimal
Any help would be much appreciated.
Thanks
Pete
[attachment deleted by admin]
Any help would be much appreciated.
Thanks
Pete
[attachment deleted by admin]
Re:IDT Loading in C
You can use a macro to automatically set up the stub and wrap your C handler.
Code: Select all
/* eg. for a non-errorcode exception handler */
#define END_EXC(func) \
void excstub_##func(void); \
asm(".text\n" \
".globl excstub_" #func "\n" \
"excstub_" #func ":\n" \
" pusha\n" \
" call " #func "\n" \
" popa\n" \
" iret")
/* then when define your ISR... */
void exception0(void)
{
kprintf("Divide by zero.");
} END_EXC(exception0);
/* when you set the IDT entry, every handler's stub name is prefixed by 'excstub_' */
set_idt_entry(0, excstub_exception0);
Re:IDT Loading in C
To be very honest, as far as I have seen (GCC 2.95.3 and 3.1/3.2) they all use push ebp; mov ebp, esp ....... leave; ret to start/leave a function. If you could replace the leave/ret with a leave/iret you would be all set. Because dead code is no real concern, just add the leave/iret before the leave/ret.
In result, before compilation:
and after compilation:
which, at least in my case, has worked each time I tried it.
In result, before compilation:
Code: Select all
int bla() {
// something
i++;
asm ("leave; iret");
}
Code: Select all
bla:
push %ebp
mov %esp, %ebp
; do the i++ thing
leave
iret
leave
ret
Re:IDT Loading in C
Ok it was no bug with the IDT but with my test code.
Why doesn't:-
work for making the top left character rotate, when
works perfectly?
Pete
Why doesn't:-
Code: Select all
while(1)
*vidmem++;
Code: Select all
char temp;
while(1){
temp++;
*vidmem = temp;
}
Pete
Re:IDT Loading in C
try using (*vidmem)++. The ++ operator has precedence over the * operator
Re:IDT Loading in C
...that's why you should always use parantheses in compound statements, even if you (think you) are sure about operator precedence. Helps with reading, too.
Every good solution is obvious once you've found it.