How do I know if my IDT is working? [SOLVED] I think.
How do I know if my IDT is working? [SOLVED] I think.
I have tried a few things to test stuff. I was trying to make a keyboard driver for the kernel to use and was not getting a result. I thought maybe I was missing something or had screwed something up, but I can't seem to do anything after my main program body. I print my current features and whether they are implimented or not, so I show that the video driver is working by printing. I first load the IDT and then say it is working, I run my keyboard driver code and then say that it is working and I tried to test it with a simple print operation when a key is pressed. but nothing happens. I might need to take the data out of the keyboard controller for it to work multiple times but I can't even get it to work once. I tested that the functions upto that point are running and I tested continued program execution by printing a statement after the keyboard functions run. I don't know if it is hung up or not but to test things I wanted to see if my exceptions were working so I made a loop:
int loop=1,a=5,b=5,c;
while(loop)
{
c = a/b;
b--;
vid.write("testing\n");
}
if I leave in the vid.write() command I get a kernel stack fault before I can see any output, if I take it out I get nothing but even if my interrupts were disabled I should get an exception that would result in a triple fault if not handled right???? but if it is handled then I should get the printout from my handler right???
in short I don't know why but none of my interrupt handlers seem to be working, not the exceptions nor the IRQs that I have tried to setup. Any help would be appriciated. I will post code if asked.
int loop=1,a=5,b=5,c;
while(loop)
{
c = a/b;
b--;
vid.write("testing\n");
}
if I leave in the vid.write() command I get a kernel stack fault before I can see any output, if I take it out I get nothing but even if my interrupts were disabled I should get an exception that would result in a triple fault if not handled right???? but if it is handled then I should get the printout from my handler right???
in short I don't know why but none of my interrupt handlers seem to be working, not the exceptions nor the IRQs that I have tried to setup. Any help would be appriciated. I will post code if asked.
Last edited by LordMage on Sun Oct 14, 2007 4:28 am, edited 1 time in total.
Getting back in the game.
Have you enabled interrupts?
Code: Select all
STI
yeah, I didn't at first, big mistake on my part but I caught that and have been working on this for two days. my hangup is that even if I hadn't wouldn't I get a trip fault if I divided by zero. I am not so disappointed that my keyboard isn't working, it's that nothing is working the way I would think it should. If I put to many video writing statements in the code or do them to close together it has a stack fault before the statements even appear to run. but if I divide by zero nothing happens. I am just down right confused. I will post the code in a minute. just have to paste it in
Getting back in the game.
here is the important code for my main.
Main.cpp
Interrupt.cpp
Keyboard.cpp
now for the vid and INT variables for the functions, they are included as externs. so from what I know they should be just linked to the real ones declared in other files.
hopefully this will give a good enough show of what I have to get some help.
Main.cpp
Code: Select all
vid.write("Kernel Level Drivers:\n");
vid.write(" -Video Driver - ver 00.01 "); vid.setcolor(vid.GREEN, vid.BLACK); vid.write("[CHECK]\n"); // If you can see it works
vid.setcolor(vid.LIGHT_GREY, vid.BLACK);
vid.write(" -Loading IDT - ver 00.01 ");
// Loads the Interrupt Descripter Table
INT.enableINT(); // Enable my Interrupts
vid.setcolor(vid.GREEN, vid.BLACK); vid.write("[CHECK]\n");
vid.setcolor(vid.LIGHT_GREY, vid.BLACK);
vid.write(" -Keyboard Driver - ver 00.01 ");
Keyboard KB;
vid.setcolor(vid.RED, vid.BLACK); vid.write("[NOT IMPLEMENTED]\n");
vid.setcolor(vid.LIGHT_GREY, vid.BLACK);
vid.write(" -Memory Management - ver 00.01 "); vid.setcolor(vid.RED, vid.BLACK); vid.write("[NOT IMPLEMENTED]\n");
vid.setcolor(vid.LIGHT_GREY, vid.BLACK);
int Loop = 1;
int a = 5, b = 5,c;
while(Loop)
{
c = a/b;
b--;
//vid.write("test worked");
};
Interrupt.cpp
Code: Select all
void __declspec (naked) default_handler() //Handles any interrupts that have not been set.
{ //This function should never run...
_asm pushad;
vid.write("\nAn unhandled interrupt has occured...\n");
_asm{
popad
iretd
}
}
void __declspec (naked) cpu0()
{
_asm pushad;
vid.write("\nDivide Error...\n");
_asm{
popad
iretd
}
}
Interrupt::Interrupt()
{
int i = 32;
set_pic();
set_exceptions();
for (;i<256;i++) //Fill IDT with default entries.
{
set_ISR(i,default_handler, INT_GATE|BITS_32|PRESENT|RING_3);
}
struct
{
unsigned short size;
unsigned long offset;
} idt_desc;
idt_desc.size=(256*8)-1;
idt_desc.offset=(unsigned long )idt;
lidt(idt_desc); //Load IDT.
current_mask = 0xffff; //disables all interrupts
}
void Interrupt::set_pic() //re-programs the pic
{ //IRQ interrupts start at MASTER_VEC
outportb(PICM, ICW1);
outportb(PICS, ICW1);
outportb(PICMI, MASTER_VEC);
outportb(PICSI, SLAVE_VEC);
outportb(PICMI, 4);
outportb(PICSI, 2);
outportb(PICMI, ICW4);
outportb(PICSI, ICW4);
outportb(PICMI, 0xff);
outportb(PICSI, 0xff);
}
void Interrupt::set_exceptions() //Sets CPU interrupts in the IDT
{
set_ISR(0, cpu0, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(1, cpu1, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(2, cpu2, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(3, cpu3, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(4, cpu4, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(5, cpu5, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(6, cpu6, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(7, cpu7, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(8, cpu8, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(9, cpu9, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(10, cpu10, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(11, cpu11, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(12, cpu12, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(13, cpu13, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(14, cpu14, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(15, cpu15, TRAP_GATE|BITS_32|PRESENT|RING_0);
set_ISR(16, cpu16, TRAP_GATE|BITS_32|PRESENT|RING_0);
for(int i = 17; i < 31; i++)
{ //Sets the reserved CPU interrupts
set_ISR(i, cpu15, TRAP_GATE|BITS_32|PRESENT|RING_0);
}
}
void Interrupt::set_ISR(int intnum, void (*handler)(), unsigned char control)
{
struct addr //Adds interrupt information to the IDT
{
unsigned short offset1;
unsigned short offset2;
};
union
{
void (*function)();
struct addr function_addr;
}intrpt;
intrpt.function = handler;
idt[intnum].selector = CodeSelector;
idt[intnum].dword_count = 0;
idt[intnum].type = control;
idt[intnum].offset1 = intrpt.function_addr.offset1;
idt[intnum].offset2 = intrpt.function_addr.offset2;
}
void Interrupt::IRQ_enable(unsigned short x, void (*handler)(), unsigned char control)
{
current_mask &= ~(1<<x) ; //Zero off the IRQ mask to enable
if (x>=8)
{
current_mask &= ~(1<<2);
set_ISR((x + SLAVE_VEC - 7), handler, control);
}
else //Sets the appropriate interrupt at the same time
{
set_ISR((x + MASTER_VEC), handler, control);
}
outportb(PICMI, (char)current_mask & 0xff);
outportb(PICSI, (char)(current_mask >> 8) & 0xff);
}
Code: Select all
Keyboard::Keyboard()
{
set_KeyMap();
INT.IRQ_enable(2, KBINT, INT_GATE|BITS_32|PRESENT|RING_0);
sendkeys(KB_RESTART);
sendkeys(KB_ENABLE);
//vid.write("\nKeyboard Driver Initiated\n");
};
void Keyboard::sendkeys(unsigned char key)
{
// Send Data to the keyboard controller
WaitToSend();
outportb(0x60, key); // 0x60 is the port for the keyboard controller
}
void Keyboard::WaitToSend() // Wait for keyboard controller to be ready
{
long i = MAX_TRYS_FOR_READY;
while(i-- && (inportb(0x64) & 0x02));
}
void __declspec (naked) KBINT()
{
INT.disableINT();
_asm pushad;
vid.write("You hit a key");
outportb(PICM, EOI);
_asm
{
popad
iret
}
INT.enableINT();
}
void Interrupt::enableINT()
{
_asm sti;
}
void Interrupt::disableINT()
{
_asm cli;
}
hopefully this will give a good enough show of what I have to get some help.
Getting back in the game.
Okay, just shoot me in the head, I realised while making that last post that I did infact accidently put cli in the enable and sti in the disable so that was part of the problem but now I have an entirely different problem. I just get kernel stack faults that happen pretty much as soon as my kernel is loaded. I am guessing the problem now is with the keyboard or interrupt section so I am going to trouble shoot for a sec
alright, it is defintitely the keyboard driver any help would be appreciated
Apparently my original question is still completely valid, I still can't throw an exception when I divide by zero, VMWare just keeps on trucking like 5/0 never happened
alright, it is defintitely the keyboard driver any help would be appreciated
Apparently my original question is still completely valid, I still can't throw an exception when I divide by zero, VMWare just keeps on trucking like 5/0 never happened
Getting back in the game.
If you want assembly, I can supply links and attached files to simple fasm sources, not commented, 32bit protected mode. Works 100% in bochs and real hardware.LordMage wrote:Well, I give, I can't seem to understand what I am not doing so I will just have to wait for neons next tutorial. I sure hope he doesnt take too long.
Always go with some template, will save you bunch of time.
Files attached. Timer & ps2 keyboard work. The keyboard handler, in the state it is now only good for kbd layouts testing.
bin image gets written to the beginning of floppy, has to be 1st floppy drive (Drive A: in Windows) to boot from
http://www.chrysocome.net/rawwrite
you'll need to change path for romimage & vgaromimagein in *.bxrc file
to make things simple put bxrc & bin files in Bochs directory.
Tested with bochs 2.3.5
bin image gets written to the beginning of floppy, has to be 1st floppy drive (Drive A: in Windows) to boot from
http://www.chrysocome.net/rawwrite
you'll need to change path for romimage & vgaromimagein in *.bxrc file
to make things simple put bxrc & bin files in Bochs directory.
Tested with bochs 2.3.5
- Attachments
-
- pmode_ints.zip
- (3.46 KiB) Downloaded 111 times
okay, here is question that I probably shouldn't have to ask but I am going to anyway. If I want to enable the keyboard do I have to enable the timer also? I notice that you did but is it absolutely required? if so, what exactly are you telling the timer with the command you used? Ohh, here is a wierd one. I noticed by using bochs that my OS is failing before succsessully running the kernel. bot not every time. only sometimes and it complains or at least I think it is complaining about something being outside of the r/w range. I will have to try to show exactly what is going on later but I am confused. How could a change to my kernel cause my stage2 loader to error out. at best it is erroring right as it loads the kernel and if that is the case I am still confused because the thing that I am changing is at the end of my kernel program?
Getting back in the game.
Okay, I think I have it working now. I noticed that in my IDT ctor that I was trying to setup my exceptions before I was declareing my IDT so I swapped that around and that seemed to fix something, then I temporarily got rid of all the exceptions except number 13, the GP Fault. Finally I ran it in bochs and got a positive response nothing crashed but instead I got ~="reading from port 0x0064 len 4 is 0xffffffff" so I traced that back to a function that was supposed to be reseting and enabling my keyboard. I don't know whether I wrote the function wrong or if something else is misbehaving so I just commented it out and now the only problem I have is my keyboard buffer gets full and I need to empty it so I can figure that out pretty easily I think. Thanks for the help everyone. That assembly code is what really pushed me over the edge so I could fix everything. Thanks much
Getting back in the game.