Chinaunix首页 | 论坛 | 博客
  • 博客访问: 82372
  • 博文数量: 28
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-04 11:06
文章分类

全部博文(28)

文章存档

2014年(22)

2013年(5)

2012年(1)

我的朋友

分类: 嵌入式

2014-04-20 17:28:13

uboot调用内核时传递的参数是 r1=Machine_ID  
ENTRY(stext)
setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
@ and irqs disabled
mrc p15, 0, r9, c0, c0 @ get processor id
bl __lookup_processor_type @ 返回值r5=procinfo   r9=cpuid  

点击(此处)折叠或打开

  1. *    r9 = cpuid
  2.  * Returns:
  3.  *    r3, r4, r6 corrupted
  4.  *    r5 = proc_info pointer in physical address space
  5.  *    r9 = cpuid (preserved)
  6.  */
  7.     __CPUINIT
  8. __lookup_processor_type:
  9.     adr    r3, __lookup_processor_type_data  r3=下面31行代码的物理地址
  10.     ldmia    r3, {r4 - r6}      r4=下面31行的虚拟地址  r5= __proc_info_end  r6=__proc_info_end  
  11.      

    点击(此处)折叠或打开

    1. VMLINUX_SYMBOL(__proc_info_begin) = .;      属性段的开始地址          \
    2.     *(.proc.info.init)         此属性的结构体都在这个地址处 
    3.   由于在配置文件中自定义了 config_cpu_arm920t =1 所以只会调用proc-arm920这个文件 即此段属性中只会有arm920t的proc结构体    \
    4.     VMLINUX_SYMBOL(__proc_info_end) = .    属性段的结束地址
    5.    

      点击(此处)折叠或打开

      1. .align

      2.     .section ".proc.info.init", #alloc, #execinstr

      3.     .type    __arm920_proc_info,#object
      4. __arm920_proc_info:
      5.     .long    0x41009200
      6.     .long    0xff00fff0
      7.     .long PMD_TYPE_SECT | \
      8.         PMD_SECT_BUFFERABLE | \
      9.         PMD_SECT_CACHEABLE | \
      10.         PMD_BIT4 | \
      11.         PMD_SECT_AP_WRITE | \
      12.         PMD_SECT_AP_READ
      13.     .long PMD_TYPE_SECT | \
      14.         PMD_BIT4 | \
      15.         PMD_SECT_AP_WRITE | \
      16.         PMD_SECT_AP_READ
      17.     b    __arm920_setup
      18.     .long    cpu_arch_name
      19.     .long    cpu_elf_name
      20.     .long    HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
      21.     .long    cpu_arm920_name
      22.     .long    arm920_processor_functions
      23.     .long    v4wbi_tlb_fns
      24.     .long    v4wb_user_fns
      25. #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
      26.     .long    arm920_cache_fns
      27. #else
      28.     .long    v4wt_cache_fns
      29. #endif
      30.     .size    __arm920_proc_info, . - __arm920_proc_info
      31. // 处理器的信息
      32.     struct proc_info_list {
        unsigned int cpu_val;  //处理器类型
        unsigned int cpu_mask;  //处理器掩码
        unsigned long __cpu_mm_mmu_flags; /* used by head.S */
        unsigned long __cpu_io_mmu_flags; /* used by head.S */
        unsigned long __cpu_flush; /* used by head.S */
        const char *arch_name;
        const char *elf_name;
        unsigned int elf_hwcap;
        const char *cpu_name;
        struct processor *proc;
        struct cpu_tlb_fns *tlb;
        struct cpu_user_fns *user;
        struct cpu_cache_fns *cache;
        };



  12.     sub    r3, r3, r4            @ get offset between virt&phy//物理地址-虚拟地址的差值
  13.     add    r5, r5, r3            @ convert virt addresses to //对应_proc_info_begin 的物理地址
  14.     add    r6, r6, r3            @ physical address space   //对应_proc_info_end 的物理地址
  15. 1:    ldmia    r5, {r3, r4}            @ //r3=value,r4= mask  
  16.     and    r4, r4, r9            @ mask wanted bits
  17.     teq    r3, r4
  18.     beq    2f
  19.     add    r5, r5, #PROC_INFO_SZ        @ sizeof(proc_info_list)
  20.     cmp    r5, r6
  21.     blo    1b
  22.     mov    r5, #0                @ unknown processor
  23. 2:    mov    pc, lr
  24. ENDPROC(__lookup_processor_type)

  25. /*
  26.  * Look in <asm/procinfo.h> for information about the __proc_info structure.
  27.  */
  28.     .align    2
  29.     .type    __lookup_processor_type_data, %object
  30. __lookup_processor_type_data:
  31.     .long    .
  32.     .long    __proc_info_begin
  33.     .long    __proc_info_end
  34.     .size    __lookup_processor_type_data, . - __lookup_processor_type_data
movs r10, r5                  @ invalid processor (r5=0)?
 THUMB( it eq )                   @ force fixup-able long branch encoding
beq __error_p                         @ yes, error 'p'
bl __lookup_machine_type           @ r5=machinfo //查找对应的机器id
      

点击(此处)折叠或打开

  1. * r1 = machine architecture number
  2.  * Returns:
  3.  * r3, r4, r6 corrupted
  4.  * r5 = mach_info pointer in physical address space
  5.  */
  6. __lookup_machine_type:
  7.     adr    r3, __lookup_machine_type_data  //r3= __lookup_machine_type_data 的物理地址 即下面第29的物理地址
  8.     ldmia    r3, {r4, r5, r6} r4=.long的虚拟地址(下面第29行的地址) r5=_arch_info_begin的虚拟地址 r6=arch_info_end的地址
  9.                               

    点击(此处)折叠或打开

    1. __arch_info_begin = .;  arch属性段的开始地址
    2.             *(.arch.info.init) arch_info的结构体  会根据CONFIG_MACH_FENG2440 CONFIG_MACH_SMDK2440是否被定义
    3.                                   来确定内核将支持那个board  通过make menuconfig 方式来选择变量 定义情况 分析Kconfig文件可知
    4. __arch_info_end = .;   arch属性段的结束地址
    5.    

      点击(此处)折叠或打开

      1. struct machine_desc {
      2.     unsigned int        nr;        /* architecture number    */
      3.     const char        *name;        /* architecture name    */
      4.     unsigned long        boot_params;    /* tagged list        */

      5.     unsigned int        nr_irqs;    /* number of IRQs */

      6.     unsigned int        video_start;    /* start of video RAM    */
      7.     unsigned int        video_end;    /* end of video RAM    */

      8.     unsigned int        reserve_lp0 :1;    /* never has lp0    */
      9.     unsigned int        reserve_lp1 :1;    /* never has lp1    */
      10.     unsigned int        reserve_lp2 :1;    /* never has lp2    */
      11.     unsigned int        soft_reboot :1;    /* soft reboot        */
      12.     void            (*fixup)(struct machine_desc *,
      13.                      struct tag *, char **,
      14.                      struct meminfo *);
      15.     void            (*reserve)(void);/* reserve mem blocks    */
      16.     void            (*map_io)(void);/* IO mapping function    */
      17.     void            (*init_early)(void);
      18.     void            (*init_irq)(void);
      19.     struct sys_timer    *timer;        /* system tick timer    */
      20.     void            (*init_machine)(void);
      21. #ifdef CONFIG_MULTI_IRQ_HANDLER
      22.     void            (*handle_irq)(struct pt_regs *);
      23. #endif
      24. };
      25.  machine宏定义如下
      26.  #define MACHINE_START(_type,_name) \  
      27. static const struct machine_desc __mach_desc_##_type \
      28.  __used \
      29. __attribute__((__section__(".arch.info.init"))) = { \
      30. .nr = MACH_TYPE_##_type, \
      31. .name = _name,

      32. #define MACHINE_END      };
        以smdk2440为例
      MACHINE_START(S3C2440, "SMDK2440")
      .boot_params = S3C2410_SDRAM_PA + 0x100,


      .init_irq = s3c24xx_init_irq,
      .map_io = smdk2440_map_io,
      .init_machine = smdk2440_machine_init,
      .timer = &s3c24xx_timer,
      MACHINE_END

      宏展开后得到
      static const struct machine_desc   __mach_desc_S3C2440       __used __attribute__((__section__(".arch.info.init")))
      = { 
           .nr = MACH_TYPE_S3C2440, \
           .name = SMDK2440,
           .init_irq = s3c24xx_init_irq,
           .map_io = smdk2440_map_io,
          .init_machine = smdk2440_machine_init,
          .timer = &s3c24xx_timer,

           };
      board的结构体

        
  10.     sub    r3, r3, r4            @ get offset between virt&phys
  11.     add    r5, r5, r3            @ convert virt addresses to
  12.     add    r6, r6, r3            @ physical address space
  13. 1:    ldr    r3, [r5, #MACHINFO_TYPE]    @ get machine type
  14.     teq    r3, r1                @ matches loader number?
  15.     beq    2f                @ found
  16.     add    r5, r5, #SIZEOF_MACHINE_DESC    @ next machine_desc
  17.     cmp    r5, r6
  18.     blo    1b
  19.     mov    r5, #0                @ unknown machine
  20. 2:    mov    pc, lr
  21. ENDPROC(__lookup_machine_type)

  22. /*
  23.  * Look in arch/arm/kernel/arch.[ch] for information about the
  24.  * __arch_info structures.
  25.  */
  26.     .align    2
  27.     .type    __lookup_machine_type_data, %object
  28. __lookup_machine_type_data:
  29.     .long    .
  30.     .long    __arch_info_begin
  31.     .long    __arch_info_end
  32.     .size    __lookup_machine_type_data, . - __lookup_machine_type_data


movs r8, r5 @ invalid machine (r5=0)?
 THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_a @ yes, error 'a'

/*
* r1 = machine no, r2 = atags,
* r8 = machinfo, r9 = cpuid, r10 = procinfo
*/
bl __vet_atags
#ifdef CONFIG_SMP_ON_UP
bl __fixup_smp
#endif
bl __create_page_tables // 创建页表

ldr r13, =__mmap_switched @ address to jump to after @ mmu has been enabled
// 复制数据 清bss段 保存processor_id=cpu id  保存_machine_arch_typ=machine id   调用start_kernel
adr lr, BSYM(1f) @ return (PIC) address
 ARM( add pc, r10, #PROCINFO_INITFUNC )
 THUMB( add r12, r10, #PROCINFO_INITFUNC )
 THUMB( mov pc, r12 )
1: b __enable_mmu
ENDPROC(stext)
.ltorg



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