linux arm 内核解压后启动过程(注释)

内核版本 3.10.90

内核在解压后执行时会跳转执行的代码为:
arch\arm\kernel\head.S 中的

/*
 * Kernel startup entry point.
 * ---------------------------
 *
 * This is normally called from the decompressor code.  The requirements
 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
 * r1 = machine nr, r2 = atags or dtb pointer.
 *
 * This code is mostly position independent, so if you link the kernel at
 * 0xc0008000, you call this at __pa(0xc0008000).
 *
 * See linux/arch/arm/tools/mach-types for the complete list of machine
 * numbers for r1.
 *
 * We're trying to keep crap to a minimum; DO NOT add any machine specific
 * crap here - that's what the boot loader (or in extreme, well justified
 * circumstances, zImage) is for.
 */
    .arm

    __HEAD
ENTRY(stext) /* linux内核的入口*/

 THUMB(    adr    r9, BSYM(1f)    )    @ Kernel is always entered in ARM.
 THUMB(    bx    r9        )    @ If this is a Thumb-2 kernel,
 THUMB(    .thumb            )    @ switch to Thumb now.
 THUMB(1:            )

#ifdef CONFIG_ARM_VIRT_EXT
    bl    __hyp_stub_install
#endif
    @ ensure svc mode and all interrupts masked
    safe_svcmode_maskall r9

    mrc    p15, 0, r9, c0, c0        @ get processor id
    bl    __lookup_processor_type        @ r5=procinfo r9=cpuid
    movs    r10, r5                @ invalid processor (r5=0)?
 THUMB( it    eq )        @ force fixup-able long branch encoding
    beq    __error_p            @ yes, error 'p'

#ifdef CONFIG_ARM_LPAE
    mrc    p15, 0, r3, c0, c1, 4        @ read ID_MMFR0
    and    r3, r3, #0xf            @ extract VMSA support
    cmp    r3, #5                @ long-descriptor translation table format?
 THUMB( it    lo )                @ force fixup-able long branch encoding
    blo    __error_p            @ only classic page table format
#endif

#ifndef CONFIG_XIP_KERNEL
    adr    r3, 2f
    ldmia    r3, {r4, r8}
    sub    r4, r3, r4            @ (PHYS_OFFSET - PAGE_OFFSET)
    add    r8, r8, r4            @ PHYS_OFFSET
#else
    ldr    r8, =PLAT_PHYS_OFFSET        @ always constant in this case
#endif

    /*
     * r1 = machine no, r2 = atags or dtb,
     * r8 = phys_offset, r9 = cpuid, r10 = procinfo
     */
    bl    __vet_atags
#ifdef CONFIG_SMP_ON_UP
    bl    __fixup_smp
#endif
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
    bl    __fixup_pv_table
#endif
    bl    __create_page_tables  /* 创建原始的页表,为 mmu 开启做准备*/

    /*
     * The following calls CPU specific code in a position independent
     * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of
     * xxx_proc_info structure selected by __lookup_processor_type
     * above.  On return, the CPU will be ready for the MMU to be
     * turned on, and r0 will hold the CPU control register value.
     */
    ldr    r13, =__mmap_switched        @ address to jump to after
                        @ mmu has been enabled  /* 最后在 __enable_mmu 里调用到
                                                 * __mmap_switched --> start_kernel
                                                 */
    adr    lr, BSYM(1f)            @ return (PIC) address
    mov    r8, r4                @ set TTBR1 to swapper_pg_dir
 ARM(    add    pc, r10, #PROCINFO_INITFUNC    )
 THUMB(    add    r12, r10, #PROCINFO_INITFUNC    )
 THUMB(    mov    pc, r12                )
1:    b    __enable_mmu  /* 会跳转执行r13中的指令,即 __mmap_switched --> start_kernel */
ENDPROC(stext)

 

__mmap_switched 定义在  arch\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)
                            /* .long    __bss_start            @ r6
                             * .long    _end                @ r7
                             * 参考 arch\arm\kernel\vmlinux.lds.S 中的
                             * BSS_SECTION(0, 0, 0)
                             */
1:    cmp    r6, r7
    strcc    fp, [r6],#4
    bcc    1b

 ARM(    ldmia    r3, {r4, r5, r6, r7, sp})
                            /* .long    init_thread_union + THREAD_START_SP @ sp
                             * 建立栈指针
                             */
 THUMB(    ldmia    r3, {r4, r5, r6, r7}    )
 THUMB(    ldr    sp, [r3, #16]        )
    str    r9, [r4]            @ Save processor ID
                            /* .long    processor_id            @ r4
                             * 使得  processor_id 在 c 中有值
                             */
    str    r1, [r5]            @ Save machine type
                            /* .long    __machine_arch_type        @ r5
                             * 使得 __machine_arch_type 在 C 中有值
                             */
    str    r2, [r6]            @ Save atags pointer
                            /* .long    __atags_pointer            @ r6
                             * 使得 __atags_pointer 在 c中有值
                             */
    cmp    r7, #0
    bicne    r4, r0, #CR_A            @ Clear 'A' bit
    stmneia    r7, {r0, r4}            @ Save control register values
    b    start_kernel    /* 跳转至C代码 */
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_data


  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值