uboot启动原理

半腔热情 提交于 2020-02-24 09:04:26

  1.裸机运行程序时一般情况下程序代码小于16KB将其下载地址设置到BL1的起始地址。BL0会自动加载并执行BL1。

当程序大于16kB时无法直接运行。

  例如UBOOT就大于16KB,执行的原理为。将程序分为BL1、BL2两部分。

其中BL1初始化DDR并且指定BL2的起始地址。BL2为真正需要的程序。

BL1部分

start.S

#define WTCON        0xE2700000

#define SVC_STACK    0xd0037d80

.global _start                    // 把_start链接属性改为外部,这样其他文件就可以看见_start了
_start:
    // 第1步:关看门狗(向WTCON的bit5写入0即可)
    ldr r0, =WTCON
    ldr r1, =0x0
    str r1, [r0]
    
    // 第2步:设置SVC栈
    ldr sp, =SVC_STACK
    
    // 第3步:开/关icache
    mrc p15,0,r0,c1,c0,0;            // 读出cp15的c1到r0中
    //bic r0, r0, #(1<<12)            // bit12 置0  关icache
    orr r0, r0, #(1<<12)            // bit12 置1  开icache
    mcr p15,0,r0,c1,c0,0;

    // 第4步:初始化ddr
    bl sdram_asm_init        
    // 第5步:重定位,从SD卡第45扇区开始,复制32个扇区到DDR 的0x23E00000    
    bl copy_bl2_2_ddr

sd_start.c

#define SD_START_BLOCK    45
#define SD_BLOCK_CNT    32
#define DDR_START_ADDR    0x23E00000

typedef unsigned int bool;

// 通道号:0,或者2
// 开始扇区号:45
// 读取扇区个数:32
// 读取后放入内存地址:0x23E00000
// with_init:0
typedef bool(*pCopySDMMC2Mem)(int, unsigned int, unsigned short, unsigned int*, bool);

typedef void (*pBL2Type)(void);


// 从SD卡第45扇区开始,复制32个扇区内容到DDR的0x23E00000,然后跳转到23E00000去执行
void copy_bl2_2_ddr(void)
{
    // 第一步,读取SD卡扇区到DDR中
    pCopySDMMC2Mem p1 = (pCopySDMMC2Mem)(*(unsigned int *)0xD0037F98);
    
    (*p1)(2, SD_START_BLOCK, SD_BLOCK_CNT, (unsigned int *)DDR_START_ADDR, 0);        // 读取SD卡到DDR中
    // 第二步,跳转到DDR中的BL2去执行
    pBL2Type p2 = (pBL2Type)DDR_START_ADDR;
    (*p2)();
}

 

BL2(功能无所谓,将链接地址和BL1中的跳转地址相同即可)

SECTIONS
{
    . = 0x23E00000;
    
    .text : {
        start.o
        * (.text)
    }
            
    .data : {
        * (.data)
    }
    
    bss_start = .; 
    .bss : {
        * (.bss)
    }
    
    bss_end  = .;    
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!