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

来源:互联网 发布:js闭包的好处 编辑:程序博客网 时间:2024/05/16 17:40

今天是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 byHDIVN 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_2SUB 用操作数 one 减去操作数 two,把结果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即值:SUB R0, R1, R2 ; R0 = R1 - R2SUB R0, R1, #256 ; R0 = R1 - 256SUB 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