免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1878 | 回复: 0
打印 上一主题 下一主题

1.2 uboot分析之start.S详细分析(1) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-14 19:22 |只看该作者 |倒序浏览

1.2 uboot之start.S源码详细分析
     本文详细分析start.s文件--->
由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成,这在board/prochip/UB4020/u-boot.lds可以找到,u-boot的程序入口为_start,在cpu/sep4020/start.S中。
1.设置异常向量表
.globl _start                   /* 声明标量是全局函数,CPU加电启动后,就从这里执行代码*/
_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                   /* 快速中断异常向量 */
_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,oxdeadbeef
.word  {,} …              插入一个32位的数据队列。可以使用.word把标识符作为常量使用。
ldr pc,_irq                                                 从内存的某个位置读取数据并且赋值给pc,但是偏移量是那个位置的链接(运行)地址。
.balignl 16,0xdeadbeef                              这条指令把deadbeef字符串填充进去,一共填到地址为16对齐的地方为止。
下面定义了几个全局变量,在后面的代码搬运,申请空间中将会用到:
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!如果不是从内存启动,做一些重要的初始化工作
* relocate u-boot to ram 搬运u-boot到ram中
* setup stack 设置堆栈
* jump to second stage 跳转到第二阶段
*
*************************************************************************
*/

_TEXT_BASE:
         .word         TEXT_BASE                       //程序在SDRAM运行的起始地址,即链接基地址,在/board/prochip/UB4020/config.mk中定义为0x30700000
.globl _armboot_start
_armboot_start:
         .word _start                                     //程序运行起始地址,其实是FLASH中程序的起始地址
/*
* These are defined in the board-specific linker script.这些变量定义在板级的链接脚本中
*/
.globl _bss_start
_bss_start:
         .word __bss_start                            //bss段的链接起始地址
.globl _bss_end
_bss_end:
         .word _end                                      //bss段的连接结束地址
         
2.复位时切换到SVC32模式,并设置各个模式下的堆栈
/*
* the actual reset code 真正的复位代码
*/

reset:
         /*stack setup for each mode 设置各个模式下的堆栈*/
         
         /* SVC32 mode*/         
         mrs   r0,cpsr
         bic     r0,r0,#0x1f
         orr     r0,r0,#0x13
         msr   cpsr,r0
//以下这段代码对不是从NAND FLASH启动的代码才有作用,因为从NAND FLASH启动,已经把uboot
//搬运到了SDRAM中。
         ldr     r0, _TEXT_BASE
         sub    r0, r0, #CFG_MALLOC_LEN                //动态缓冲区和全局环境变量大小
         sub    r0, r0, #CFG_GBL_DATA_SIZE            //uboot唯一的全局变量区大小
#ifdef CONFIG_USE_IRQ
         sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
         sub    sp, r0, #12  


#ifdef CONFIG_USE_IRQ
         /* IRQ mode*/
         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*/
         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*/
         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*/
         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*/
         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*/      
         mov  R4, #0xD3
    msr   cpsr, R4
         各模式下堆栈设置完毕之后的内存分布图如下所示:
         注意:ARM是满递减堆栈。。。
  
_TEXT_BASE
CFG_GBL_DATASIZE
CFG_MALLOC_LEN
SP_USR&SP_SYSTEM
4字节
SP_UNDEFINE
4字节
4字节
SP_ABORT
CONFIG_STACKSIZE_FIQ
SP_FIQ
CONFIG_STACKSIZE_IRQ
SP_IRQ
低地址
高地址
_TEXT_BASE
CFG_GBL_DATASIZE
CFG_MALLOC_LEN
SP_USR&SP_SYSTEM
4字节
SP_UNDEFINE
4字节
4字节
SP_ABORT
CONFIG_STACKSIZE_FIQ
SP_FIQ
CONFIG_STACKSIZE_IRQ
SP_IRQ
低地址
高地址
_TEXT_BASE
CFG_GBL_DATASIZE
CFG_MALLOC_LEN
SP_USR&SP_SYSTEM
4字节
SP_UNDEFINE
4字节
4字节
SP_ABORT
CONFIG_STACKSIZE_FIQ
SP_FIQ
CONFIG_STACKSIZE_IRQ
SP_IRQ
低地址
高地址

3.进行CPU初始化(频率、正常模式、打开所有模块、串口、SDRAM时序参数)
         /*
          * we do sys-critical inits only at reboot, 我们只在重新启动的时候才进行系统重要部分初始化
          * not when booting from ram!                从ram中启动的时候不执行
          */

#ifndef CONFIG_SKIP_LOWLEVEL_INIT   //这个很关键
         bl      cpu_init_crit        //跳转到cpu初始化部分
         /*
          * before relocating, we have to setup RAM timing 在加载之前,先设置RAM的时序
          * because memory timing is board-dependend, you will 因为RAM因板子的不同而不同
          * find a lowlevel_init.S in your board directory. 在你板子目录里找到lowlevel_init.S这个文件
          */
         bl      lowlevel_init        //跳转到配置EMI即SDRAM时序参数部分
#endif
         cpu_init_crit代码如下:
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers   设置重要的寄存器
* setup memory timing        设置存储器的时序
*
*************************************************************************
*/

cpu_init_crit:
         /* PLLCON */
         ldr    r0, =0x10001004          /*88M*/
         ldr     r1, =0x400B                 
         str     r1, [r0]

         ldr    r0, =0x10001014          /*Normal*/
         ldr     r1, =0x1
         str     r1, [r0]
         
         ldr    r0, =0x10001004          /*88M*/              //配置系统频率为88MHZ
         ldr     r1, =0xC00B               
         str     r1, [r0]

         ldr    r0, =0x1000100C         /*打开系统所有模块*/
         ldr     r1, =0xFFFFFFFF
         str     r1, [r0]

         /*UARTCON*/                     //进行串口的配置
#if 1
         ldr    r0, =0x1000500C         /*databit:8*/
         ldr     r1, =0x83
         str     r1, [r0]

         ldr    r0, =0x10005004                   /*baud=9600*/
         ldr     r1, =0x0
         str     r1, [r0]

         ldr    r0, =0x10005000
         ldr     r1, =0x2F
         str     r1, [r0]

         ldr    r0, =0x1000500C
         ldr     r1, =0x3
         str     r1, [r0]
#endif
         mov  pc, lr                             //程序返回
         以下是low_level_init.S中的lowlevel_init代码
.globl lowlevel_init
lowlevel_init:
    ldr    r4,    =EMI_CSECONF
    ldr    r5,    =0x8ca6a6a1                 //配置SDRAM参数
    str    r5,    [ r4 ]

    ldr    r4,    =EMI_SDCONF1
    ldr    r5,    =0x1E184177
    str    r5,    [ r4 ]

    ldr    r4,    =EMI_SDCONF2
    ldr    r5,    =0x80001860
    str    r5,    [ r4 ]
         
    mov pc, lr                                //程序返回



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/107770/showart_2121210.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP