u-boot汇编启动部分分析

       今天上午没事,拿了个u-boot反汇编出来,分析了下,汇编部分不是很多,流程还是比较清晰的,下面是汇编部分分析。不过这个u-boot应该有问题,我没看到重定向这个部分,还有nand flash部分也没看到,但是大致的流程是差不多的

 

主要流程

1、异常向量表初始化

2、设备初始化

1)设置特权模式,禁止中断

2)开启led状态灯,这里应该打开串口等。

3)关闭看门狗,设置中断掩码。

4)设置处理器时钟(频率和分频)

5)这里应该还有对FLASH的初始化,这个U-boot里,应该不对

3、处理器状态设置

1)设置Cache Operations Register,关闭指令缓存。

2)设置TLB Operations Register,关闭TLB缓存。

3)设置Cache Operations Register,关闭MMU,禁止数据缓存等。

4、内存寄存器设置

5、代码重定向,将FLASH里的代码复制到RAM,pc重定向。

6、设置堆栈,准备调用C。

7、启动C代码。

 

 

1、异常向量部分

 

 

33f80000 <_start>:

33f80000: ea000012 b 33f80050 <start_co de> //向量reset中断入口,跳转到33f80050

33f80004: e59ff014 ldr pc, [pc, #20] ; 33f80020 <_undefined_instruction>  //未定义指令异常向量

33f80008: e59ff014 ldr pc, [pc, #20] ; 33f80024 <_software_interrupt> //软中断异常向量

33f8000c: e59ff014 ldr pc, [pc, #20] ; 33f80028 <_prefetch_abort> //预处理异常向量

33f80010: e59ff014 ldr pc, [pc, #20] ; 33f8002c <_data_abort> //数据异常向量

33f80014: e59ff014 ldr pc, [pc, #20] ; 33f80030 <_not_used> //未用

33f80018: e59ff014 ldr pc, [pc, #20] ; 33f80034 <_irq> //普通中断

33f8001c: e59ff014 ldr pc, [pc, #20] ; 33f80038 <_fiq> //快速中断

 

 

 

2、起始代码部分,主要设置特权模式,禁止中断,开LED灯,关闭看门狗,设置中断掩码,设置时钟等。

 

 

33f80050 <start_code>:

33f80050: e10f0000 mrs r0, CPSR   //读取状态寄存器到R0

33f80054: e3c0001f bic r0, r0, #31 ; 0x1f   //清除后五位模式位

33f80058: e38000d3 orr r0, r0, #211 ; 0xd3    //设置特权模式,禁止IRQ和FRQ中断

33f8005c: e129f000 msr CPSR_fc, r0   //给状态寄存器赋值

33f80060: eb00028d bl 33f80a9c <__coloured_LED_init>    //跳转到LED初始化

33f80064: eb00028d bl 33f80aa0 <__red_LED_on>              //跳转到开启红灯

33f80068: e3a00453 mov r0, #1392508928 ; 0x53000000   //设置看门狗的寄存器WTCON地址0x53000000

33f8006c: e3a01000 mov r1, #0 ; 0x0   //将看门狗设置为关闭

33f80070: e5801000 str r1, [r0]   //给看门狗赋值

33f80074: e3e01000 mvn r1, #0 ; 0x0   //设置中断掩码0xffff

33f80078: e59f0338 ldr r0, [pc, #824] ; 33f803b8 <.text+0x3b8> //读取中断INTMSK地址 0x4a000008

33f8007c: e5801000 str r1, [r0]   //为中断INTMSK(0x4a000008)赋值

33f80080: e59f1334 ldr r1, [pc, #820] ; 33f803bc <.text+0x3bc> //设置INTSUBMSK为0x000003ff,全部禁止

33f80084: e59f0334 ldr r0, [pc, #820] ; 33f803c0 <.text+0x3c0> //读取INTSUBMSK地址0x4a00001c

33f80088: e5801000 str r1, [r0]   //设置INTSUBMSK

33f8008c: e59f0330 ldr r0, [pc, #816] ; 33f803c4 <.text+0x3c4>  //读取时钟分频寄存器CLKDIVN的地址0x4c000014

33f80090: e3a01003 mov r1, #3 ; 0x3   //设置FCLK:HCLK:PCLK=1:2:4

33f80094: e5801000 str r1, [r0]   //为时钟分频寄存器赋值

33f80098: eb00000c bl 33f800d0 <cpu_init_crit>   //跳转到cpu_init_crit

 

 

3、cpu_init_crit部分,对处理器进行设置

 

 

33f800d0 <cpu_init_crit>:

33f800d0: e3a00000 mov r0, #0 ; 0x0

33f800d4: ee070f17 mcr 15, 0, r0, cr7, cr7, {0} //设置Cache Operations Register 使instruction and data caches无效

33f800d8: ee080f17 mcr 15, 0, r0, cr8, cr7, {0} //设置TLB Operations Register   使translation lookaside buffers无效 

33f800dc: ee110f10 mrc 15, 0, r0, cr1, cr0, {0} //读取control register的值

33f800e0: e3c00c23 bic r0, r0, #8960 ; 0x2300 //清空control register 的第13位,9:8位

33f800e4: e3c00087 bic r0, r0, #135 ; 0x87      //清空control register 的第7位(Little-endian),2:0位 禁止Data cache和MMU

33f800e8: e3800002 orr r0, r0, #2 ; 0x2            //给第1位赋值1,设置Fault checking enabled,开启错误检测

33f800ec: e3800a01 orr r0, r0, #4096 ; 0x1000 //给第12位赋值1,设置Instruction cache enabled

33f800f0: ee010f10 mcr 15, 0, r0, cr1, cr0, {0} //给control register赋值

33f800f4: e1a0c00e mov ip, lr   //保存lr

33f800f8: eb0000b9 bl 33f803e4 <lowlevel_init>   //调用lowlevel_init

33f800fc: e1a0e00c mov lr, ip   //恢复lr

33f80100: e1a0f00e mov pc, lr   //返回

 

 

 

4、lowlevel_init部分,对内存进行设置

这个是对内存进行赋值部分

 

33f803e4 <lowlevel_init>:

33f803e4: e59f0020 ldr r0, [pc, #32] ; 33f8040c <.text+0x40c>   //读取SMRDATA在程序里的地址

33f803e8: e51f1010 ldr r1, [pc, #-16] ; 33f803e0 <_TEXT_BASE> //读取代码起始地址

33f803ec: e0400001 sub r0, r0, r1   //计算偏移距离

33f803f0: e3a01312 mov r1, #1207959552 ; 0x48000000   //读取MEMORY控制器起始地址

33f803f4: e2802034 add r2, r0, #52 ; 0x34   //计算要复制的末地址

33f803f8: e4903004 ldr r3, [r0], #4   //读取SMRDATA的内容

33f803fc: e4813004 str r3, [r1], #4    //复制到MEMORY控制器

33f80400: e1520000 cmp r2, r0    //比较是否到复制的末地址

33f80404: 1afffffb bne 33f803f8 <lowlevel_init+0x14>   //不等则继续复制

33f80408: e1a0f00e mov pc, lr   //函数返回

33f8040c: 33f80410 mvnccs r0, #268435456 ; 0x10000000   //此处保存的是SMRDATA的地址

 

33f80410 <SMRDATA>:    //具体设置查看手册

33f80410: 2211d120 andcss sp, r1, #8 ; 0x8   //nandflash(8bit)

33f80414: 00000700 andeq r0, r0, r0, lsl #14

33f80418: 00000700 andeq r0, r0, r0, lsl #14

33f8041c: 00000700 andeq r0, r0, r0, lsl #14

33f80420: 00001f4c andeq r1, r0, ip, asr #30

33f80424: 00000700 andeq r0, r0, r0, lsl #14

33f80428: 00000700 andeq r0, r0, r0, lsl #14

33f8042c: 00018005 andeq r8, r1, r5   //Sync. DRAM

33f80430: 00018005 andeq r8, r1, r5   //Sync. DRAM

33f80434: 008e0459 addeq r0, lr, r9, asr r4

33f80438: 00000032 andeq r0, r0, r2, lsr r0

33f8043c: 00000030 andeq r0, r0, r0, lsr r0    //BANK6/7 memory map 32M

33f80440: 00000030 andeq r0, r0, r0, lsr r0   //cas 延迟3时钟

 

 

5、代码重定向,这个uboot里没有,我从源码里考了一个过来

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

relocate:

adr r0,_start //当前代码地址

ldr r1,_TEXT_BASE //要移动到的地址

cmp r0,r1 //比较两个地址,看现在在Flash 还是在RAM里

beq stack_setup //如果不需要重定向则跳转到堆栈设置处

 

ldr  r2,_armboot_start //读取代码初始地址

ldr  r3,_bss_start //读取bss初始地址

sub r2,r3,r2 //计算所要的移动量

add r2,r0,r2

 

copy_loop

ldmia r0!,{r3-r10} //循环移动

stmia   r1!,{r3-r10}

cmp  r0,r2

ble copy_loop

 

 

 

6、初始化堆栈

 

 

33f8009c <stack_setup>:

33f8009c: e51f0064 ldr r0, [pc, #-100] ; 33f80040 <_TEXT_BASE>   //读取代码首地址

33f800a0: e2400803 sub r0, r0, #196608 ; 0x30000    //计算堆区地址

33f800a4: e2400080 sub r0, r0, #128 ; 0x80    //计算全局数据区地址

33f800a8: e240d00c sub sp, r0, #12 ; 0xc   //使sp指向栈区

 

33f800ac <clear_bss>:

33f800ac: e51f006c ldr r0, [pc, #-108] ; 33f80048 <_bss_start>   //取bss开始位

33f800b0: e51f106c ldr r1, [pc, #-108] ; 33f8004c <_bss_end>   //取bss结束位

33f800b4: e3a02000 mov r2, #0 ; 0x0   //数据初始值

 

33f800b8 <clbss_l>:

33f800b8: e5802000 str r2, [r0]   //为bss设置初值0

33f800bc: e2800004 add r0, r0, #4 ; 0x4   //地址累加

33f800c0: e1500001 cmp r0, r1    //比较结束地址

33f800c4: dafffffb ble 33f800b8 <clbss_l>   //循环初始化

 

7、跳转到C部分

33f800c8: e51ff004 ldr pc, [pc, #-4] ; 33f800cc <_start_armboot> //令pc指向_start_armboot

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值