On Tue, Mar 05, 2002 at 11:27:03AM +0530, Ganesh P wrote: > 1. How does the scheduler perform a task switch i.e. where do I find the > exact code that performs the task switch. In include/asm-i386/system.h (I'll insert some additional comments): /* * This whole procedure is essentially a coroutine call. Coroutines * are independent execution "streams" that transfer control to each * other, basically cooperative multithreading. * The essential parts of this switching are: * (1) save current registers on our stack * (2) save stack pointer and program counter in a buffer * (3) restore stack pointer from another buffer * (4) jump to saved program counter from the other buffer * (5) make sure that when waking up, we restore our registers from * the stack * -- wli */ #define switch_to(prev,next) do { \ /* \ * The first thing we'll do is store the three registers we \ * must absolutely save across function calls onto the stack. \ * Essentially, we're doing a "call by hand" because the \ * part normally after the call that restores registers is \ * done differently. \ * -- wli \ */ \ asm volatile("pushl %%esi\n\t" \ "pushl %%edi\n\t" \ "pushl %%ebp\n\t" \ \ /* \ * Now one of the arguments to the inline asm is a \ * pointer to a place we can save our stack pointer \ * and another is a place where we can save our \ * program counter (EIP in Intel nomenclature). \ * The magic trick here is that we can't use our \ * actual program counter as we're running because \ * we would loop. Instead we use a trick to get the \ * address of where we know we'd like to return to \ * by creating the label 1: and then saving $1f to \ * the saved program counter. \ * \ * It might appear at first that since this is a \ * constant value we would only need to get at that, \ * but even though this is only used once, we could \ * very well be restoring something created by hand \ * or saved by interrupt handling. \ * \ * The next exciting bit is that the FASTCALL() \ * macro actually declares a function to accept its \ * arguments from registers, now since the only \ * register that has been altered is the stack pointer \ * we are as ready as ever to do the call. Now the \ * tricky part of this is that we don't set our program \ * counter directly (using jmp), but rather set up the \ * program counter as the return address for \ * __switch_to()! Then the calling convention that on \ * i386, the return address is on the top of the stack \ * is used so the function can be returned from \ * normally to put us in the new thread, but we can't \ * call it normally, so instead we jmp to the function. \ * -- wli \ */ \ "movl %%esp,%0\n\t" /* save ESP */ \ "movl %2,%%esp\n\t" /* restore ESP */ \ "movl $1f,%1\n\t" /* save EIP */ \ "pushl %3\n\t" /* restore EIP */ \ \ /* \ * __switch_to() has had a call set up by all the stuff \ * I was talking about above. When we return from it, \ * we are executing in the new task. The handcoded \ * return address setup is the label 1: \ * -- wli \ */ \ "jmp __switch_to\n" \ "1:\t" \ \ /* \ * This is where we came out in the new thread. Now we \ * have our stack and program counter, we just have to \ * remember to restore our registers from the stack. \ * -- wli \ */ \ "popl %%ebp\n\t" \ "popl %%edi\n\t" \ "popl %%esi\n\t" \ :"=m" (prev->thread.esp),"=m" (prev->thread.eip) \ :"m" (next->thread.esp),"m" (next->thread.eip), \ "a" (prev), "d" (next)); \ } while (0) Although it's a little bit obfuscated by some fancy gyrations, I hope I've made it clear that the whole "control transfer" or "task switch" is really nothing more than some trickery to use the minimal number of registers so that compiled C code can have its variables saved and restored, and an indirect jump to the saved position of the program counter. > 2. When does the scheduler get control so that it can perform the task > switch. i.e is the scheduler called from the timer interrupt or something > like that? The scheduler gets control during explicit calls to schedule() and other functions in sched.c > 4. Does the linux kernel use the facilities provided by the processor ( I > think x86 has facilities for task switch ) for the task switching? TSS's are essentially required for SMP operation. However, Linux uses one TSS per cpu. > 3. Is it possible to load the linux image inside gdb and execute it. Operating system kernels generally assume direct hardware access not available from userspace. User-mode Linux is able to be used with gdb, with some requirements on how gdb is invoked. > 4. Is there a port of the User-Mode Linux for windows ? Not that I am aware of. Cheers, Bill -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ IRC Channel: irc.openprojects.net / #kernelnewbies Web Page: http://www.kernelnewbies.org/