Page 1 of 1

Returning interrupt value?

Posted: Sat Oct 24, 2015 3:27 am
by Awe2K
So, I'm developing simple kernel. Now I'm creating some code that makes possible interactions between drivers and my ELF programs.
This system works simply:
  1. Program calls call_driver() method.
  2. This causes interrupt 0x10 (I don't know why I'm using it)
  3. Then, from kernel side, interrupt handler is executed and it processes command (EAX - code of driver, EBX - function, ECX - data (may be ptr))
  4. Handler should return result in EDX
My problem is that my EDX isn't changing at all, here's the code how I did driver calls:

Driver call code (program-side):

Code: Select all

unsigned int call_driver(unsigned int drv, unsigned int func,
		unsigned int data0) {
	int res=0;
	__asm__ ("int $0x10"
			:"=d"(res)
			:"a"(drv), "b"(func), "c"(data0)
			:
	);
        return res;
}
Interrupt handler code (kernel-side):

Code: Select all

void isr_handler(registers_t regs)
{
    if (interrupt_handlers[regs.int_no] != 0)
    {
        isr_t handler = interrupt_handlers[regs.int_no];
        handler(regs);
    }
    else
    {
        puts("Unhandled interrupt: 0x");
        puts_h(regs.int_no);
        puts("\n");
    }
    // Just write test value to EDX
    __asm__ ("movl $12, %edx");
    return;
}
My question: how could it be fixed/am I doing something wrong?
Thanks in advance.

Re: Returning interrupt value?

Posted: Sat Oct 24, 2015 3:35 am
by Techel
Whe passing regs to the main interrupt handler and then to the specific handler it gets copied.
Edit: your real problem is changing edx directly in the handler. I suspect you are preserving the registers before calling the C function.

Re: Returning interrupt value?

Posted: Sat Oct 24, 2015 3:41 am
by Octocontrabass
Awe2K wrote:This causes interrupt 0x10 (I don't know why I'm using it)
You should choose an interrupt that isn't reserved by Intel for CPU exceptions.
Awe2K wrote:

Code: Select all

    __asm__ ("movl $12, %edx");
This overwrites EDX while the code for isr_handler is using it, potentially causing a crash or other nasty misbehavior. If isr_handler returns without crashing, EDX is promptly overwritten with the value in the regs struct by the code that called isr_handler.

Did you copy any of your code from a tutorial? Most OS development tutorials are full of bugs.

Re: Returning interrupt value?

Posted: Sat Oct 24, 2015 3:46 am
by Nable
Octocontrabass wrote:Did you copy any of your code from a tutorial? Most OS development tutorials are full of bugs.
This is obvious:

Code: Select all

registers_t regs
It was discussed a lot of times but people still repeat this mistake.

Re: Returning interrupt value?

Posted: Sat Oct 24, 2015 5:32 am
by Awe2K
Octocontrabass wrote:
Awe2K wrote:This causes interrupt 0x10 (I don't know why I'm using it)
You should choose an interrupt that isn't reserved by Intel for CPU exceptions.
I'm not sure if it causes problems but thanks for advice.
Octocontrabass wrote:
Awe2K wrote:

Code: Select all

    __asm__ ("movl $12, %edx");
This overwrites EDX while the code for isr_handler is using it, potentially causing a crash or other nasty misbehavior. If isr_handler returns without crashing, EDX is promptly overwritten with the value in the regs struct by the code that called isr_handler.
Ok, didn't know it can cause something wrong, removed it.
Octocontrabass wrote:Did you copy any of your code from a tutorial? Most OS development tutorials are full of bugs.
Yes, ISR's handler is copied from tutorial (I was too lazy to implement my own ISR's/IRQ's handler).

Also, I've already found the solution out. That ISR handler code preserves registers in registers_t type, so I just had to change edx there. Thanks again, guys.

Re: Returning interrupt value?

Posted: Sat Oct 24, 2015 5:45 am
by iansjack
I was too lazy to implement my own ISR's/IRQ's handler
It never ceases to amaze me that so many people want to pursue the difficult subject of OS development yet freely admit to being "too lazy" to so this or that. The sad truth is that this laziness almost always creates far more work than buckling down, reading documentation, and trying to understand what you are doing.

Re: Returning interrupt value?

Posted: Sat Oct 24, 2015 5:53 am
by Octocontrabass
Awe2K wrote:That ISR handler code preserves registers in registers_t type,
No, it actually doesn't. Nable helpfully reminded me that you've copied one of the less-obvious bugs from a certain tutorial. Even though it seems to work now, it will cause you problems later if you don't fix it.

Re: Returning interrupt value?

Posted: Sat Oct 24, 2015 6:04 am
by Awe2K
Octocontrabass wrote:
Awe2K wrote:That ISR handler code preserves registers in registers_t type,
No, it actually doesn't. Nable helpfully reminded me that you've copied one of the less-obvious bugs from a certain tutorial. Even though it seems to work now, it will cause you problems later if you don't fix it.
Yes, I've already changed registers_t in handler to registers_t *. Driver calls seem to work now.