curren、內核棧、current_thread_info
內核棧
爲什麼要有內核棧?
內核棧用於存放一些內核的棧信息,例如臨時變量,函數調用信息。
內核棧存放在哪裏?
task_struct->stack
內核棧和thread_info一起存放在一個聯合體thread_union中,thread_union的大小爲THREAD_SIZE。
thread_info
線程描述符,和體系結構有關的信息。
/*
* low level task data that entry.S needs immediate access to.
* __switch_to() assumes cpu_context follows immediately after cpu_domain.
*/
struct thread_info {
unsigned long flags; /* low level flags */
mm_segment_t addr_limit; /* address limit */
struct task_struct *task; /* main task structure */
int preempt_count; /* 0 => preemptable, <0 => bug */
int cpu; /* cpu */
};
#define THREAD_SIZE 16384
#define THREAD_START_SP (THREAD_SIZE - 16)
union thread_union {
struct thread_info thread_info;
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
current宏
棧指針->thread_info
sp的低字節部分改爲0(起始地址THREAD_SIZE對齊)
thread_info->task
#define get_current() (current_thread_info()->task)
#define current get_current()
/*
* how to get the thread information struct from C
*/
static inline struct thread_info *current_thread_info(void) __attribute_const__;
static inline struct thread_info *current_thread_info(void)
{
return (struct thread_info *)
(current_stack_pointer & ~(THREAD_SIZE - 1));
}
寫一個簡單的內核模塊來打印響應的信息。
static void print_arg(void)
{
struct task_struct *task = current;
printk("[%s %d] task = 0x%lx\n", __func__, __LINE__, task);
printk("[%s %d] task->statck = 0x%lx\n", __func__, __LINE__, task->stack);
printk("[%s %d] current_stack_pointer = 0x%lx\n", __func__, __LINE__, current_stack_pointer);
printk("[%s %d] ~(THREAD_SIZE - 1) = 0x%lx\n", __func__, __LINE__, ~(THREAD_SIZE - 1));
printk("[%s %d] (current_stack_pointer & ~(THREAD_SIZE - 1)) = 0x%lx\n", __func__, __LINE__, (current_stack_pointer & ~(THREAD_SIZE - 1)));
printk("[%s %d] current_thread_info = 0x%lx\n", __func__, __LINE__, current_thread_info());
printk("[%s %d] task->stack->task = 0x%lx\n", __func__, __LINE__, ((struct thread_info *)task->stack)->task);
return;
}
static int __init test_module_init(void)
{
printk("[%s %d] init!\n", __func__, __LINE__);
print_arg();
return 0;
}
結果如下
# insmod test_module.ko
[ 5903.536202] [test_module_init 28] init!
[ 5903.540313] [print_arg 16] task = 0xffffffc00d060000
[ 5903.545394] [print_arg 17] task->statck = 0xffffffc00c220000
[ 5903.551181] [print_arg 18] current_stack_pointer = 0xffffffc00c223c20
[ 5903.557643] [print_arg 19] ~(THREAD_SIZE - 1) = 0xffffc000
[ 5903.563207] [print_arg 20] (current_stack_pointer & ~(THREAD_SIZE - 1)) = 0xffffffc00c220000
[ 5903.571755] [print_arg 21] current_thread_info = 0xffffffc00c220000
[ 5903.578033] [print_arg 22] task->stack->task = 0xffffffc00d060000