Interrupts are not working!

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
mangaluve
Member
Member
Posts: 110
Joined: Mon Feb 23, 2009 6:53 am

Interrupts are not working!

Post by mangaluve »

Im having troubles getting interrupts to work. I've followed a tutorial on http://www.jamesmolloy.co.uk/tutorial_h ... 20IDT.html. The problem occurs after kernel-main, when I use STI to enable interrupts. I get weird interrupts as soon as I enable them, and lots of them (interrupt after interrupt) without doing something that should trigger even one of them. This is my kernel code (it starts in kernel.asm, Im fairly positive that my boot loader works)

kernel.asm

Code: Select all

[BITS 32]
[global start]
[extern _k_main]	 ;this is in kernel.c

start:
  call _k_main

  sti			 ;this causes trouble, a large number of interrupt trigger
  hlt
idt.asm

Code: Select all

[GLOBAL _idt_flush]
[GLOBAL _isr_handler]
[extern _isr_c_handler]

_idt_flush:
    mov eax, [esp+4]
    lidt [eax]
    ret

_isr_handler:
    pusha
    push gs
    push fs
    push es
    push ds

    call _isr_c_handler	; Call the C interrupt handler

    pop ds
    pop es
    pop fs
    pop gs
    popa
    iret
kernel.c

Code: Select all

typedef unsigned int   u32int;
typedef          int   s32int;
typedef unsigned short u16int;
typedef          short s16int;
typedef unsigned char  u8int;
typedef          char  s8int;


void k_clear_screen();
void putchar(char c);

int cursor_pos = 0;

extern void isr_handler();

void putchar(char c) {
	char *vidmem = (char *) 0xb8000;
	vidmem[2*cursor_pos + 1] = 0x07;
	vidmem[2* (cursor_pos ++)] = c;
}


struct idt_entry_struct
{
    u16int base_lo;
    u16int sel;
    u8int  always0;
    u8int  flags;
    u16int base_hi;
} __attribute__((packed));
typedef struct idt_entry_struct idt_entry_t;

struct idt_ptr_struct
{
    u16int limit;
    u32int base;
} __attribute__((packed));
typedef struct idt_ptr_struct idt_ptr_t;

idt_entry_t idt_entries[256];
idt_ptr_t   idt_ptr;

static void idt_set_gate(u8int num, u32int base, u16int sel, u8int flags)
{
    idt_entries[num].base_lo = base & 0xFFFF;
    idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
    idt_entries[num].sel     = sel;
    idt_entries[num].always0 = 0;
    idt_entries[num].flags   = flags /* | 0x60 */;
}


static void init_idt()
{
    int i;
    idt_ptr.limit = sizeof(idt_entry_t) * 256 -1;
    idt_ptr.base  = (u32int)&idt_entries;

    for(i = 0; i < 32 ; i++)
    	idt_set_gate(i, (u32int)isr_handler , 0x08, 0x8E);

    idt_flush((u32int)&idt_ptr);
}

void isr_c_handler()
{
	putchar('a');
}


k_main()
{
	k_clear_screen();
	init_idt();
};


void k_clear_screen()
{
	char *vidmem = (char *) 0xb8000;
	unsigned int i = 0;
	while (i < (80* 25* 2 ) ) {
		vidmem[i] = ' ';
		i++;
		vidmem[i] = 0x07;
		i++;
	};
};
Now you would expect no interrupt to be triggered, (unless I trigger it by myself). The interrupt handler isr_c_handler() (which is called from _isr_handler in idt.asm) should thus not print any a:s. But it's printing more than enough to fill the screen. Any help would be appreciated!
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: Interrupts are not working!

Post by yemista »

try "show int" in bochs to see what interrupt it is. Its probably the timer.
User avatar
Troy Martin
Member
Member
Posts: 1686
Joined: Fri Apr 18, 2008 4:40 pm
Location: Langley, Vancouver, BC, Canada
Contact:

Re: Interrupts are not working!

Post by Troy Martin »

Either that or a series of GPFs and other faults.
Image
Image
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I wish I could add more tex
mangaluve
Member
Member
Posts: 110
Joined: Mon Feb 23, 2009 6:53 am

Re: Interrupts are not working!

Post by mangaluve »

Thanks!

How do I use show int int bochs?

I only get One interrupt if I replace the hlt-statement with a hang: jmp hang.. I mean I get PANIC and stuff, different message all the time. Sometime I get GPF:s, but why do they occur?
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: Interrupts are not working!

Post by 01000101 »

in the bochs debugger... type "show int" to see all the interrupts (yours AND the BIOS's startup interrupts).
neonek
Member
Member
Posts: 38
Joined: Thu Aug 28, 2008 1:53 pm
Location: Białystok - Podlasie, Poland

Re: Interrupts are not working!

Post by neonek »

Maybe try cli before you call the main function.
Please correct my English. If you'll find mistake please tell me about it so I can improve my English.
mangaluve
Member
Member
Posts: 110
Joined: Mon Feb 23, 2009 6:53 am

Re: Interrupts are not working!

Post by mangaluve »

Well I have a CLI in my boot loader so it cannot be it. I haven't touched the PIC yet, so timer interrupts shouldnt be enabled?

But it's stranged, I looked at the wiki and used some test-code,

Code: Select all

int_handler:
   mov ax, 010h
   mov gs, ax
   mov dword [gs:0xB8000],') : '
   hlt

idt:
   resd 50*2

idtr:
   dw (50*8)-1
   dd idt

test1:
   lidt [idtr]
   mov eax,int_handler
   mov [idt+49*8],ax
   mov word [idt+49*8+2],08h
   mov word [idt+49*8+4],0x8E00
   shr eax,16
   mov [idt+49*8+6],ax
   int 49
It works fine, it prints a smiley and then halts. But when I try an IRET in my isr, I get errors, something like "CS selector is null":

Code: Select all

int_handler:
   iret

idt:
   resd 50*2

idtr:
   dw (50*8)-1
   dd idt

test1:
   lidt [idtr]
   mov eax,int_handler
   mov [idt+49*8],ax
   mov word [idt+49*8+2],08h
   mov word [idt+49*8+4],0x8E00
   shr eax,16
   mov [idt+49*8+6],ax
   int 49
   hlt
How can this be?

Another thing, after my kernel-main function (in my original code), I just have a HLT. What happens then if an ISR is called and then returned from? will the CPU return and continue on the HLT-statement? What should I have in the "end" of my kernel, in the state where I only wait for interrupts? A jmp $ or a hlt?
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Interrupts are not working!

Post by jal »

mangaluve wrote:I haven't touched the PIC yet, so timer interrupts shouldnt be enabled?
Of course it is, that's what the BIOS does for ya.
It works fine, it prints a smiley and then halts. But when I try an IRET in my isr, I get errors, something like "CS selector is null"
Which usually means you screwed up big time, some place.
How can this be?
We've all experienced strange things. Usually, it's our own fault (bug, anyone?).
Another thing, after my kernel-main function (in my original code), I just have a HLT. What happens then if an ISR is called and then returned from? will the CPU return and continue on the HLT-statement?
I'd say: check the HLT in the Intel manual. It should give you all the information you need (short answer: of course not!).
What should I have in the "end" of my kernel, in the state where I only wait for interrupts? A jmp $ or a hlt?
Both, of course. Although I'm not sure why you would want to do that.


JAL
User avatar
Troy Martin
Member
Member
Posts: 1686
Joined: Fri Apr 18, 2008 4:40 pm
Location: Langley, Vancouver, BC, Canada
Contact:

Re: Interrupts are not working!

Post by Troy Martin »

Question: what interrupt is firing? If its 0Dh or 0Eh, then it's something went wrong in memory (GPF or PF, don't remember which.)
Image
Image
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I wish I could add more tex
mangaluve
Member
Member
Posts: 110
Joined: Mon Feb 23, 2009 6:53 am

Re: Interrupts are not working!

Post by mangaluve »

Thanks for all the replies!

Over the course of the day I've been able to fix the problems. I dont really know what was wrong (I changed some things, then changed back and back and forth) but it's seems to be working now.
Helium
Posts: 2
Joined: Wed Aug 27, 2008 12:36 pm

Re: Interrupts are not working!

Post by Helium »

As far as I know, a simple HLT (while interrupts are enabled) only waits until one interrupt has happend. When the interrupt handler returns, you get to the first instruction after the HLT. I don't know how your code is linked, but probably you'll end up on one of your functions. When the function returns, it takes a "random" value off the stack and you're finally in the nirwana where everything (protection faults, interrupts) may happen.

I'd write the end of the kernel in this way:

Code: Select all

sti
hang:
hlt
jmp hang
The HLT is mainly needed to keep the CPU cool and save power: If you leave it out, the CPU will execute the loop in a very fast rate, but with HLT, it will wait for an interrupt every time before continuing.
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Re: Interrupts are not working!

Post by kmtdk »

well
first:
the cpu waits for an int if the command is hlt.
BUT what if the timer is very low ( = MANY interupt)
then the cpu will do a lot of work.
however if you use "cli", you disable all interupts, and with a "hlt" it will HALT, and dont do anything .
KMT dk
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
frazzledjazz
Posts: 7
Joined: Tue Mar 03, 2009 3:52 pm

Re: Interrupts are not working!

Post by frazzledjazz »

needs to use 'interrupt;' or similar construct, as BTW BP/TP I think v3 and up, as WELL AS FPC 1.x.x uses.

someone needs to correct the wiki.
Borland had support for this WAY back in the day. FPC just keep it.

putchar('a'); is oviously called from some interrupt that keeps getting called. putchar, effective hits int 10, though.[video memory for text mode] my guess would be the timer interrupt is getting called, thus 'putting chars everywhere'.

otherwise the code looks fine. I have similar code in project FPOS, though I'm not the maintainer.

Pascal, I'm sorry....It just reads easier. C 'structs' can be anything. Pascal clearly defines them as pointers, pchars, strings, records, etc... so if I seem outdated it is only your perception, pascal has been kicking since the days of CP/M and I don't think will ever stop. FPC and Lazarus IDE integration just makes it that much more valuable.[effectively VB/VC are obsolete because of it.] GPFs are virtually non-existent in Pascal as well. It ports better [even to MAC] than Python' Tkinter interface, which is C-based. C is losing ground as far as I'm concerned. Just thought I should point that out.

for example:

Procedure KeyboardHandler (r:trealregs); interrupt;

begin
// put something here
end;

without 'interrupt;' it calls 'return' in assembler wrong and supposedly triple-faults.
you need iret, not ret, which C (functions??) usually return with. I'm not sure, but i think there is a way to do this in C, try bran's kernel dev pages.

I am using his methods(Bran's) in pascal, almost as he shows them in C. implementing the interrupts already in use IE: mouse, etc. obviously needs a workaround, but mostly works this way, using his method. I would set up a GPF interrupt, though to be safe. Mario set one up already. It needs to be in the isr file to work properly.Try to keep interrupts SHORT and just let them return to otherwise running code[the proper handler] and let THAT code adjust for what it needs to.

IE: extended key codes on keyboard, actions for mouse buttons, etc.These would be in :

keyboard.pas[or .h and .c]
mouse.pas [or .h or .c]

ETC.

hope this helps.

cli
hlt

in assembler block will HALT the machine, leaving it on.you just told it to 'wait for no interrupts to come'.it does it VERY well.

:-)
Helium
Posts: 2
Joined: Wed Aug 27, 2008 12:36 pm

Re: Interrupts are not working!

Post by Helium »

If you want to test interrupt routines, you must have enabled the interrupts. CLI / HLT will never leave or execute some "nirvana" code, but no interrupt routine will ever be called. The CPU then does really nothing and doesn't react to anything (except NMIs).
Post Reply