uboot启动流程分析之一

最开始的就是start.S



<pre name="code" class="html"> 一个可执行的Image 必须有一个入口点并且只能有一个唯一的全局入口,通常这个入口放在Rom(flash)的0x0地址。
start.S
· _start:
<span style="font-family: Arial, Helvetica, sans-serif;"> /*异常向量表*/</span><pre code_snippet_id="650016" snippet_file_name="blog_20150422_2_4063097" name="code" class="plain">  /*大小32个字节,每个异常占据4个字节,保留4个字节空间*/<pre code_snippet_id="650016" snippet_file_name="blog_20150422_3_8027903" name="code" class="plain">  /*将异常中断处理程序注册到向量表,或使用跳转指令或使用数据  
    *读取指令LDR向PC中直接赋值
    */<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
 
 
 
//声明-----------
·  breset             /*复位,可能出现情况:系统加电,系统复位*/
·  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                    /*快速异常中断,响应时间要求高*/
/*中断程序入口地址*/
·  _undefined_instruction:     .wordirq_undefined_instruction
·  _software_interrupt:          .word irq_software_interrupt 
·  _prefetch_abort:                .word irq_prefetch_abort 
·  _data_abort:                       .word irq_data_abort
·  _not_used:                         .word irq_not_used
·  _irq:                                   .word irq_irq
·  _fiq:                                   .word irq_firq
·  _pad1:                                .word 0x12345678
               .....


·  /* 
·   *  复位程序入口 
·   */  
·  reset:                                        //上电触发reset 
·    /* 
·   *MCU  微控制单元准备   
·   */ 
·   ldr  r0, =0x100 
·    delay_wait_mcu:   
·   sub r0, #1            
·   cmp  r0, #0                    //判断MCU是否准备好
·   bne delay_wait_mcu 
·  
·   ldr r0, =REG_BASE_SCTL 
·  mov r1, #0 
·  wait_mux_finish: 
·   add r1, r1, #1 
·  str r1, [r0, #REG_SC_GEN1]      /*系统通用寄存器0x0084*/ 
·   ldr r2, [r0, #REG_SC_GEN1]
·   cmp  r1, r2
·  bne wait_mux_finish         /*确保地址范围是可读写的 RAM 空间*/


·  mrs  r1,cpsr
          /*将CPSR状态寄存器读取,保存到r1中  保存标志位FIQ.r8-10*/
·  bic  r2, r1, #0x1f          /*反码0x1110 0000    低五位清零*/
·  orr  r2, r2, #0xd1        /*或  0x1101 0001*/
·  msr cpsr,r2
·  adrl  r8,_start              /*取地址       分组寄存器fiq单独的物理寄存器*/
·  mov r9,r3
·  mov r10,r4
·  msr cpsr, r1


   /初始化PLL  DDR  PIN/
·  /*PLL(统一脉冲信号)/DDR/pin mux 引脚/...* /
·  ldr r0, _blank_zone_start
·  ldr r1, _TEXT_BASE
·  sub r0, r0,r1
·  add r0, r0,#RAM_START_ADRS
·  mov r1, #0x0                /* flags: 0->normal 1->pm*/
·  mov r2, #INIT_REG_ITEM1
·  bl  init_registers



/屏蔽中断/
/*设置为SVC32模式  系统模式*/
·  mrs r0, cpsr
               /*将状态寄存器的内容传送至通用寄存器,将CPSR中的内容传送至R0保存当前处理器状态,中断屏蔽位以及各标志位*/
·   bic  r0,r0,#0x1f          /*位清除指令  将R0最低5位清零,其余位不变工作模式位清零     工作模式位清零,设置CPSR中相应的位,使处理器进入相应的执行模式*/
·   orrr0,r0,#0xd3/*r0=(0xd3|r0)*/          /*工作模式位设置为10011,将中断禁止位和快中断位置1               "1101 0011" 指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中*/ 
·  msr cpsr, r0                                               /*将通用寄存器的内容传送至状态寄存器,将中的内容R0传送至CPSR*/ 

/*初始化串口*/
 bl  uart_early_init

/检查启动介质     NAND/SPI/EMMC  FLASH/
·  cmp  r6, #BOOT_FROM_NAND                     /*判断启动介质*/   
·  bne  check_from_spi 

·  cmp r0,#0x01 
·  bne  check_from_nand

·   cmp r6, #BOOT_FROM_SPI 
·   bne check_from_emmc 

标准操作:

·   /*i-cache初始化               指令cache 与数据cache*/ 
·  mrc p15, 0, r0, c1, c0, 0   
·  orr r0, r0, #0x00001000 
·  mcr p15, 0, r0, c1, c0, 0 

/*关闭MCU*/ 
·  #ldr  r0,=0xf840f000 
·  #ldr  r1,[r0] 
·  #bic    r1,r1,#0x1 
·  #str    r1,[r0] 
·  
/*时钟*/
·  # ldr    r0,=REG_BASE_TIMER01 
·  #mov   r1,#0 
·  #str    r1,[r0,#REG_TIMER_CONTROL] 
·  
/*看门狗*/
·  # mov     r1,#0 
·  # str  r1,[r4,#REG_SC_WDG_RST_CTRL] 

/*初始化寄存器1*/ 
·  normal_init_item1: 
·  ldr r0,_blank_zone_start 
·  ldr r1, _TEXT_BASE 
·  subr0,r0,r1 
·  ldr r1,[r4,#REG_SC_GEN14] 
·  add r0,r0,r1
·  mov r1,#0x0 /*flags:0->normal1->pm*/ 
·  mov r2,#INIT_REG_ITEM1 
·  bl init_registers 
·  b normal_init_item2 



·  copy_to_ddr:                        /*重定位uboot*/ 
·  ldr r4,=REG_BASE_SCTL 
·  ldr r0, [r4, #REG_SC_GEN14] 
·                   /*r0存放的是程序开始的地址*/

 

·  ldr r1, _TEXT_BASE            /* r1 存放的是内存中的地址* 
·  
·   /* 比较两个地址是否相等*/ 
·   cmp  r0,r1 
·   beq stack_setup                      /* 比较r0/r1是否相等,这个比较就是确定当前是不是从Flash中执行的,还是这段代码已装载到_TEXT_BASE处执行的。如果不等,则将 FLASH中的u-boot代码搬到_TEXT_BASE处。*/ 


·如果不等  
·  ldr r2,_armboot_start 
·  ldrr3,_bss_start                      /*flash中存储的u-boot可执行文件中,代码段、数据段以及BSS段都是首尾相连存储的,所以在计算搬移大小的时候就是利用了用BSS段的首地址减去代码的首地址,这样算出来的就是实际使用的空间。*/  
·   sub  r2,r3,r2 
·   /*memcpy(r1,r0,r2)*/
    /*r1存放的是TEXT_BASE*/ 
·  bl  memcpy 
·   


·  stack_setup:                                                                         /*设置栈*/ 
·   ldr  r0,_TEXT_BASE       /*往上128KB是重定位的uboot*/ 
·   sub r0,r0,#CONFIG_BOOTHEAD_GAP 
·   sub r0, r0,#CONFIG_SYS_MALLOC_LEN 
      /* 向下分配空间   因为u-boot中其它地方调用了malloc函数,该空间就是供其动态分配的。*/ 
·   sub r0,r0,#CONFIG_SYS_GBL_DATA_SIZE 
 /*全局数据区   为global_data结构体预留的空间*/ 
·   sub sp,r0,#12       /*为取址中止异常留三个字*/ 
·   and sp,sp,#~7            /*用户栈顶*/ 
·   
·   /*清零BSS段*/
·  clear_bss:
·  ldr r0,_bss_start
·  ldr r1,_bss_end
·  mov r2,#0x00000000
·  
·  clear_bss_loop:
·  str r2,[r0]               /*清零*/
·  cmp r0, r1                 //是否清理到段尾
·  add r0, r0, #4   //移动指针
·  bne clear_bss_loop


 /*执行C程序,board.c参数r0,r1,r2*/
·  ldr pc,_start_armboot
·  _start_armboot: .word start_armboot



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值