Chinaunix首页 | 论坛 | 博客
  • 博客访问: 76059
  • 博文数量: 38
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 200
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-28 14:15
文章分类

全部博文(38)

文章存档

2013年(1)

2012年(37)

我的朋友

分类:

2012-04-17 11:07:29

浅析开发板相关函数bootloader传入的寄存器r2对应开发板tags参数地址
浅析blob到kernel传递tags参数和cmdline处理流程

r0 = 0
r1=mach_type_id
r2=BOOT_PARAMS



arch/arm/kernel/vmlinux.lds
arch/arm/kernel/head.S
为入口位置
    .section ".text.head", "ax"
ENTRY(stext)
    msr    cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
                        @ and irqs disabled
    mrc    p15, 0, r9, c0, c0        @ get processor id          // r9 = 0x41129200
    bl    __lookup_processor_type        @ r5=procinfo r9=cpuid
    movs    r10, r5                @ invalid processor (r5=0)? // r5 = __proc_info_begin虚拟地址值,所以r10等于__proc_info_begin虚拟地址值
    beq    __error_p            @ yes, error 'p'                // 如果r5等于0,那么beq成立,跳转到__error_p执行,halt在那里[luther.gliethttp]
    bl    __lookup_machine_type        @ r5=machinfo
    movs    r8, r5                @ invalid machine (r5=0)?
    beq    __error_a            @ yes, error 'a'
    bl    __vet_atags
    bl    __create_page_tables


arch/arm/kernel/head-common.S
    .long    __proc_info_begin
    .long    __proc_info_end
3:    .long    .
    .long    __arch_info_begin
    .long    __arch_info_end
__lookup_machine_type:

    adr    r3, 3b
    ldmia    r3, {r4, r5, r6}                                // r4 = 3b的虚拟地址值,r5 = __arch_info_begin虚拟地址值[luther.gliethttp]
    sub    r3, r3, r4            @ get offset between virt&phys
    add    r5, r5, r3            @ convert virt addresses to
    add    r6, r6, r3            @ physical address space
1:    ldr    r3, [r5, #MACHINFO_TYPE]    @ get machine type      // MACHINFO_TYPE为0,所以ldr r3, [r5, #0],对于EDB9312开发板r3 = 451
    teq    r3, r1                @ matches loader number?        // r1为bootloader,比如vivi,redboot或者blob等传入的nr值,即函数的第2个参数值
    beq    2f                @ found                             // 如果bootloader确实启动该zImage内核,那么跳到2f成功返回
    add    r5, r5, #SIZEOF_MACHINE_DESC    @ next machine_desc
    cmp    r5, r6
    blo    1b
    mov    r5, #0                @ unknown machine
2:    mov    pc, lr
ENDPROC(__lookup_machine_type)

反汇编可以得到machine_desc的.nr
c0008344:    c001ba18     andgt    fp, r1, r8, lsl sl
c0008348:    c0008348     andgt    r8, r0, r8, asr #6
c000834c:    c001ba18     andgt    fp, r1, r8, lsl sl
c0008350:    c001ba4c     andgt    fp, r1, ip, asr #20

c0008354 <__lookup_machine_type>:
c0008354:    e24f3014     sub    r3, pc, #20    ; 0x14      // 从当前pc回数20个字节,即
c0008358:    e8930070     ldmia    r3, {r4, r5, r6}    // r4 = c0008348, r5 = c001ba18, r6 = c001ba4c
c000835c:    e0433004     sub    r3, r3, r4
c0008360:    e0855003     add    r5, r5, r3
c0008364:    e0866003     add    r6, r6, r3
c0008368:    e5953000     ldr    r3, [r5]                // 所以取出虚拟地址c001ba18数据


c001ba18 <__arch_info_begin>:
c001ba18:    000001c3     andeq    r0, r0, r3, asr #3  // 0x1c3 = 451,所以等于MACH_TYPE_EDB9312
c001ba1c:    80800000     addhi    r0, r0, r0
c001ba20:    00003fb4     streqh    r3, [r0], -r4
c001ba24:    c02d6cd0     ldrgtd    r6, [sp], -r0
c001ba28:    00000100     andeq    r0, r0, r0, lsl #2


下面该宏MACHINE_START用来在__arch_info_begin空间生成一个machine结构体struct machine_desc,
该machine_desc结构体用来描述该款SoC,比如ep9312,的基础配置信息.[luther.gliethttp]
从这里来看宏默认只是定义.nr,即该SoC对应的索引值.[luther.gliethttp]
#define MACHINE_START(_type,_name)            \
static const struct machine_desc __mach_desc_##_type    \
 __used                            \
 __attribute__((__section__(".arch.info.init"))) = {    \
    .nr        = MACH_TYPE_##_type,        \
    .name        = _name,

#define MACHINE_END                \
};

#define MACH_TYPE_EDB9312              451
所以下面的.nr = 451,[luther.gliethttp]
arch/arm/mach-ep93xx/edb9312.c
MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
    /* Maintainer: Toufeeq Hussain */
    .phys_io    = EP93XX_APB_PHYS_BASE,
    .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
    .boot_params    = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
    .map_io        = ep93xx_map_io,
    .init_irq    = ep93xx_init_irq,
    .timer        = &ep93xx_timer,
    .init_machine    = edb9312_init_machine,
MACHINE_END
再比如:
#define MACH_TYPE_AT91RM9200DK         262
所以下面的.nr = 262,[luther.gliethttp]
arch/arm/mach-at91/board-dk.c
MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
    /* Maintainer: SAN People/Atmel */
    .phys_io    = AT91_BASE_SYS,
    .io_pg_offst    = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
    .boot_params    = AT91_SDRAM_BASE + 0x100,
    .timer        = &at91rm9200_timer,
    .map_io        = dk_map_io,
    .init_irq    = dk_init_irq,
    .init_machine    = dk_board_init,
MACHINE_END

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