內核棧和current_thread_info

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章