uboot移植第二天——代码分析(2)

今天是uboot移植学习第二天,通过csdn博客记录自己的学习过程,希望通过这个方法,使自己所学的知识得到复习和扩展,总结经验发现不足,也希望自己的博客能够给人启发,疑问的到解决。

uboot中start.S相关代码分析

这次主要对代码分析(1)的第一阶段相关代码分析

  1. 设置为管理模式
reset:
    /*
     * set the cpu to SVC32 mode
     */
    mrs r0,cpsr①
    bic r0,r0,#0x1f②
    orr r0,r0,#0xd3③
    msr cpsr,r0④


CPSR 是当前的程序状态寄存器(Current Program Status Register),
而 SPSR 是保存的程序状态寄存器(Saved Program Status Register)
1、 MRS指令
MRS指令的格式为:
MRS{条件} 通用寄存器,程序状态寄存器(CPSR或SPSR)
MRS指令用于将程序状态寄存器的内容传送到通用寄存器中。该指令一般用在以

①:将cpsr(当前程序状态寄存器)的值读到r0中
②:清除r0中的后5位,因为在cpsr中第五位为模式设置位
③:将r0第五位或上0xd3
④:将r0的值写入cpsr,这样就将我们的处理器设置为了管理模式

2、turn off the watchdog——关闭看门狗

    ldr     r0, =pWTCON
    mov     r1, #0x0
    str     r1, [r0]
    解释:往pWTCON寄存器中写0即可

3、mask all IRQs by setting all bits in the INTMR——关闭外部中断

    ldr r1, =0x7fff
    ldr r0, =INTSUBMSK
    str r1, [r0]
    解释:INTSUBMSK寄存器全写1,就把中断给mask了。INTSUBMSK寄存器如下:

这里写图片描述
4、设置时钟比例

    /* FCLK:HCLK:PCLK = 1:2:4 */
    /* default FCLK is 120 MHz ! */
    ldr r0, =CLKDIVN
    mov r1, #3
    str r1, [r0]
解析:The S3C2440A supports selection of Dividing Ratio between FCLK, HLCK and PCLK. This ratio is determined by
HDIVN and PDIVN of CLKDIVN control register.
通过设置HDIVN and PDIVN of CLKDIVN的值确定时钟的比例

这里写图片描述

5、bl lowlevel_init——存储控制器初始化

    ldr     r0, =SMRDATA
    ldr r1, _TEXT_BASE
    sub r0, r0, r1
    ldr r1, =BWSCON /* Bus Width Status Controller 0x48000000*/
    add     r2, r0, #13*4
解析:刚开始时代码和数据都只是保存在norflash上内存中还没有。
所以不能用链接地址读取SMRDATA开始处的数据。
_TEXT_BASE:
.word TEXT_BASE  这个是我们的链接地址,即代码运行时所在的地址。
BWSCON:存储控制器相关寄存器的起始寄存器
SMRDATA:表示13个寄存器的值得存放的开始地址(链接地址)在内存中,但现在不能读取。
sub r0, r0, r1算出SMRDATA的相对地址(在norflash上13个寄存器的值得存放的开始地址)启动时是可以读取的,使得板子启动时不在连接地址上时也能取SMRDATA中的值进行初始化存储控制器。

注:
在重定位后,在我们的内存中(sdram)会有我们flash中的内容,在编译时是按链接地址编译,ldr r0, =SMRDATA中r0的值为内存中的地址(即在内存中13个寄存器的值得存放的开始地址,在flash中也有,TEXT_BASE 链接地址也是内存的地址,因此我们要计算出SMRDATA对于TEXT_BASE的相对偏移,这个相对偏移的值就是SMRDATA在flash的起始地址)。

6、重定位——即就是把falsh中的代码复制到ram中,本开发板复制到sdram中;

7、stack_setup——设置堆栈,因为接下来要调c函数,来进行更复杂的处理。

stack_setup:
    ldr r0, _TEXT_BASE      /* upper 128 KiB: relocated uboot   */
    sub r0, r0, #CFG_MALLOC_LEN /* malloc area                      */
    sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo  

解析: 
r0
= TEXT_BASE
= 0x33D00000
而关于sub指令:
SUB : 减法
(Subtraction)
SUB{条件}{S} <dest>, <op 1>, <op 2>
dest = op_1 - op_2
SUB 用操作数 one 减去操作数 two,把结果放置到目的寄存器中。操作数 1 是一
个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即值:
SUB R0, R1, R2 ; R0 = R1 - R2
SUB R0, R1, #256 ; R0 = R1 - 256
SUB R0, R2, R3,LSL#1 ; R0 = R2 - (R3 << 1)
减法可以在有符号和无符号数上进行

#CFG_MALLOC_LEN、#CFG_GBL_DATA_SIZE是宏定义

8、clear_bss——清bss段,该段存放的是初始化为零或为未初始化的变量,只要额外的放在一个段就行,使用时取就行;
进入uboot的第二阶段

clear_bss:
    ldr r0, _bss_start      /* find start of bss segment        */
    ldr r1, _bss_end        /* stop here                        */
    mov     r2, #0x00000000     /* clear                            */

clbss_l:str r2, [r0]        /* clear loop...                    */
    add r0, r0, #4
    cmp r0, r1
    ble clbss_l

解析:
此处的_bss_start是:
.globl _bss_start
_bss_start:
.word __bss_start
而_bss_end,是:
.globl _bss_end
_bss_end:
.word _end
对应的,__bss_start和_end,都在前面提到过的那个链接脚本里面:
u-boot-1.1.6\board\smdk2410\u-boot.lds中的:
__bss_start = .;
.bss : { *(.bss) }
_end = .;
即bss段的起始地址和结束地址
往里面的值全部赋值为0

以上对uboot做了个非常粗略的分析,因本人初学记录下的学习笔记,也希望能够帮到正在学习uboot移植的学子,若有不对之处,望各位指出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值