U-boot源码分析之start.s

硬件平台为东南大学自主研发的ARM720T芯片SEP4020

代码目录:cpu/sep4020/start.s

 

#include <config.h>

#include <version.h>

 

/*

 * Jump vector table

 */

 

//_startGNU汇编器默认的入口标签,.global_start声明为外部程序可访问的

.globl _start

//向量跳转表,每条占一个字节,地址范围为0x00000000-0x00000020

//ldrstr指令是用来在存储器和寄存器传递数据的,两者方向相反

//ldr为存储器到寄存器,str为寄存器到存储器

_start: b   reset

       ldr   pc, _undefined_instruction

       ldr   pc, _software_interrupt

       ldr   pc, _prefetch_abort

       ldr   pc, _data_abort

       ldr   pc, _not_used

       ldr   pc, _irq

       ldr   pc, _fiq

 

//.wordGNU ARM汇编特有的伪操作,为分配一段字内存单元(分配的单元为字对齐)

_undefined_instruction: .word undefined_instruction

_software_interrupt:      .word software_interrupt

_prefetch_abort:     .word prefetch_abort

_data_abort:           .word data_abort

_not_used:             .word not_used

_irq:                     .word irq

_fiq:                     .word fiq

 

       .balignl 16,0xdeadbeef

 

 

/*

 *************************************************************************

 *

 * Startup Code (reset vector)

 *

 * do important init only if we don't start from memory!

 * relocate u-boot to ram

 * setup stack

 * jump to second stage

 *

 *************************************************************************

 */

//TEXT_BASE定义了代码运行时所在的地址

_TEXT_BASE:

       .word      TEXT_BASE

 

//_start来初始化_armboot_start

.globl _armboot_start

_armboot_start:

       .word _start

 

/*

 * These are defined in the board-specific linker script.

 */

//_bss_start保存的是_bss_start标号所在的地址

.globl _bss_start

_bss_start:

       .word __bss_start

 

.globl _bss_end

_bss_end:

       .word _end

 

//中断的堆栈设置

#ifdef CONFIG_USE_IRQ

/* IRQ stack memory (calculated at run-time) */

.globl IRQ_STACK_START

IRQ_STACK_START:

       .word      0x0badc0de

 

/* IRQ stack memory (calculated at run-time) */

.globl FIQ_STACK_START

FIQ_STACK_START:

       .word 0x0badc0de

#endif

 

 

/*

 * the actual reset code

 */

//复位后开始初始化CPU的寄存器,这里才是真正CPU的初始化

reset:

       /*stack setup for each mode*/

      

       /* SVC32 mode*/  

       mrs  r0,cpsr           //cpsr寄存器的值传递到通用寄存器r0

       bic   r0,r0,#0x1f     //cpsr5为清零

       orr   r0,r0,#0x13    //cpsr0141,对于sep4020来说M[40]10011,即进入管理模式

       msr  cpsr,r0            //将设置好的值写回cpsr寄存器

       ldr   r0, _TEXT_BASE

       sub  r0, r0, #CFG_MALLOC_LEN

       sub  r0, r0, #CFG_GBL_DATA_SIZE

#ifdef CONFIG_USE_IRQ

       sub  r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

       sub  sp, r0, #12     

 

//以下代码是在SEP4020各个模式下进行配置

//SEP4020的操作模式由cpsr的低五位进行配置

//SEP4020操作模式有:User,FIQ,IRQ,Supervisor,Abort,Undefined,System

 

//如果设置了CONFIG_USE_IRQ,则配置中断模式

#ifdef CONFIG_USE_IRQ

       /* IRQ mode*/

       //配置cpsr0xD2表示:处理器操作模式为中断模式,并且拒绝接收中断和快速中断请求

       mov R4, #0xD2

           msr  cpsr, R4

       //初始化堆栈  

       ldr   r0, _TEXT_BASE

       sub  r0, r0, #CFG_MALLOC_LEN

       sub  r0, r0, #CFG_GBL_DATA_SIZE

       sub  r0, r0, #(CONFIG_STACKSIZE_FIQ)

       sub  sp, r0, #12     

      

 

       /* FIQ mode*/

       //配置cpsr0xD1表示:处理器操作模式为快速中断模式,并且拒绝接收中断和快速中断请求

       mov R4, #0xD1

           msr  cpsr, R4  

       ldr   r0, _TEXT_BASE

       sub  r0, r0, #CFG_MALLOC_LEN

       sub  r0, r0, #CFG_GBL_DATA_SIZE

       sub  sp, r0, #12     

#endif

      

       /* ABORT mode*/

       //配置cpsr0xD7表示:处理器操作模式为中止模式,并且拒绝接收中断和快速中断请求

       mov R4, #0xD7

           msr  cpsr, R4  

       ldr   r0, _TEXT_BASE

       sub  r0, r0, #CFG_MALLOC_LEN

       sub  r0, r0, #CFG_GBL_DATA_SIZE

       sub  sp, r0, #8

      

       /* UNDEFINE mode*/

       //配置cpsr0xDB表示:处理器操作模式为未定义模式,并且拒绝接收中断和快速中断请求

       mov R4, #0xDB

           msr  cpsr, R4  

       ldr   r0, _TEXT_BASE

       sub  r0, r0, #CFG_MALLOC_LEN

       sub  r0, r0, #CFG_GBL_DATA_SIZE

       sub  sp, r0, #4

      

       /* SYSTEM mode*/

       //配置cpsr0xDF表示:处理器操作模式为系统模式,并且拒绝接收中断和快速中断请求

       mov R4, #0xDF

           msr  cpsr, R4  

       ldr   r0, _TEXT_BASE

       sub  r0, r0, #CFG_MALLOC_LEN

       sub  sp, r0, #CFG_GBL_DATA_SIZE

 

       /*Return to SVC mode*/

       //返回SVC模式

       //配置cpsr0xDB表示:处理器操作模式为管理模式,并且拒绝接收中断和快速中断请求 

       mov R4, #0xD3

           msr  cpsr, R4

 

 

       /*

        * we do sys-critical inits only at reboot,

        * not when booting from ram!

        */

 

//如果配置了CONFIG_SKIP_LOWLEVEL_INIT,则初始化CPU

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

       bl    cpu_init_crit

       /*

        * before relocating, we have to setup RAM timing

        * because memory timing is board-dependend, you will

        * find a lowlevel_init.S in your board directory.

        */

       bl    lowlevel_init

#endif

 

remap:

       mov r0, pc

       add  r0,   r0,   #0x20000000

       add  r0,   r0,   #0x08

       mov pc,   r0

 

       mov r0,   r0

       mov r0,   r0

       mov r0,   r0

       mov r0,   r0

 

           ldr   r4,   =0x11000020

      ldr       r5,   =0xb

       str    r5,   [ r4 ]

 

/*

       init BSS section

*/

       ldr r0, = 0

       ldr r1, _bss_start

       ldr r2, _bss_end

bss_init:

       str r0, [r1]

       add r1,r1,#4

       cmp r1,r2

       blt bss_init

 

//U-boot将自己从flash搬移到RAM

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

relocate:                       /* relocate U-Boot to RAM       */

       adr   r0, _start        /* r0 <- current position of code   */

       ldr   r1, _TEXT_BASE         /* test if we run from flash or RAM */

       cmp     r0, r1                  /* don't reloc during debug         */

       beq    vector_copy

//通过比较_start_TEXT_BASE的值来确定U-boot是否在内存中,_TEXT_BASE为连接时存放地址,_start

//为连接时存放地址,若两者不同则表示U-boot当前在内存中

 

       ldr   r2, _armboot_start  //_armboot_start_start地址

       ldr   r3, _bss_start         //_bss_start为数据段地址

       sub  r2, r3, r2        /* r2 <- size of armboot            */

       add  r2, r0, r2        /* r2 <- source end address         */

 

copy_loop:

       ldmia      r0!, {r3-r10}         /* copy from source address [r0]    */

       stmia       r1!, {r3-r10}         /* copy to   target address [r1]    */

       cmp r0, r2                    /* until source end addreee [r2]    */

       ble   copy_loop

 

 

/*

       now copy to sram the interrupt vector

*/

vector_copy:

       ldr   r0, _TEXT_BASE

       add  r2, r0, #128

       ldr   r1, =0x30000000 /*modified by shixq from 0x0c000000 to 0x30000000*/

/*    add  r1, r1, #0x08 *//*deleted by shixq*/

vector_copy_loop:

       ldmia      r0!, {r3-r10}

       stmia       r1!, {r3-r10}

       cmp r0, r2

       ble   vector_copy_loop

#endif     /* CONFIG_SKIP_RELOCATE_UBOOT */

 

       /*enable the irq*/

       mrs  R4, cpsr

           bic   R4, R4, #0x80

           msr  cpsr, R4  

 

       ldr   pc, _start_armboot

 

_start_armboot:      .word start_armboot

//到这里第一阶段结束,进入第二阶段C代码的start_armboot

 

 

 

/*

//CPU初始化,这段初始化代码与具体使用的硬件相关,这里为SEP4020

cpu_init_crit:

       /* PLLCON */

       //配置系统时钟为88M

       ldr r0, =0x10001004    /*72M*/

       ldr   r1, =0x400b          

       str    r1, [r0]

      

       //设置系统启动模式为Normal模式

       ldr r0, =0x10001014    /*Normal*/

       ldr   r1, =0x1

       str    r1, [r0]

      

       //配置系统时钟为88M

       ldr r0, =0x10001004    /*72M*/

       ldr   r1, =0xC00b  

       str    r1, [r0]

 

       //打开系统所有模块时钟

       ldr r0, =0x1000100C   /*open all*/

       ldr   r1, =0xFFFFFFFF

       str    r1, [r0]

 

       /*UARTCON*/

#if 1

       //设置串口每个数据传输的比特数为8,Divisor Latch被访问

       ldr r0, =0x1000500C   /*databit:8*/

       ldr   r1, =0x83

       str    r1, [r0]

 

       //配置波特率为115200,这里波特率寄存器中值为0x002F=88M/16/115200

       ldr r0, =0x10005004    /*baud=9600*/

       ldr   r1, =0x0

       str    r1, [r0]

 

       ldr r0, =0x10005000

       ldr   r1, =0x2F

       str    r1, [r0]

 

       //设置串口每个数据传输的比特数为8,普通寄存器被访问

       ldr r0, =0x1000500C

       ldr   r1, =0x3

       str    r1, [r0]

#endif

       mov pc, lr

 

你可能感兴趣的:(汇编,vector,Flash,System,存储,linker)