S5pv210——SD卡重入

1:s5pv210启动原理:s5pv210启动的时候首先查看OMpin设置的启动方式,如果设置为SDMMC启动的话,首先从SD的通道1启动,但是通道1连接的是iNand,如果iNand中启动不了,

则从SD卡的通道2启动,sd卡通道2连接外置的sd卡,BL0首先从sd卡的第一扇区中复制16kb到sram中去执行(包括16字节的校验头),

所以BL1所做的事情:

(1)  开关置锁

(2)  关看门狗

(3)  开icache

(4)  设置栈

(5)  初始化dram

(6)  初始化dram以后,在执行sd卡复制函数,把接下来要执行的代码复制到dram中;

(7)  跳转到内存中去执行接下来的代码即可;

代码实战:

BL1:

(1)  开关置锁

(2)  关看门狗

(3)  开icache

(4)  设置栈

(5)  初始化dram

/*
 *        s5pv210裸机实验
 *        
 *        
 *
 */
 
#define WTCON                0xE2700000
#define PS_HOLD_CONTROL        0xE010E81C
#define SVC_STACK            0xD0037D80

 
    .global _start
_start:
    
    //关看门狗
    ldr r0, =WTCON
    ldr r1, =0
    str r1, [r0]
    
    //PS_HOLD置锁
    ldr r0, =0xE010E81C
    ldr r1, =0x301
    ldr r2, [r0]
    orr r2, r2, r1
    str r2, [r0]
 
    //开icache
    mrc p15, 0, r0, c1, c0, 0
    //bic r0, r0, #(1<<12)        //置0 关icache
    orr r0, r0, #(1<<12)        //置1 开icache
    mcr p15, 0, r0, c1, c0, 0
    
    
    //设置栈
    ldr sp, =SVC_STACK

    bl sdram_asm_init
    
    
    bl cpysd_2_dram
    
    b .

(6)  初始化dram以后,在执行sd卡复制函数,把接下来要执行的代码复制到dram中;

(7)  跳转到内存中去执行接下来的代码即可;

/*
 *        s5pv210裸机实验
 *        
 *        sd卡中内容复制到内存中
 *
 */

#define CopySDMMCtoMem            0xD0037F98
#define MEM_ADDRESS                0x23e00000
#define bool                     int
extern void led_blink(void);

typedef bool (*CopyFunc_t)(int, unsigned int, unsigned short, unsigned int*, bool);

void cpysd_2_dram(void) 
{
    //初始化函数指针p1,将0xD0037F98中的值强制类型转换为CopyFunc_t函数类型
    CopyFunc_t p1 = (CopyFunc_t)(*(unsigned int*)CopySDMMCtoMem);
    
    //初始化函数指针p2,
    void (*p2)(void) = (void (*)(void))MEM_ADDRESS;
    
    //将sd扇区45中的内容复制到内存0x23e00000内存位置中
    (*p1)(2, 45, 40, (unsigned int*)MEM_ADDRESS, 0);
    
    //跳转到0x23e00000内存地址处执行函数        
    (*p2)();
    
}
 
 

BL2:

/*
 *        s5pv210裸机实验
 *        
 *        
 *
 */
 
#define WTCON                0xE2700000
#define PS_HOLD_CONTROL        0xE010E81C
#define SVC_STACK            0xD0037D80

 
    .global _start
_start:
    bl led_blink    
    
    b .

 

/*
 *        s5pv210裸机实验
 *        
 *        LED流水灯
 *
 */

 
#define _REG_GPJ0CON            *((unsigned int*)0xE0200240)
#define _REG_GPJ0DAT            *((unsigned int*)0xE0200244)
#define _REG_GPD0CON            *((unsigned int*)0xE02000A0)
#define _REG_GPD0DAT            *((unsigned int*)0xE02000A4)

void delay(void);

void led_blink(void)
{
    //GPJ03、4、5设置为output模式
    
    _REG_GPJ0CON = 0x11111111;
    
    //GPD0 1设置为输出模式
    _REG_GPD0CON &= ~(0xF << 4);
    _REG_GPD0CON |= (0x1 << 4);
    
    while (1) {
        
        //led4 暗
        _REG_GPD0DAT |= (1<<1);        ////GPJ03、4、5输出低电平为亮
        //led1 亮
        _REG_GPJ0DAT = ((0<<3) | (1<<4) | (1<<5));                       
        
        //延时
        delay();
        
        //led2 亮
        _REG_GPJ0DAT = ((1<<3) | (0<<4) | (1<<5));
        
        //延时
        delay();
        
        //led3 亮
        _REG_GPJ0DAT = ((1<<3) | (1<<4) | (0<<5));
        
        //延时
        delay();
        //关 1 2 3
        _REG_GPJ0DAT = ((1<<3) | (1<<4) | (1<<5));
        //led4 亮
        _REG_GPD0DAT &= ~(1<<1);        ////延时
        delay();        
    }    
}


void delay(void)
{
    volatile unsigned int i = 900000;        // volatile 让编译器不要优化,这样才能真正的减
    while (i--);                            // 才能消耗时间,实现delay
}

 

posted @ 2017-02-02 21:29  biaohc  阅读(513)  评论(0编辑  收藏  举报