关闭

ARM平台device tree是如何工作的?(一)

标签: armkerneldevicetree
496人阅读 评论(0) 收藏 举报
分类:

bootloader传递给内核的参数


在bootloader启动kernel之前会设置ARM CPU的r0,r1,r2,r9寄存器:
未使用device tree的2.6版本中,只需要将:
r0=0;
r1=machine_id;
r2=atags_address;

使用device tree之后,就稍微复杂一些,设置如下:
r0=cp#15 control register;
r1=machine ID;
r2=atags/dtb pointer;
r9=processor ID;

在arm/arm/kernel/head-common.S中,汇编代码会将这几个寄存器的值保存到几个变量中。

/*
 * The following fragment of code is executed with the MMU on in MMU mode,
 * and uses absolute addresses; this is not position independent.
 *
 *  r0  = cp#15 control register                                                                                                                                                                             
 *  r1  = machine ID
 *  r2  = atags/dtb pointer
 *  r9  = processor ID
 */
        __INIT
__mmap_switched:
        adr     r3, __mmap_switched_data

        ldmia   r3!, {r4, r5, r6, r7}
        cmp     r4, r5                          @ Copy data segment if needed
1:      cmpne   r5, r6
        ldrne   fp, [r4], #4
        strne   fp, [r5], #4
        bne     1b

        mov     fp, #0                          @ Clear BSS (and zero fp)
1:      cmp     r6, r7
        strcc   fp, [r6],#4
        bcc     1b

 ARM(   ldmia   r3, {r4, r5, r6, r7, sp})
 THUMB( ldmia   r3, {r4, r5, r6, r7}    )
 THUMB( ldr     sp, [r3, #16]           )
        str     r9, [r4]                        @ Save processor ID
        str     r1, [r5]                        @ Save machine type
        str     r2, [r6]                        @ Save atags pointer
        cmp     r7, #0
        strne   r0, [r7]                        @ Save control register values
        b       start_kernel
ENDPROC(__mmap_switched)

        .align  2
        .type   __mmap_switched_data, %object
__mmap_switched_data:
        .long   __data_loc                      @ r4
        .long   _sdata                          @ r5
        .long   __bss_start                     @ r6
        .long   _end                            @ r7
        .long   processor_id                    @ r4
        .long   __machine_arch_type             @ r5
        .long   __atags_pointer                 @ r6
#ifdef CONFIG_CPU_CP15
        .long   cr_alignment                    @ r7
#else
        .long   0                               @ r7
#endif
        .long   init_thread_union + THREAD_START_SP @ sp
        .size   __mmap_switched_data, . - __mmap_switched_da

上述代码做了三件事:
1、如果需要,保存数据段信息到__data_loc,_sdata,__bss_start_end变量中;
2、保存r9寄存器的值,即processor ID到processor_id变量中,保存r1寄存器的值,即machine ID到__machine_arch_type中,保存r2寄存器的值,即atags或dtb的地址到__atags_pointer变量中;
3、跳转到start_kernel()这个函数中去执行;

start_kernel()这个函数是C代码实现的。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:13594次
    • 积分:334
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:1篇
    • 译文:2篇
    • 评论:8条
    最新评论