Chinaunix首页 | 论坛 | 博客
  • 博客访问: 591305
  • 博文数量: 197
  • 博客积分: 7001
  • 博客等级: 大校
  • 技术积分: 2155
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-24 00:29
文章分类

全部博文(197)

文章存档

2022年(1)

2019年(2)

2015年(1)

2012年(100)

2011年(69)

2010年(14)

2007年(3)

2005年(7)

分类: LINUX

2010-12-29 21:37:08

犯了一个错误,总结一下对核心栈的认识。


tss_struct 和thread_struct 两个结构涉及核心栈指针。
struct tss_struct {
   /*
    * The hardware state:
    */
   struct x86_hw_tss    x86_tss;

   

} ____cacheline_aligned;

struct x86_hw_tss {
   unsigned short        back_link, __blh;
   unsigned long        sp0;
   unsigned short        ss0, __ss0h;
   unsigned long        sp1;
   /* ss1 caches MSR_IA32_SYSENTER_CS: */
   unsigned short        ss1, __ss1h;
   …..
}


thread_struct 位于task_struct中


struct thread_struct {
   /* Cached TLS descriptors: */
   struct desc_struct    tls_array[GDT_ENTRY_TLS_ENTRIES];
   unsigned long        sp0;
   unsigned long        sp;
   …..
}

1 在创建进程时copy_thread中初始化
   p->thread.sp = (unsigned long) childregs;
   p->thread.sp0 = (unsigned long) (childregs+1);


2  在进程切换时,switch_to(prev, next, last)    会切换 thread_struct中的sp0,同时要修改tss中的esp0(因为每个cpu才一个TSS,只要调整esp0即可),见__switch_to函数
__notrace_funcgraph struct task_struct *
__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
/*
    * Reload esp0.
    */
   load_sp0(tss, next);
}
实际就是用thread_struct 的sp0初始化TSS中的sp0
static inline void
native_load_sp0(struct tss_struct *tss, struct thread_struct *thread)
{
   tss->x86_tss.sp0 = thread->sp0;

}

3 TSS真正被使用的域就是SS0和sp0,用于从用户态切换到核心态。在用户态kernel stack 总是为空,所以从核心态返回用户态不需要保存核心栈指针(肯定是栈顶,tss_struct中已经准备好了)

阅读(1439) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~