Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1570007
  • 博文数量: 204
  • 博客积分: 2215
  • 博客等级: 大尉
  • 技术积分: 4426
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-06 08:03
个人简介

气质,源于心灵的自信!

文章存档

2018年(1)

2017年(1)

2016年(1)

2015年(18)

2014年(20)

2013年(30)

2012年(119)

2011年(14)

分类: 嵌入式

2011-08-13 14:07:50

由于近来一直在看uboot,所以也做个uboot的启动分析,针对的是uboot-2011.3的代码,主要是对代码进行注释,废话就不多说啦,开始贴代码和注释。

/*注释uboot-2011.3 shangbaogen-2011-8-13*/
.globl _start                   /*声明一个全局变量符号,供外部函数使用*/
_start: b start_code            /*处理器上电后执行的第一天指令,该条指令占四个字节*/
 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,0xdeadbeef
/*上面的一共15条指令,每条指令占四个字节,一共15*4=60字节,
  又用四个字节(死牛肉)填充,刚好64字节,以16字节对齐*/
/*
 *************************************************************************
 *
 * Startup Code (called from the ARM reset exception vector)
 *
 * do important init only if we don't start from memory!
 * relocate armboot to ram
 * setup stack
 * jump to second stage
 *
 *************************************************************************
 */
.globl _TEXT_BASE                /*声明一个全局变量,供外部函数使用*/
 
/*分配一个字的空间,用与存放链接地址,
*该变量定义的u-boot-2011.03\board\samsung\smdk2410\config.mk,
*变量的值为CONFIG_SYS_TEXT_BASE = 0x33F80000*/
_TEXT_BASE:
  .word CONFIG_SYS_TEXT_BASE
 
/*
 * These are defined in the board-specific linker script.
 * Subtracting _start from them lets the linker put their
 * relative position in the executable instead of leaving
 * them null.
 */

/*其中__bss_start,__bss_end__,_end都是定义在链接脚本文件u-boot-2011.03\arch\arm\cpu\arm920t\uboot.lds中*/
.globl _bss_start_ofs         /*声明一个bss段开始地址偏移量的全局变量供外部函数使用*/
_bss_start_ofs:               /*分配一个四字节的空间用于存放bss段开始地址的偏移量*/
 .word __bss_start - _start
.globl _bss_end_ofs           /*声明一个bss段结束地址偏移量的全局变量供外部函数使用*/
_bss_end_ofs:                 /*分配一个四字节的空间用于存放bss段结束地址的偏移量*/
 .word __bss_end__ - _start
.globl _end_ofs               /*声明一个_end标号结束地址偏移量的全局变量供外部函数使用*/
_end_ofs:
 .word _end - _start
                              /*到此上面共分配了64+16=80字节*/
 
#ifdef CONFIG_USE_IRQ         /*如果定义了CONFIG_USE_IRQ,则分配irq栈空间*/
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:              /*分配四个字节用于存放irq栈空间的起始地址*/
 .word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START       /*分配四个字节用于存放fiq栈空间的起始地址*/
FIQ_STACK_START:
 .word 0x0badc0de
#endif
/* IRQ stack memory (calculated at run-time) + 8 bytes */
.globl IRQ_STACK_START_IN    /*分配四个字节用于存放irq栈空间的起始地址*/
IRQ_STACK_START_IN:
 .word 0x0badc0de
/*
 * the actual start code
 */
                            /*上电后会执行如下标号地址指令*/
start_code:                 /*该标号地址的指令的作用是设置cpu为管理模式,并且关闭irq,fiq中断*/
 /*
  * set the cpu to SVC32 mode
  */
 mrs r0, cpsr
 bic r0, r0, #0x1f       /*设置cpu为管理模式*/
 orr r0, r0, #0xd3       /*关闭irq,fiq中断*/
 msr cpsr, r0
 
/*下面的是针对AT91RM9200的配置,不分析*/
#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
 /*
  * relocate exception table
  */
 ldr r0, =_start
 ldr r1, =0x0
 mov r2, #16
copyex:
 subs r2, r2, #1
 ldr r3, [r0], #4
 str r3, [r1], #4
 bne copyex
#endif
 
/*如果定义了s3c24x0则做如下设置,CONFIG_S3C24X0在\u-boot-2011.03\include\configs\smdk2410.h 定义为#define CONFIG_S3C24X0 1 */
#ifdef CONFIG_S3C24X0  /* turn off the watchdog */
# if defined(CONFIG_S3C2400)     /*如果是s3c2400寄存器,则定义如下宏*/
#  define pWTCON 0x15300000
#  define INTMSK 0x14400008      /* Interupt-Controller base addresses */
#  define CLKDIVN 0x14800014     /* clock divisor register */
#else                            /*否则定义如下宏,s3c2410用到的寄存器*/
#  define pWTCON 0x53000000      /*watch dog 寄存器的基址*/
#  define INTMSK 0x4A000008      /*中断控制器一级掩码寄存器地址*/
#  define INTSUBMSK 0x4A00001C   /*中断控制器二级掩码寄存器地址*/
#  define CLKDIVN 0x4C000014     /* 分频寄存器的地址*/
# endif
 
 /*关闭看门狗*/
 ldr r0, =pWTCON
 mov r1, #0x0
 str r1, [r0]
 /*
  * mask all IRQs by setting all bits in the INTMR - default
  */

 /*设置所有的中断掩码,屏蔽所有一级中断*/
 mov r1, #0xffffffff
 ldr r0, =INTMSK
 str r1, [r0]
 
# if defined(CONFIG_S3C2410)/*如果定义了s3c2410则屏蔽如下二级中断*/
 ldr r1, =0x3ff
 ldr r0, =INTSUBMSK
 str r1, [r0]
# endif
 
/*下面是针对s3c2440做的移植*/
# if defined(CONFIG_S3C2440)       /*如果定义了s3c2440,则做如下操作*/
#  define LOCKTIME  0x4C000000     /*定义LOCKTIME的基址*/
#  define MPLLCON  0x4C000004      /*定义MPLLCON的基址*/
#  define UPLLCON  0x4C000008      /*定义UPLLCON的基址*/
#  define CLKDIV_VAL 5
#  define M_MDIV 0x7f    /* XTal=12.0MHz MPLL=405MHz */
#  define M_PDIV 2
#  define M_SDIV 1
#  define U_MDIV 0x38    /* XTal=12.0MHz UPLL=48MHz */
#  define U_PDIV 2
#  define U_SDIV 2
 
 /*针对s3c2440屏蔽如下二级中断*/
 ldr r1, =0x7fff
 ldr r0, =INTSUBMSK
 str r1, [r0]
 
 /*设置在时钟稳定前的锁定时间*/
 ldr r0,=LOCKTIME      /* 设置U_LTIME和M_LTIME */
 ldr r1,=0x0fff0fff
 str r1,[r0]
 
 /*设置 Fclk:Hclk:Pclk = 1:4:8 */
 ldr r0, =CLKDIVN      /* Fclk:Hclk:Pclk = 1:4:8 */
 ldr r1, =CLKDIV_VAL
 str r1, [r0]
 
 /* 总线模式设为异步模式 */
 mrc p15, 0, r0, c1, c0, 0   
 orr r0, r0, #0xc0000000
 mcr p15, 0, r0, c1, c0, 0
 
 /* 配置UPLL ,该配置专用于usb*/
 ldr r0,=UPLLCON      
 ldr r1,=((U_MDIV<<12) + (U_PDIV<<4) + U_SDIV) 
 str r1,[r0]
 
 /* 为确保硬件完成操作,至少需7个时钟周期的延迟时间*/
 nop             
 nop
 nop
 nop
 nop
 nop
 nop
 
 /* 配置MPLL ,该配置用于设置Fclk:Hclk:Pclk*/
 ldr r0,=MPLLCON      
 ldr r1,=((M_MDIV<<12) + (M_PDIV<<4) + M_SDIV)
 str r1,[r0]
 
#else /*否则设置分频比为FCLK:HCLK:PCLK = 1:2:4 */
 /* FCLK:HCLK:PCLK = 1:2:4 */
 /* default FCLK is 120 MHz ! */
 ldr r0, =CLKDIVN
 mov r1, #3
 str r1, [r0]
#endif /* CONFIG_S3C2440 */
#endif /* CONFIG_S3C24X0 */
 /*
  * we do sys-critical inits only at reboot,
  * not when booting from ram!
  */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT /*该宏用于直接下载到内存中调试用的*/
 bl cpu_init_crit                /*该函数用于I/D caech,tlb的刷新,以及mmu的设置,sdram的设置*/
#endif
 
剩下的分析请看下一篇博文。
阅读(4707) | 评论(1) | 转发(7) |
给主人留下些什么吧!~~

yibaojia2013-06-25 21:16:20

楼主给力啊!但楼主的这个第一阶段还是不能工作的吧!  如果楼主把_TEXT_BASE 的值改为0x3ff80000的话。说明楼主已经把SDRAM的u-boot代码区给分配了,就不需要board_init_f 自己分配了,   所以要在 board_init_f 里面做修改,到调用relocate_code ,代码搬移的时候通过r6再传递给relocate_code ,代码搬移后也不需要“pie”搞的段里面的数据重定位了,即不需要fix .rel.dyn relocations 这段代码重新修改地址值了;因为在一开始楼主已经把链接地址写死,定位在0x3ff80000。所以搬运后正好位于这一段内;如果还要这一段的话。再经过fix .rel.dyn relocations  肯定出错!
这是我的理解不知说的对不? 
烦劳楼主回复一下!  呵呵!!