织梦CMS - 轻松建站从此开始!

罗索

MX51 uboot 启动流程分析 - stage1

落鹤生 发布于 2012-06-20 08:59 点击:次 
uboot启动过程分为两个部分,一般来说,系统在执行uboot之前会执行一段固化的程序,这段固化的程序会做一些基本的初始化,然后读取uboot的第一部分到内部内存中,PC指针跳转到这个内存地址,执行uboot的第一部分。
TAG:

uboot启动过程分为两个部分,一般来说,系统在执行uboot之前会执行一段固化的程序,这段固化的程序会做一些基本的初始化,然后读取uboot的第一部分到内部内存中,PC指针跳转到这个内存地址,执行uboot的第一部分。

uboot的第一部分要执行一些必要的硬件初始化,从我的理解至少包括外部ram的初始化,flash device的初始化,因为马上就要把第二段uboot从flash读入到外部ram中

有人可能会问,为什么不把uboot全部读入ram,然后从头开始执行,而是费了半天劲,读了两次uboot?

这是因为在读取第一部分uboot前,外部内存还不能使用,只能使用内部ram,从扩展性的角度,不能假定整个uboot可以装入内部ram。因此先装入一部分uboot,把外部ram初始化好,再把剩下的大部分uboot装到外部ram中执行。

uboot的第一阶段工作

1 硬件设备初始化

2 加载uboot的第二段代码到RAM空间

3 设置好栈

4 跳转到第二阶段的入口点

uboot的入口start.S

cpu/arm_cortexa8/start.S

 36 .globl _start
 37 _start: b   reset
 38     ldr pc, _undefined_instruction
 39     ldr pc, _software_interrupt
 40     ldr pc, _prefetch_abort
 41     ldr pc, _data_abort
 42     ldr pc, _not_used
 43     ldr pc, _irq
 44     ldr pc, _fiq
 45
 46 _undefined_instruction: .word undefined_instruction
 47 _software_interrupt:    .word software_interrupt
 48 _prefetch_abort:    .word prefetch_abort
 49 _data_abort:        .word data_abort
 50 _not_used:      .word not_used
 51 _irq:           .word irq
 52 _fiq:           .word fiq
 53 _pad:           .word 0x12345678 /* now 16*4=64 */
 54 .global _end_vect
 55 _end_vect:

行36 _start是GNU汇编器的默认入口标签,.globl将_start声明为外部程序可以访问的标签,.globl是GNU汇编的保留关键字,前面加点是GNU汇编的语法

b reset是uboot的第一条指令

38~44 ARM体系结构规定在上电复位的起始位置后,必须有8条连续的跳转指令,他们就是异常向量表。以后系统每当有异常出现,则CPU会根据异常号,从内存的0x00000000处开始查表做相应的处理

 69 _TEXT_BASE:
 70     .word   TEXT_BASE

uboot镜像在SDRAM中的重定位地址,.word关键字是指定_TEXT_BASE中存放的是WORD尺寸的数据,TEXT_BASE在mx51中定义为0x97800000

至于TEXT_BASE为什么定义为0x97800000,这是board特定的。

首先mx51的外部ram起始地址空间是0x90000000,终结地址空间是0xb0000000总共512MB,而0x97800000指向的 是120MB,一般来说板子都有128MB的SDRAM,所以把uboot的镜像copy到120MB的位置是可以正常工作的,当然我们也可以把 config.mk中的-Text修改为更大的值,毕竟我们的SDRAM一般为256MB以上

 72 .globl _armboot_start
 73 _armboot_start:
 74     .word _start

72定义_armboot_start为全局的,使得LD能够看到这个符号

74定义_armboot_start为_start

 79 .globl _bss_start
 80 _bss_start:
 81     .word __bss_start

__bs_start是在u-boot.lds中定义的

103 reset:
104     /*
105      * set the cpu to SVC32 mode
106      */
107     mrs r0, cpsr
108     bic r0, r0, #0x1f
109     orr r0, r0, #0xd3
110     msr cpsr,r0

103 reset: 是复位后的起始地址,在CPU一上电以后就会跳到这里执行

136 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
137     bl  cpu_init_crit
138 #endif

执行CPU初始化,bl完成跳转后会把后面的一条指令地址保存到连接寄存器LR(R14)中,以便使得子程序执行完后正常返回

140 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
141 relocate:               @ relocate U-Boot to RAM
142     adr r0, _start      @ r0 <- current position of code
143     ldr r1, _TEXT_BASE      @ test if we run from flash or RAM
144     cmp r0, r1          @ don't reloc during debug
145     beq stack_setup
146
147     ldr r2, _armboot_start
148     ldr r3, _bss_start
149     sub r2, r3, r2      @ r2 <- size of armboot
150     add r2, r0, r2      @ r2 <- source end address
151
152 copy_loop:              @ copy 32 bytes at a time
153     ldmia   r0!, {r3 - r10}     @ copy from source address [r0]
154     stmia   r1!, {r3 - r10}     @ copy to   target address [r1]
155     cmp r0, r2          @ until source end addreee [r2]
156     ble copy_loop
157 #endif  /* CONFIG_SKIP_RELOCATE_UBOOT */

141~157 此时外部内存已经初始化完毕,已经可以使用外部内存,需要重定位代码,即将uboot搬运到_TEXT_BASE位置处
142 ~145比较当前位置和_TEXT_BASE,如果相同则直接跳转到stack设置即可

149 armboot尺寸应该是数据段起始位置减去代码段起始位置,也就是_bss_start - _armboot_start

150 source结束地址是_start加armboot的尺寸,也就是_start + armboot_size

152 ~ 156 r0是源地址,r1是目标地址,把源地址的内容复制到目标地址,复制数目由r2定义

153 从源地址r0读取8个寄存器32 bytes到r3~r10

154 把r3~r10共8个寄存器32bytes拷贝到r1指向的内存地址

155~156 循环操作,直到armboot的尺寸

159     /* Set up the stack */
160 stack_setup:
161     ldr r0, _TEXT_BASE      @ upper 128 KiB: relocated uboot
162     sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
163     sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
164 #ifdef CONFIG_USE_IRQ
165     sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
166 #endif
167     sub sp, r0, #12     @ leave 3 words for abort-stack
168     and sp, sp, #~7     @ 8 byte alinged for (ldr/str)d

162 将从_TEXT_BASE - CONFIG_SYS_MALLOC_LEN开始到_TEXT_BASE的内存空间预留给malloc

163 又在malloc区下面预留了CONFIG_SYS_GBL_DATA_SIZE的空间给global data

164 ~ 168 最下面的空间预留给了堆栈,看来uboot中堆栈是从低地址向高地址增长的

170     /* Clear BSS (if any). Is below tx (watch load addr - need space) */
171 clear_bss:
172     ldr r0, _bss_start      @ find start of bss segment
173     ldr r1, _bss_end        @ stop here
174     mov r2, #0x00000000     @ clear value
175 clbss_l:
176     str r2, [r0]        @ clear BSS location
177     cmp r0, r1          @ are we at the end yet
178     add r0, r0, #4      @ increment clear index pointer
179     bne clbss_l         @ keep clearing till at end

bss段用来存放全局未初始化变量,清除这个区域,使得这些全局变量的初始值为0

184     ldr pc, _start_armboot  @ jump to C code


185


186 _start_armboot: .word start_armboot



184 跳转到C代码入口start_armboot,start_armboot在lib_arm/board.c中

(kickxxx)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201206/16106.html]
本文出处:CSDN博客 作者:kickxxx 原文
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容