taoyuetao的个人空间 https://blog.eetop.cn/taoyuetao [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

[原创] linux启动流程分析(4)---汇编部分(2)

已有 8629 次阅读| 2007-2-14 10:40 |个人分类:【 Linux & GNU 】

天气: 晴朗
心情: 高兴

================================

Author: taoyuetao
Email: tao_yuetao@yahoo.com.cn
Blog: http://www.eetop.cn/blog/?11145

2007-02-14

================================

前面一篇文章,简单介绍了内核启动的汇编主流程,这篇介绍其中调用的汇编子函数__lookup_processor_type

函数__lookup_processor_type介绍:

内核中使用了一个结构struct proc_info_list,用来记录处理器相关的信息,该结构定义在
kernel/include/asm-arm/procinfo.h头文件中。

/* 
 * Note!  struct processor is always defined if we're
 * using MULTI_CPU, otherwise this entry is unused,
 * but still exists.
 *
 * NOTE! The following structure is defined by assembly
 * language, NOT C code.  For more information, check:
 *  arch/arm/mm/proc-*.S and arch/arm/kernel/head-armv.S
 */    
struct proc_info_list {
    unsigned int        cpu_val;
    unsigned int        cpu_mask;
    unsigned long       __cpu_mmu_flags;    /* used by head-armv.S */
    unsigned long       __cpu_flush;        /* used by head-armv.S */
    const char      *arch_name;
    const char      *elf_name;
    unsigned int        elf_hwcap;
    struct proc_info_item   *info;
    struct processor    *proc;
}; 

在arch/arm/mm/proc-xscale.S文件中定义了所有和xscale有关的proc_info_list,我们使用的pxa270定义如下:

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

.type   __bva0_proc_info,#object
__bva0_proc_info:
    .long   0x69054110          @ Bulverde A0: 0x69054110, A1 : 0x69054111.
    .long   0xfffffff0          @ and this is the CPU id mask.
#if CACHE_WRITE_THROUGH
    .long   0x00000c0a
#else
    .long   0x00000c0e
#endif
  b   __xscale_setup
  .long   cpu_arch_name
    .long   cpu_elf_name
    .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_XSCALE
    .long   cpu_bva0_info
    .long   xscale_processor_functions
    .size   __bva0_proc_info, . - __bva0_proc_info
   
由于.section指示符,上面定义的__bva0_proc_info信息在编译的时候被放到了.proc.info段中,这是由linux的
链接脚本文件vmlinux.lds指定的,参考如下:
       SECTIONS
       {
           . = 0xC0008000;
           .init : {           /* Init code and data       */
              _stext = .;
              __init_begin = .;
                  *(.text.init)
              __proc_info_begin = .;
                  *(.proc.info)
              __proc_info_end = .;
             
这里的符号__proc_info_begin指向.proc.info的起始地址,而符号__proc_info_end指向.proc.info的结束地址。
后面就会引用这两个符号,来指向.proc.info这个段。
    

下面来来看看函数的源代码,为了分析方便将函数按行进行编号,其中17-18行就是前面提到的对.proc.info的引用,
第2行将17行的地址放到寄存器r5中,adr是小范围的地址读取伪指令。第3行将r5所指向的数据区的数据读出到r7,r9
r10,执行结果是r7=__proc_info_end,r9=__proc_info_begin,r10=第19行的地址,第4-6行的结果应该是r10指向
__proc_info_begin的地址,第7行读取cpu的id,这是一个协处理器指令,将processor ID存储在r9中,第8行将r10指向
的__bva0_proc_info开始的数据读出放到寄存器r5,r6,r8,结果r5=0x69054110(cpu_val),r6=0xfffffff0(cpu_mask),
r8=0x00000c0e(__cpu_mmu_flags),第9-10行将读出的id和结构中的id进行比较,如果id相同则返回,返回时r9存储
processor ID,如果id不匹配,则将指针r10增加36(proc_info_list结构的长度),如果r10小于r7指定的地址,也就是
__proc_info_end,则继续循环比较下一个proc_info_list中的id,如第11-14行的代码,如果查找到__proc_info_end
仍未找到一个匹配的id,则将r10清零并返回,如15-16行,也就是说如果函数执行成功则r10指向匹配的proc_info_list
结构地址,如果函数返回错误则r10为0。

/*     
 * Read processor ID register (CP#15, CR0), and look up in the linker-built
 * supported processor list.  Note that we can't use the absolute addresses
 * for the __proc_info lists since we aren't running with the MMU on
 * (and therefore, we are not in the correct address space).  We have to
 * calculate the offset.
 *     
 * Returns:
 *  r5, r6, r7 corrupted           
 *  r8  = page table flags
 *  r9  = processor ID
 *  r10 = pointer to processor structure
 */    
1 __lookup_processor_type:   
2    adr r5, 2f
3    ldmia   r5, {r7, r9, r10}
4    sub r5, r5, r10         @ convert addresses
5    add r7, r7, r5          @ to our address space
6    add r10, r9, r5
7    mrc p15, 0, r9, c0, c0      @ get processor id
8 1:   ldmia   r10, {r5, r6, r8}       @ value, mask, mmuflags
9    and r6, r6, r9          @ mask wanted bits
10   teq r5, r6
11   moveq   pc, lr
12   add r10, r10, #36           @ sizeof(proc_info_list)
13   cmp r10, r7
14   blt 1b
15   mov r10, #0             @ unknown processor
16   mov pc, lr
   
/*     
 * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
 * more information about the __proc_info and __arch_info structures.
 */    
17 2:     .long   __proc_info_end
18        .long   __proc_info_begin
19        .long   2b
20        .long   __arch_info_begin
21        .long   __arch_info_end


点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 0

    粉丝
  • 0

    好友
  • 0

    获赞
  • 1075

    评论
  • 4435

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-5-29 23:21 , Processed in 0.014580 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部