Page 1 of 1

Interrupts in usermode.

Posted: Thu Apr 16, 2009 11:52 am
by eXeCuTeR
Interrupts are working just fine in kernelmode, but when i enter usermode, they don't. It's weird because I've checked my TSS entry and it seems to be fine.

(this particular interrupt I'm using is an interrupt I have added into my OS and he is working fine in kernelmode...also all exceptions don't work in usermode, or IRQs)

gdt.c:

Code: Select all

code code code...
..
void initialize_gdt(void)
{
	unsigned int i = 1, limit[NUM_ENTRIES], base[NUM_ENTRIES];
	unsigned char access[NUM_ENTRIES], granularity[NUM_ENTRIES];
	
	limit[0] = base[0] = access[0] = granularity[0] = 0x0; // null segment
	for(;i<NUM_ENTRIES-1; i++)
	{
		limit[i] = 0xFFFFFFFF;
		base[i] = 0x0;
	}
	
	int access_flags[NUM_ENTRIES] = { 0x0, 0x9A, 0x92, 0xFA, 0xF2, 0xE9 };
	for(i=0;i<NUM_ENTRIES;i++)
		access[i] = access_flags[i];
		
	for(i=1;i<NUM_ENTRIES-1;i++)
		granularity[i] = 0xCF;
	
	/* initializing tss */	
	memset(&tss, 0, sizeof(s_tss));
	
	tss.ss0 = 0x10;
	tss.esp0 = 0x0;
	tss.cs   = 0x0B/*0x08|0x3*/;
	tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13/*0x10|0x3*/;
	
	base[NUM_ENTRIES-1] = (unsigned int)&tss;
	limit[NUM_ENTRIES-1] = (unsigned int)(sizeof(s_tss) + base[NUM_ENTRIES-1]);
	granularity[NUM_ENTRIES-1] = 0x0;
	
	build_gdt((unsigned int *)base, (unsigned int *)limit, (unsigned char *)access, (unsigned char *)granularity);
	
	gdt_install((unsigned int)&gdt.gdt_ptr);
	tss_install();
}
switchto_usermode.asm:

Code: Select all

code code code...
..
		cli
		mov ax, 0x23
		mov ds, ax
		mov es, ax
		mov fs, ax
		mov gs, ax

		mov eax, esp
		push 0x23
		push eax
		push $0x202
		push $0x1B
		push flush
		iret
	flush:
                ret
and in main.c:

Code: Select all

    switchto_usermode();
	puts("Usermode.");
	asm volatile("int $120"); // just an interrupt I have added and works in kernelmode
 // also putch(1/0); or anyother exception/IRQ doesn't work in usermode!

Please help! thanks.

Re: Interrupts in usermode.

Posted: Thu Apr 16, 2009 12:05 pm
by earlz
tss.esp0 needs to be a valid stack. It can't be NULL as that is the stack that is loaded when the usermode application jumps to a kernel interrupt

Re: Interrupts in usermode.

Posted: Thu Apr 16, 2009 1:17 pm
by eXeCuTeR
earlz wrote:tss.esp0 needs to be a valid stack. It can't be NULL as that is the stack that is loaded when the usermode application jumps to a kernel interrupt
Ah right...so what should I set it to and when exactly?

Re: Interrupts in usermode.

Posted: Thu Apr 16, 2009 2:54 pm
by Craze Frog
The address of the kernel stack! (It can be anything as long as it's not used for anything else.)

Re: Interrupts in usermode.

Posted: Thu Apr 16, 2009 4:59 pm
by eXeCuTeR
Craze Frog wrote:The address of the kernel stack! (It can be anything as long as it's not used for anything else.)
Roger that, thanks. got it working.