Linux启动流程导读(arm为例)

arm为例,分析一下kernel的启动过程;

内核版本:linux-3.2.tar.gz

一、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                          @#define __HEAD  .section ".head.text","ax"
 ENTRY(stext)
 
  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:            )
 
     setmode    PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode   关闭普通中断,快速中断,使能svc模式
                         @ and irqs disabled
     mrc    p15, 0, r9, c0, c0        @ get processor id         获得芯片ID
     bl    __lookup_processor_type        @ r5=procinfo r9=cpuid 获得处理器型号,r5 == id,#1
     movs    r10, r5                @ invalid processor (r5=0)?  校验正确性,0错误
  THUMB( it    eq )        @ force fixup-able long branch encoding
     beq    __error_p            @ yes, error 'p'
 
 #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

==========

#1 :arch/arm/kernel/head-common.h

==========

/*
  * 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.
  *
  *    r9 = cpuid
  * Returns:
  *    r3, r4, r6 corrupted
  *    r5 = proc_info pointer in physical address space
  *    r9 = cpuid (preserved)
  */
     __CPUINIT
 __lookup_processor_type:
     adr    r3, __lookup_processor_type_data        @adr 相对偏移读取,读取下面type_data地址
     ldmia    r3, {r4 - r6}       @将该地址存放的值 放入r4(.),r5(begin),r6(end)
     sub    r3, r3, r4            @ get offset between virt&phys   链接地址-实际地址=偏移量

==========

继续arch/arm/kernel/head.s

==========

/*
      * r1 = machine no, r2 = atags or dtb,
      * r8 = phys_offset, r9 = cpuid, r10 = procinfo
      */
     bl    __vet_atags       @#1,head-common.s
 #ifdef CONFIG_SMP_ON_UP
     bl    __fixup_smp       @略
 #endif
 #ifdef CONFIG_ARM_PATCH_PHYS_VIRT
     bl    __fixup_pv_table  @略
 #endif
     bl    __create_page_tables  @#2

==========

#1 :arch/arm/kernel/head-common.h

==========

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/22665.html