Page 1 of 2
system reboots when executing an int inside the before creat
Posted: Sun Jul 20, 2003 7:28 am
by Freanan(who cannot login)
just tried to build an idt, loadt it with lidt,
insert an interrupt, and call this interrupt with int n.
My system reboots at the point of the int-instruction.
(i tried it out with the int outcommented and it did not reboot then, so it must be the int).
So either my idt is completely false or i do something wrong installing the interrupt vector.
But i cannot imagine where there can be a bug, for i use pretty much the same code as several other kernels i found on the web...
Please help me with that - thank you.
Here is my kmain(stripped off the text-output to keep it short):
Code: Select all
void kmain()
{
initIDT(); //setup an idt
setinteruptvector(9,kbhandler,0x08,0xEE00);//install an interupt vector -later it will be the keyboard handler
asm("int $9");//call the interupt
while(true);//hang
};
//This is my struct for idt entries:
typedef struct interrupt_vector
{
word handleroffset_l;
word segmentselector;
word properties;
word handleroffset_h;
}intvect;
This is the stuff that does the work:
Code: Select all
intvect* idt; //Interupt Descriptor Table (global)
inline void initIDT()
{
unsigned long idtinfo[2]; //this is the info i am going to load into idtr
int i;
for(i=0; i<256; i++)setinteruptvector(i,emptyint,0x08,0xEE00);//fill idt with empty ints
asm("pushfl");//disable ints while loading idt
idtinfo[0]=(256*(sizeof(intvect)-1))<<16; //size of idt
//(i also tried it without '<<16', because some sources do it and others not
// i also wonder why one should do that '<<16')
idtinfo[1]=(unsigned long)idt; //idt adress
__asm__ __volatile__ ("lidt (%0)": :"p" (((char *) idtinfo)+2));//load the idt-info stuff
asm("popfl"); //re-enable ints
};
void setinteruptvector(int tableindex, void *hoffset, word selector, word properties)
//I also tried void(*hoffset)() instead of void* hoffset
//(and when calling: &kbhandler instead of kbhandler)
//i have seen both and i think in the end it does the same...(?)
{
idt[tableindex].segmentselector=selector;
idt[tableindex].properties=properties;
idt[tableindex].handleroffset_l=(unsigned short)(((unsigned long)hoffset) & 0xFFFF);
idt[tableindex].handleroffset_h=(unsigned short)(((unsigned long)hoffset) >>16);
};
And the two interrupt handlers:
Code: Select all
void kbhandler()
{
//asm ("cli \n");
kprint("Keyboard input or Coprocessor Overrun Exception!",7);
while(true);
//asm("sti \n" "iret \n");
};
void emptyint()
{
//asm ("cli \n");
kprint("Empty Interupt!",7);
while(true);
//asm("sti \n" "iret \n");
};
//I also tried it with the asm statements not outcommented and the while(true);
//outcommented - same result
Re:system reboots when executing an int inside the before cr
Posted: Sun Jul 20, 2003 11:01 am
by Freanan
sorry for the messed up quotes-stuff - but i had to write on another pc and could not login, so i cannot format my text properly
i hope this does not keep anybody from helping me
Re:system reboots when executing an int inside the before cr
Posted: Mon Jul 21, 2003 4:00 am
by Pype.Clicker
first of all, you should know that INT 9 isn't free for keyboard in protected mode. Actually, it is reserved for some exception (x87 overflow)... So you'll eventually have to re-map your hardware interrupts using the PIC (8259a) chip -- see Bona Fide OS Dev tutorials for more info.
second, it's a pretty bad idea to have your "idtinfo" structure as a function-local variable. Local variables are allocated on the stack and their content will be destroyed with the next function call. This means that the processor may find garbage when it'll try to access the IDT (though some processor might cache the content ad thus work anyway)
As for the "<<16", its reason is that the real structure of the IDTR memory location is
Code: Select all
0 16 32 48
+-----+-----+-----+
|limit| base |
+-----+-----+-----+
the "<<16" actually shifts the limit to the highest half-word of idt_info[0], and thus the 6 bytes starting at ((char*)idt_info) are your IDTR location.
It's kind of a workaround to bypass any kind of field-alignment the compiler could try to use...
do *not* use "asm sti" before you do the "iret". "iret" is in charge of restoring the IF flag itself. all it could do is bugging.
Also, as the compiled code actually adds stack-manipulations like "push ebp; mov ebp, esp" at the function start, having "asm iret" in a C function is usually a bad idea...
Finally, you should load GPF exception handler with a valid descriptor so that you get a "Segmentation fault" message if your IDT misbehaves rather than having the CPU rebooting.
Last but not least, debugging your kernel with BOCHS may save time, as it will gives you more comprehensive error messages that what your PC can do before interrupts are working
Re:system reboots when executing an int inside the before cr
Posted: Tue Jul 22, 2003 2:02 am
by Freanan
Thank you Pype.Clicker!
I just put idtinfo before the initIDT function to make it a global variable and
changed the stuff inside the interrupts
kprint('something',7) and an endless loop afterwards.
I also filled thw whole idt with standard-handlers that put out text, to have output instead of rebooting, as you suggested.
There is just one problem:
ld does not find my idtinfo variable and says 'undefined reference to _idtinfo'!
Re:system reboots when executing an int inside the before cr
Posted: Tue Jul 22, 2003 5:07 am
by Pype.Clicker
did you include the "BSS" section in your linker script ? as idtinfo is now an uninitialized global variable, that's where it should be...
Re:system reboots when executing an int inside the before cr
Posted: Wed Jul 23, 2003 4:28 am
by Freanan
I do not use any linker script.
Perhaps i should do that :-[!
Is there a good manual how to use them online?
Re:system reboots when executing an int inside the before cr
Posted: Wed Jul 23, 2003 9:28 am
by Pype.Clicker
i'm not sure, but i think there's none easily googlable. Solar collected all sort of infos about it
here, though.
Re:system reboots when executing an int inside the before cr
Posted: Tue Aug 19, 2003 10:48 am
by Freanan
I just decided to setup idt in assembler.
So there can't be any errors because of messed up linking.
At the moment i just have a kernelfile in assembler, but later i think i'll make an asm-start-routine which sets everything up and calls the c-main-function...
But i still have the same error - when calling an int (i just used int 0x02...) the pc reboots.
So it must be something about my code :'(
Here is my new code:
Code: Select all
[BITS 32]
;main-program
mov byte [0xB8000], "K" ;debug-textoutput
mov byte [0xB8001], 4
lidt [idt_pointer] ;load idtr
mov byte [0xB8002], "!" ;more textoutput
mov byte [0xB8003], 4
int 0x02 ;calling an int
hang:
jmp hang
;interrupt descriptor table
idt:
%rep 0xF ;repeat 16 times the following desc
dw handler ;the adress of the isr
dw 0x08 ;codesegment-selector
db 0xEE ;11101110=EE
db 0 ;empty byte
dw 0 ; that would be the end of the adress
%endrep
idt_end:
;idt data to load into idtr
idt_pointer:
dw idt_end-idt-1 ;size
dd idt ;adress
;standard-isr to test the idt
handler:
mov byte [0xB8002], "I" ;Output
mov byte [0xB8003], 4
hng jmp hng ;and hang
The descriptor i used here i found in some educational kernel about idt-loading. But i think it is strange, that here
only 'handler' and '0' are used as the two parts of the adress, because in all the kernels in c i saw, the adress was shifted to get the first word of the adress...
Please tell me what i did wrong again!
Thank you!
Re:system reboots when executing an int inside the before cr
Posted: Tue Aug 19, 2003 10:54 am
by Therx
The only possible bug I can see is that depending where the kernel is loaded I doubt that the address of handler is 16bit so you'll have to use the second double word at the end.
If you want to look at my code (in colour ;D) it's
here
Hope this helps
Pete
Re:system reboots when executing an int inside the before cr
Posted: Tue Aug 19, 2003 11:34 am
by Freanan
Thank you pete for the link, i'll look if it helps me!
I just realised that there are some errors in my code:
the ':' at 'hng: jmp hng' is missing and it has to be
...
db 0
db 0xEE...
not the other way round...
I also changed the dpl to 0.
But fixing these two errors did not change anything...
Re:system reboots when executing an int inside the before cr
Posted: Tue Aug 19, 2003 2:08 pm
by Pype.Clicker
hmm ... i'm surprised you assembled this without complaints from nasm (which shouldn't like a 32-bits offset "handler" to be stored in a 16-bits place). Chances are that your IDT get screwed up in the building process. Check the hexdump of your kernel to be sure everything is okay ...
Re:system reboots when executing an int inside the before cr
Posted: Wed Aug 20, 2003 3:40 am
by Freanan
That sounds logic...
Is there any possibility to be sure, that it is not messed up?
I tried to do the &-ing and shifting as in all the c-kernels - the operators were also described in the nasm-manual. But then nasm complained that "& and shift operators are only to be used with scalars".
Or i have to tell the assembler that it is supposed to be a word as in 'mov word ...'?
Re:system reboots when executing an int inside the before cr
Posted: Wed Aug 20, 2003 3:45 am
by Pype.Clicker
as i can't remember if base_me and base_hi are close to each other in IDT descriptors - i know they aren't in segment descriptors.
Code: Select all
mov edi, idt_start
.loop:
mov eax,default_irq_handler ;; this could be relocated by the linker if needed
mov [edi+.descriptor_base_lo],ax
shr eax,16
mov [edi+.descriptor_base_me],al
mov [edi+.descriptor_base_hi],ah
add edi,8
cmp edi,idt_end
jb .loop
Re:system reboots when executing an int inside the before cr
Posted: Wed Aug 20, 2003 5:39 am
by Freanan
Following your advise, Pype.Clicker, i looked at my binary with a hexeditor.
Being a complete hobbyist i never learned how to use that thing, but i think it helped me:
I found 8 bytes that were repeated 16 times, so this must be my descriptor:
...A8 00 08 00 00 8E 00 00...
I copied it into this forum-post and put together two bytes were there should be words...:
A800 -my handler adress
0800 -the 0x08, my codesegmentselector
00 -the 0-byte
8E -the flags
0000 -the other part of the handler
So this seems NOT to be messed up, at least if the A800 really is my handleradress...
The start adress of my handler should be 6 bytes (because of the 'idt_pointer')
after the last descriptor. And this location has, according to my editor
indeed the adress A8. So this should be allright.
Or did i get something wrong?
I might also post the whole output of the editor if it helps you helping me..
Re:system reboots when executing an int inside the before cr
Posted: Wed Aug 20, 2003 5:56 am
by Pype.Clicker
at which address do your binary get loaded ?