Hi there people, I'm trying to figure out for several days now how the following functions:
<from include/asm-i386/thread_info.h>
86 /* how to get the thread information struct from C */
87 static inline struct thread_info *current_thread_info(void)
88 {
89 struct thread_info *ti;
90 __asm__("andl %%esp,%0; ":"=r" (ti) : "" (~(THREAD_SIZE - 1)));
91 return ti;
92 }
I've read several tutorials on inline asm but what is peculiar here is, that
the input operand's constraint is "" (nothing) whereas the (~(THREAD_SIZE-1))
= (~(8192-1)) = (~0001 1111 1111 1111) = 1110 0000 0000 0000, IIRC, gets
passed as a C arg.
What exactly happens here?
You missed 0 -> "0".
It is the 2.6 kernel's way of getting the thread_info structure of the currently running task.
It works exactly current worked in 2.4s. /* in 2.4 current.h*/ static inline struct task_struct * get_current(void) { struct task_struct *current; __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL)); return current; }
The principle is simple. Each task has THREAD_SIZE sized kernel stack. At the low end of that stack, there is a pointer to the thread_info.
So, to get the thread_info of the current task, round to the base of current kernel stack(by clearing the lower bits.) whiere lies the pointer to the current task's task_info.
Entry.S does the same thing with #define GET_THREAD_INFO(reg) \ movl $-THREAD_SIZE, reg; \ andl %esp, reg
regards manish
_________________________________________________________________
Watch the online reality show Mixed Messages with a friend and enter to win a trip to NY http://www.msnmessenger-download.click-url.com/go/onm00200497ave/direct/01/
-- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/