现在的位置: 首页 > 综合 > 正文

K60系列学习(四)Start.s启动代码分析

2018年03月31日 ⁄ 综合 ⁄ 共 6575字 ⁄ 字号 评论关闭
=源代码Start.s=
.section .vector, "a"
    .global init_vector
    .code 16
    .syntax unified
 init_vector:
    .word   __onchip_ram_end,system_start
    .word   0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    .word   0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0   
    .word   0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE
    
    .text
    .global system_start
	.code 16
	.syntax unified
	.type system_start, function
system_start:
	cpsid f   /* disable all exceptions */

	/* 初始化GPRs */
	mov     r0,#0
	mov     r1,#0
	mov     r2,#0
	mov     r3,#0
	mov     r4,#0
	mov     r5,#0
	mov     r6,#0
	mov     r7,#0
	mov     r8,#0
	mov     r9,#0
	mov     r10,#0
	mov     r11,#0
	mov     r12,#0

    /*
	 *  msp setting
     */
	mov r0, #0
	msr control, r0
	isb

	/*
     * set default stack pointer
     */
	ldr r0, =__onchip_ram_end
	msr msp, r0

	ldr r0, =hardware_init_hook
    cbz r0, init_phase1
	blx r0

init_phase1:
	/*
     * set application stack pointer
     */
	/*ldr r0, =p_system_stack
	ldr r1, [r0]
	msr msp, r1*/

    b __cs3_start_c

==代码分析==
-  (1).word
   * .word的含义就是在当前位置放置一个word的类型的值,值的大小就是.word后面描述的这样.
   如.word   0x0,0x0,0x0,0x0,0x0,0x0的含义就是在此处连续的6个32位地址空间中放置0x0
   * 代码中总共从定义.vector之后的__onchip_ram_end,system_start后连续的254个32位的地址空间中放置0x0.再通过链接脚本的作用,完成了烧写到flash空间中,将向量表中的前两个值分别付给SP堆栈指针寄存器和PC程序计数寄存器,并初始化向量表的过程.烧写到Flash的时候,向量表的物理地址为[0x0000_0000]
-  (2).section name
   .section命令用来产生一个名叫name的段,对于ELF类型的目标文件,.section命令的使用格式如下:
   .section name [, "flags"[, @type[,flag_specific_arguments]]]
   * flags的使用如下:
      # a section is allocatable
      # e section is excluded from executable and shared library.
      # w section is writable   
      # x section is executable
      # M section is mergeable (可合并的)
      # S section contains zero terminated strings
      # G section is a member of a section group
      # T section is used for thread-local-storage(线程本地存储区)
   * @type 和 flag_specific_arguments两个参数的具体使用参见as Manual
   * 故代码中.section .vector, "a" 的含义是产生一个名叫.vector的allocatable的段
-  (3).global symbol
   * .global指令用于设置symbol对ld链接器可见.即就是对其他与start.S生成的目标文件进行链接的文件而言symbol也是可见的.
   * 故.global init_vector的含义就是使init_vector对链接器可见.
-  (4).code [16|32]
   由于历史原因,ARM处理其一直支持两种形式上相对独立的指令集,分别是:
   * 32位的ARM指令集,对应的处理器状态为ARM状态
   * 16位的Thumb指令集,对应处理器状态为Thumb状态
   * This directive selects the instruction set being generated. The value 16 selects Thumb, with the value 32 selecting ARM.
   * 处理器在执行过程中,动态的在两种执行状态中间切换,Thumb指令集ARM指令集的一个子集,但能带来更高的代码密度,适合于资源比较紧张的应用.
   * The Cortex M4 processor is based on the ARMv7 Architecture and Thumb®-2 ISA and is upward compatible with the Cortex M3,Cortex M1, and Cortex M0 architectures. Cortex M4 improvements include an ARMv7 Thumb-2 DSP (ported from the ARMv7-A/R profile architectures)
providing 32-bit instructions with SIMD (single instruction multiple data) DSP style multiply-accumulates and saturating arithmetic
   * 故代码中.code 16的含义是选择Thumb指令集.
-  (5) .syntax [unifed | divided]
   * Arm处理器对应的两种指令集存在两种语法格式,
     # 选择divided即就是允许Thumb和ARM分别有自己独立的语法格式.
     # 选择unifed允许二者使用统一的语法格式.详情参见as Manual
-  (6).type
   * 对于ELF类型的目标文件,.type的使用格式如下:
     .type name , type description
   * 这条指令用来将name的类型指定为type description所述.
   * type description有如下几种
     # function
     Mark the symbol as being a function name.
     # gnu_indirect_function  
     Mark the symbol as an indirect function when evaluated during reloc processing.(This is only supported on Linux targeted assemblers).
     # object
     Mark the symbol as being a data object.
     # tls_object
     Mark the symbol as being a thead-local data object.
     # common
     Mark the symbol as being a common data object.
     # notype
     Does not mark the symbol in any way. It is supported just for completeness.
     # gnu_unique_object
     Marks the symbol as being a globally unique data object. The dynamic linker will make sure that in the entire process there is just one symbol with this name and type in use. (This is only supported on Linux targeted assemblers)
   * 故 .type system_start, function 的含义是system_start标记为一个function名称
-  (6)
    == cpsid  ==
    - 这条汇编指令实际上是CPS汇编指令的衍生,CPS(Change Process State)
    - CPS的使用格式为:CPSeffect iflags由此CPS衍生出来的指令有:
      # CPSID i : Disable interrupts and configurable fault handles (set PRIMASK)
      # CPSID f : Disable interrupts and all fault handles(set FAULTMASK)
      # CPSIE i : Enable interrupts and configurable fault handles(clear PRIMASK)
      # CPSIE f : Enable interrupts and all fault handles (clear FAULTMASK)
    - FAULTMASK
      * Fault Mask Register
      * The FAULTMASK register prevents activation of all exceptions except for Non-Maskable Interrupt (NMI).
    - PRIMASK
      * Priority Mask Register
      * The PRIMASK register prevents activation of all exceptions with configurable priority.

   == MSR  ==
    - Move the contents of a general-purpose register into the specified special register.
    - 指令格式:MSR{cond} spec_reg, Rn  (cond表示这条指令存在对于条件标志符的操作)
      * cond :Is an optional condition code
      * Rn :Specifies the source register.
      * spec_reg: Can be any of: APSR_nzcvq, APSR_g, APSR_nzcvqg, MSP, PSP, PRIMASK, BASEPRI, BASEPRI_MAX, FAULTMASK, or CONTROL.
      * 特殊功能寄存器CONTROL
        # 控制寄存器主要的用途:
          * 定义特权级别 CONTROL[0]
          * 选择当前使用哪个堆栈指针CONTROL[1]
          * 在实现浮点数的时候,指示浮点数功能是否激活CONTROL[2]
        # nPRIV  --CONTROL[0]
          Cortex-M4处理器支持两种处理器的操作模式,线程模式和handler模式,线程模式用于执行应用程序,handler模式用于执行异常处理程序.
          * 0=特权级的线程模式
          * 1=用户级的线程模式
          * handler模式永远只存在特权级
        # SPSEL  --CONTROL[1]
          * 0=选择主堆栈指针MSP
          * 1=选择进程堆栈指针PSP
          * 线程模式下,可以使用PSP,但是handle模式下只允许使用MSP
        # FPCA   --CONTROL[2]
          * 0=no floating point context active
          * 1=floating point context active
          * Cortex-M4处理器根据这一位来判断在处理异常时是否保存浮点状态

   == MRS  ==
   Move the contents of a special register to a general-purpose register

   == LDR  ==
    - 指令含义 LDR loads a register with a value from a PC-relative memory address.
    - 指令格式 LDR{type}{cond} Rt, label
    * Rt 指定用加载或者存储的寄存器
    * label 一个相对于PC指针的表达式.它的值根据label和当前指令的地址进行计算.
   ==cbz==
    - 指令的含义是:Compare and Branch on Zero.
    - 指令的格式为: CBZ Rn, label
      * Rn 代表的是存储操作数的通用寄存器,且Rn必须是R0到R7之间的.
      * label代表的是程序分支
    - 使用cbz实现跳转的优势在于可以避免对于condition flag的操作,进而可以减少指令数量
    - 另指令cbnz的含义是Compare and Branch on Non-zero
    - 故代码中cbz r0, init_phase1的含义是 判断r0是否为0,为0则跳转到分支init_phase1中,如果不为0,则执行下一条指令.

   ==blx==
    - blx r0的含义是Branch with link and exchange to a address stored in R0.
    - Branch with link 的含义就是在完成分支跳转的同时,自动填充LR(Link Register)的值 

抱歉!评论已关闭.