在内核代码中当需要访问当前进程的task_struct结构时使用的指针current实际上是个宏定义,它是根据当前进程的堆栈指针ESP计算出来的。
注:
(1)THREAD_SIZE(8K)即thread_info结构体的大小
(2)"andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1))
将内核堆栈栈顶ESP指针和 (~(THREAD_SIZE - 1)相与:获得的结果为内核堆栈最底端地址(也就是结构体thread_info的地址)
ESP、thread.info、task_struct、task_struct.thread的关系结构示意图
|------------|<---0x015fbfff
| kernel | |
| stack | |
| | |
| | |
| /|/ | current--+--->|--------------|
| | | | |
| |<---%%esp | |--------------|
| | (ESP) | | *thread_info |
| | | |--------------|
| | | | |
| | | | |
-----------|------------|<---0x015fa030 | | |
/|/ | *task |-----------------+ |--------------|
| |------------| | |
thread_info| | | thread |
| | | | |
/|/ | | |--------------|
-----------|------------|<---0x15fa000 | |
| |
|--------------|
task_struct
#define
current get_current()
static
inline
struct
task_struct
*
get_current(
void
)
{
return current_thread_info()->task;
}
{
return current_thread_info()->task;
}
static
inline
struct
thread_info
*
current_thread_info(
void
)
{
struct thread_info *ti;
__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1)));
return ti;
}
{
struct thread_info *ti;
__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1)));
return ti;
}
#define
THREAD_SIZE (8192)
(1)THREAD_SIZE(8K)即thread_info结构体的大小
(2)"andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1))
将内核堆栈栈顶ESP指针和 (~(THREAD_SIZE - 1)相与:获得的结果为内核堆栈最底端地址(也就是结构体thread_info的地址)
struct
thread_info
{
struct task_struct *task;
struct exec_domain *exec_domain;
unsigned long flags;
unsigned long status;
__u32 cpu;
__s32 preempt_count;
mm_segment_t addr_limit;
struct restart_block restart_block;
unsigned long previous_esp;
__u8 supervisor_stack[0];
} ;
struct task_struct *task;
struct exec_domain *exec_domain;
unsigned long flags;
unsigned long status;
__u32 cpu;
__s32 preempt_count;
mm_segment_t addr_limit;
struct restart_block restart_block;
unsigned long previous_esp;
__u8 supervisor_stack[0];
} ;
struct
task_struct
{
volatile long state;
struct thread_info *thread_info;
atomic_t usage;
unsigned long flags;
volatile long state;
struct thread_info *thread_info;
atomic_t usage;
unsigned long flags;
ESP、thread.info、task_struct、task_struct.thread的关系结构示意图
|------------|<---0x015fbfff
| kernel | |
| stack | |
| | |
| | |
| /|/ | current--+--->|--------------|
| | | | |
| |<---%%esp | |--------------|
| | (ESP) | | *thread_info |
| | | |--------------|
| | | | |
| | | | |
-----------|------------|<---0x015fa030 | | |
/|/ | *task |-----------------+ |--------------|
| |------------| | |
thread_info| | | thread |
| | | | |
/|/ | | |--------------|
-----------|------------|<---0x15fa000 | |
| |
|--------------|
task_struct