Bochs PANIC when trying to print from within an ISR

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
Tosi
Member
Member
Posts: 255
Joined: Tue Jun 15, 2010 9:27 am
Location: Flyover State, United States
Contact:

Bochs PANIC when trying to print from within an ISR

Post by Tosi »

I am working on an Ubuntu 64 system, and I have made sure that GCC was properly configured to produce 32 bit code. I have done OS development before, and have gotten past this point successfully with similar code.

Now, when I try to print a message within my ISR handler, the screen fills with garbage and after a while, Bochs panics with the message "APIC write at unaligned address 0xfee00ffc." However, I am using the old PIC and not the APIC. I have checked and made sure that my text-mode printf code works fine outside of the interrupt handler. I also inserted code to halt the processor inside the exception handler function. It printed fine, and halted, leading me to believe the problem has something to do with the cleanup code after the exception handler. And if I just leave the exception handler as a blank stub function, it returns fine and I can print after it.

As of now, the ISR code is a slightly modified version of the same from JamesM's kernel development tutorials. The part of the code I feel has the problem is this:

Code: Select all

ALIGN 4
isr_stub:
	pushad
	mov ax,ds
	push eax
	mov ax,0x10	; Kernel data segment
	mov ds,ax
	mov es,ax
	mov fs,ax
	mov gs,ax
	mov ss,ax
	
	call exception_handler
	
	pop eax
	mov ds,ax
	mov es,ax
	mov fs,ax
	mov gs,ax
	mov ss,ax
	popad
	add esp,8
	iret
The isr stub is jumped to by each individual isr which pushes an error code and the interrupt number, like in the tutorials. The exception handler just prints out the interrupt number.
The "add esp,8" cleans up the pushed error code and interrupt number.

I plan to optimize the interrupt code later, but I want to get it at least working first. Any help would be appreciated.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Bochs PANIC when trying to print from within an ISR

Post by gerryg400 »

Not sure whether it's related, but I don't think you should be saving and restoring ss.
If a trainstation is where trains stop, what is a workstation ?
Tosi
Member
Member
Posts: 255
Joined: Tue Jun 15, 2010 9:27 am
Location: Flyover State, United States
Contact:

Re: Bochs PANIC when trying to print from within an ISR

Post by Tosi »

I had it without the lines to save SS originally since the processor does that automatically, but they were added in desperation. I get the same results whether I save SS or not.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Bochs PANIC when trying to print from within an ISR

Post by gerryg400 »

Try replacing the

Code: Select all

pop eax
with

Code: Select all

mov $0x10, ax
to see whether your print function is messing up your stack and perhaps overwriting the saved DS.

Edit: Actually on second thoughts that won't be enough because the popa and the iret will still fail.

Can we see your exception_handler function ?
If a trainstation is where trains stop, what is a workstation ?
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: Bochs PANIC when trying to print from within an ISR

Post by bewing »

It seems most likely that your stack has gotten corrupted. In your bochs error log, which register is it that ends up with a value of 0xfee00ffc?
Tosi
Member
Member
Posts: 255
Joined: Tue Jun 15, 2010 9:27 am
Location: Flyover State, United States
Contact:

Re: Bochs PANIC when trying to print from within an ISR

Post by Tosi »

Code: Select all

/* Register structure passed to exception handlers */
typedef struct _regs {
	ulong ds;
	/* Pushed by pushad */
	ulong edi, esi, ebp, esp, ebx, edx, ecx, eax;
	/* Pushed by the ISR handler and maybe the CPU */
	ulong int_no, err_code;
	/* Pushed by the CPU on interrupt */
	ulong user_eip, user_cs, user_flags, user_esp, user_ss;
} regs_t;

...

/* Common isr handler */
void exception_handler(regs_t r) {
	tmode_printf("Received interrupt %#x\n", r.int_no);
}
I don't think it's the exception handler itself, since it just calls a function I've debugged and made sure works.
ESP does seem to be getting corrupted somehow, since it shows up in the error log as "RSP=00000000fee01000." (I am not in long mode, I just compiled bochs with support for it).
Also, this line shows up in the log around 100 times before the panic:

Code: Select all

[(i)e-[CPU0 ] fetch_raw_descriptor: GDT: index (10ef) 21d > limit (27)
EDIT: I figured out what the problem was and I have at least a temporary fix for it. Somehow the pushed DS was getting overwritten, yet nothing else on the stack was. So I just saved the DS in a BSS variable and it worked fine. I'll come back to it later when I get to implementing more specific exception handling (especially for page faults), but now I want to get the timer IRQ set up.
brodeur235
Member
Member
Posts: 86
Joined: Sat Jun 06, 2009 11:55 am

Re: Bochs PANIC when trying to print from within an ISR

Post by brodeur235 »

It looks like you're mishandling your stack frame. When you enter your "isr_stub" procedure the DWORD at esp is your return address if you entered the code label using the call instruction and not jmp. That means when you pushad, push eax, pop eax, popad, the stack is now where it was to begin with; meaning the DWORD at esp is your return address. What it looks like is really happening is you're intending to try and clean up the parameters to the "isr_stub" procedure too soon by adding to the esp, but you're just overwriting the return address and whichever thing was pushed second, the error code, or the interrupt number. I just checked JamesM's tutorial and that instruction is there too, but I think it's a mistake. I may be wrong, but I don't think you can have that instruction there and have that iret work. I think you need to have the "add esp,DWORD 0x08" in your "isr_1:" procedure, right after the call to the "isr_stub:" Maybe. I may be wrong, but whatever jsut trying to help. Good luck,

Brodeur235
Post Reply