Chinaunix首页 | 论坛 | 博客
  • 博客访问: 405339
  • 博文数量: 53
  • 博客积分: 1910
  • 博客等级: 中尉
  • 技术积分: 1130
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-10 14:56
文章分类

全部博文(53)

文章存档

2013年(1)

2012年(17)

2011年(33)

2010年(2)

分类: LINUX

2011-04-18 14:33:14

ARM
NPTL
EABI
 
1.   err = pthread_create(&pthread_test1,NULL,test1_fn,NULL);
2.   pthread_create(pthread_t *tid, const pthread_attr_t *attr, void * (*func)(void *), void
     *arg);
     * pthread_t *tid :
       pthread_test1  就是 通过 ALLOCATE_STACK (iattr, &pd); 分配的struct pthread 结构
       ALLOCATE_STACK 后的用户线程栈:
    
high addr:
mem + size   ------> --------------------
                     | TLS_PRE_TCB_SIZE |
      tls end -----> -------------------- 
                     | __static_tls_size| <--- tls start =(pd +1)
               ----> |------------------| <---(pd)
   stack start ----> |------------------| <---(char *) (pd - 1)           
                     | user thread stack| 
mem  (stack end)---> |----------------- | <---guard
low addr:
 
     * attr :
       如果为NULL , 设置为default_attr (至少要设置guardsize = 1)
     * func:
       test1_fn ,用户线程函数
     * arg:
       NULL
   
     => create_thread (struct pthread *pd, const struct pthread_attr
                     *attr,STACK_VARIABLES_PARMS)
 
3. create_thread (struct pthread *pd, const struct pthread_attr *attr,STACK_VARIABLES_PARMS)
     * pd :
       pthread_t *tid  =>  ALLOCATE_STACK  分配并初始化
     * attr:
       default_attr
     * STACK_VARIABLES_PARMS:
       user thread stack (pd -1)
    
     => int res = do_clone (pd, attr, clone_flags, start_thread,STACK_VARIABLES_ARGS, 1);
    
4. static int do_clone (struct pthread *pd, const struct pthread_attr *attr,
   int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS, int stopped)
    * clone_flags:
      int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL
       | CLONE_SETTLS | CLONE_PARENT_SETTID
       | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
 
    * fct :
      start_thread => /* Run the code the user provided.  */
            THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));
    * stopped
       
    * 其他同上    
 
    => ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
         pd, &pd->tid, TLS_VALUE, &pd->tid)
 
5.  ENTRY(__clone) :
      int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
          pid_t *ptid, struct user_desc *tls, pid_t *ctid);
 
     R0 => fct (start_thread ,function pointer)
     R1 => STACK_VARIABLES_ARGS (user thread stack pointer)
     R2 => clone_flags
     R3 => pd  (pthead pointer)
     user sp => &pd->tid      (ptid pointer)     
     user sp -4 => TLS_VALUE  (pd+1, tls start addr)
     user sp -8 => &pd->tid      (ctid pointer)     
     R0 <= R2  (clone_flags)
     R1 <= R1  STACK_VARIABLES_ARGS (user thread stack pointer)
     R2 <= user sp  (ptid pointer)     
     R3 <= user sp -4 (TLS_VALUE)
     R4 <= user sp -8  (ctid pointer)
 
     => R7 <= sys_clone_wrapper (120)
        swi 0
 
user :
-----------------------------------------------------------------------------------
kernel :
 
1.     ENTRY(vector_swi)
    * 开始构建 c 函数 sys_clone的栈:
 
High addr:
(FD 栈)
                  |    ......          |
                  |--------------------|      
上次user sp --->  |    xxxx            |
                  |--------------------| 
ARM_ORIG_r0 --->  |    R0              |<-------------------------------------------
                  |--------------------|                                          A
ARM_cpsr    --->  |    spsr            |      swi 前的cpsr (user 下的)            |
                  |--------------------|                                          |
ARM_pc      --->  | swi 指令下一条地址 |                                 #S_FRAME_SIZE 
                  |--------------------|                                          |
ARM_lr      --->  |    LR_usermode     |                                          |
                  |--------------------|                                          |
ARM_sp      --->  |    SP_usermode     |                                          |
                  |--------------------|                                          |
ARM_ip      --->  |     R12            |       R12-R1                             |
                  |     ...            |                                          |
                  |     ...            |                                          |
ARM_r1      --->  |     R1             |                                          |
                  |--------------------|                                          V
ARM_r0      --->  |     R0             |   <---  (pt_regs *)------------------------
                  |--------------------|
syscall参数6--->  |    R5              | 
                  |--------------------|
syscall参数5--->  |    R4              |   <---- 当前 svc sp
                  |--------------------|
 
Low addr
     
        根据上面的栈
          a. syscall 时kernel 栈上ARM_r0和ARM_ORIG_r0 看起来是一样的内容
         其他异常不一样
          b.  syscall 最大参数 6个放到R0-R5,在具体call kernel 函数前,总认为
         传了6个,所以按规则 参数1-4放 R0-R1, 参数5,6压栈
 
   * 根据 scno (R7) 查表到sys_clone_wrapper跳转执行
     cmp scno, #NR_syscalls  @ check upper syscall limit
     adr lr, ret_fast_syscall  @ return address   @ 注意返回到ret_fast_syscall
                            在执行完 sys_clone_wrapper后
     ldrcc  pc, [tbl, scno, lsl #2]  @ call sys_* routine
 
2.  sys_clone_wrapper
      因为sys clone 没有6个参数,所以根据时间情况调整 上面的栈:
 
   
ARM_r0      --->  |   上面不变        |   <---  (pt_regs *)------------                                 
         |--------------------|
syscall参数--->   |  pt_regs *         |   从R5 改变为上面 pt_regs 所指地址
                  |--------------------|
syscall参数5--->  |    R4              |   <---- 当前 svc sp
                  |--------------------|
 
3.  执行 c 函数 sys_clone:
    int sys_clone(unsigned long clone_flags(R0), unsigned long newsp(R1),
                int __user *parent_tidptr(R2), int tls_val(R3),
         int __user *child_tidptr(svc sp), struct pt_regs *regs (svc sp-4))
 
4. sys_clone 返回 执行 ret_fast_syscall
      如果没有发生调度,那么
      恢复swi 前所有用户上下文,并获取 arm_pc (值为swi 0下面那句)
   栈如下:
                  |    ......          |
                  |--------------------|      
上次user sp --->  |    xxxx            |
                  |--------------------|   
                   下面的部分全部出栈了
 

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