Wednesday, May 13, 2009

First successful context switch!

A couple of days ago, I ran my first fully working context switches. I have two small test processes that actually just yield to each other:

/* Test processes. */
__attribute__ ((naked)) static void proc0()
{
for (;;)
{
asm("mov r0, 0x1\n\t"
"svc\n\t");
}
}

__attribute__ ((naked)) static void proc1()
{
for (;;)
{
asm("mov r0, 0x1\n\t"
"svc\n\t");
}
}



The code is really an ugly mix of C and assembly, and it seems like the __attribute__ ((naked)) thing completely fools gdb as well. If i put a breakpoint on one of these two functions gdb does not put it on the first instruction, as you would probably want it to. Instead, it puts it one instruction after the first instruction. My guess is that gdb believes the first instruction to be a preamble for setting up the stack frame. But we don't have any stack frames here, due to the special attribute used. The workaround is to put a breakpoint on the address of the first instruction.

The processes put 1 in r0, which means call the yield system call, which in turns causes the simple scheduler to switch to the other process.

2 comments:

  1. Hi Marcus,

    Thanks for sharing the progress of your project. I am attempting something similar - a simple OS for an Olimex board running an ARM7 uC. But I'm just getting started, you are far ahead of me.

    What toolchain are you using?

    ReplyDelete
  2. Hi Daniel!

    Thanks for being the first to comment! I'm using GNU binutils (2.19) and gcc 4.3.2. I configured and built it myself, but today I would probably walk an easier way and use the free "Lite" distribution from Codesourcery.

    ReplyDelete