ok6410下的uboot分析与实现

uboot 由两阶段代码组成:

•第一阶段主要步骤:

1.将cpu设置为svc模式

2.关闭mmu

3.设置外设端口地址

4.关闭watchdog

5.关闭中断

6.初始化时钟

7.初始化内存DRAM

8.把 nandflash 中的代码搬移到链接地址处

9.初始化堆栈

10.清bss段

11.使用与地址相关的跳转指令,跳转到 c 入口处。

OK6410上的启动代码如下:

@start.S
.text
.global _start
_start:
/*set the cpu to svc32 mode*/
    mrs r0,cpsr
    bic r0,r0,#0x1f
    orr r0,r0,#0xd3
    msr cpsr,r0

/*disable_mmu*/
    mcr p15,0,r0,c7,c7,0
    mrc p15,0,r0,c1,c0,0
    bic r0,r0,#0x00000007
    mcr p15,0,r0,c1,c0,0
/*peri port setup*/
    ldr r0,=0x70000000
    orr r0,r0,#0x13
    mcr p15,0,r0,c15,c2,4
/*Disable Watchdog
 *if you don‘t disable watchdog,because you don‘t to feed dog,so the CPU will conti *nue reboot.
*/
    ldr r0,=0x7e000000
    orr r0,r0,#0x4000
    mov r1,#0
    str r1,[r0]
/*Disable interrupt*/
    mvn r1,#0
    ldr r0,=0x71200014
    str r1,[r0]

    ldr r0,=0x71300014
    str r1,[r0]

/*Init clock*/
#define APLL_LOCK    0x7e00f000
#define MPLL_LOCK    0x7e00f004
#define EPLL_LOCK    0x7e00f008
#define LOCK_TIME    0xffff

#define OTHERS        0x7e00f900

#define CLK_DIV0    0x7e00f020

#define CLK_SRC        0x7e00f01c

@ set the lock time to max
    ldr r0, =LOCK_TIME
    ldr r1, =APLL_LOCK
    str r0, [r1]
    ldr r1, =MPLL_LOCK
    str r0, [r1]
    ldr r1, =EPLL_LOCK
    str r0, [r1]    

    @ set async mode
    ldr r0, =OTHERS
    ldr r1, [r0]
    bic r1, #0xc0
    str r1, [r0]

    loop1:
    ldr r0, =OTHERS
    ldr r1, [r0]
    and r1, #0xf00
    cmp r1, #0
    bne loop1        

    @ set the divider

    #define DIV_VAL    ( (0)|(1<<4)|(1<<8)|(1<<9)|(3<<12) )
    ldr r0, =CLK_DIV0
    ldr r1, =DIV_VAL
    str r1, [r0]    

    @ set APLL, MPLL, EPLL
    #define SDIV    1
    #define PDIV    3
    #define MDIV    266
    #define PLL_ENABLE    ( 1 << 31 )
    #define APLL_VAL    ( (SDIV<<0)|(PDIV<<8)|(MDIV<<16)|(PLL_ENABLE) )
    #define MPLL_VAL    APLL_VAL
    #define EPLL0_VAL    ( (2<<0)|(1<<8)|(32<<16)|PLL_ENABLE)
    #define EPLL1_VAL    ( 0 )

    #define APLL_CON    0x7e00f00c
    #define MPLL_CON    0x7e00f010
    #define EPLL_CON0    0x7e00f014
    #define EPLL_CON1    0x7e00f018

    ldr r0, =APLL_CON
    ldr r1, =APLL_VAL
    str r1, [r0]

    ldr r0, =MPLL_CON
    ldr r1, =MPLL_VAL
    str r1, [r0]

    ldr r0, =EPLL_CON0
    ldr r1, =EPLL0_VAL
    str r1, [r0]

    ldr r0, =EPLL_CON1
    ldr r1, =EPLL1_VAL
    str r1, [r0]

    @ select the source
    ldr r0, =CLK_SRC
    mov r1, #7
    str r1, [r0]

init_mem:
    ldr r0,=0x7e00f120
        mov r1, #0x8
       str r1, [r0]

        ldr r0, =0x7e001004
        mov r1, #0x4
        str r1, [r0]

        ldr r0, =0x7e001010
        ldr r1, =( ( 7800 / ( 1000000000/133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e001014
        mov r1, #(3 << 1)
        str r1, [r0]

        ldr r0, =0x7e001018
        mov r1, #0x1
        str r1, [r0]

        ldr r0, =0x7e00101c
        mov r1, #0x2
        str r1, [r0]

        ldr r0, =0x7e001020
        ldr r1, =( ( 45 / ( 1000000000 / 133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e001024
        ldr r1, =( ( 68 / ( 1000000000 / 133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e001028
        ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e00102c
        ldr r1, =( ( 80 / ( 1000000000 / 133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e001030
        ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e001034
        ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e001038
        ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e00103c
        mov r1, #0x07
        str r1, [r0]

        ldr r0, =0x7e001040
        mov r1, #0x02
        str r1, [r0]

        ldr r0, =0x7e001044
        ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e001048
        ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
        str r1, [r0]

        ldr r0, =0x7e00100c
        ldr r1, =0x00010012
        str r1, [r0]

        ldr r0, =0x7e00104c
        ldr r1, =0x0b45
        str r1, [r0]

        ldr r0, =0x7e001200
        ldr r1, =0x150f8
        str r1, [r0]

        ldr r0, =0x7e001304
        mov r1, #0x0
        str r1, [r0]

        ldr r0, =0x7e001008
        ldr r1, =0x000c0000
        str r1, [r0]

        ldr r1, =0x00000000
        str r1, [r0]

        ldr r1, =0x00040000
        str r1, [r0]

        ldr r1, =0x000a0000
        str r1, [r0]

        ldr r1, =0x00080032
        str r1, [r0]

        ldr r0, =0x7e001004
        mov r1, #0x0
        str r1, [r0]

check_dmc1_ready:

        ldr r0, =0x7e001000
        ldr r1, [r0]
        mov r2, #0x3
        and r1, r1, r2
        cmp r1, #0x1
        bne check_dmc1_ready
        nop

/*prepare C language environment*/

/*
*copy_to_ram:
*    ldr r0,=0x0c000000
*    ldr r1,=0x50000000
*    add r3,r0,#1024*4
*copy_loop:
*    ldr r2,[r0],#4
*    str r2,[r1],#4
*    cmp r0,r3
*    bne copy_loop
*/

init_stack:
    ldr sp,=0x54000000

copy_to_ram:
    adr r0, _start   /* »ñµÃ_startÖ¸ÁǰËùÔڵĵØÖ· : 0*/
    ldr r1, =_start  /* _startµÄÁ´½ÓµØÖ· 0x51000000 */

    ldr r2, =bss_start      /* bss¶ÎµÄÆðʼÁ´½ÓµØÖ· */

    sub r2, r2, r1

    cmp r0,r1
    beq clean_bss

    bl copy2ddr
    cmp r0, #0
    bne halt
clean_bss:
    ldr r0,=bss_start
    ldr r1,=bss_end
    cmp r0,r1
    beq to_ddr
clean_loop:
    mov r2,#0
    str r2,[r0],#4
    cmp r0,r1
    bne clean_loop

to_ddr:
    bl light_led
    ldr pc,=main

light_led:
    ldr r1, =0x7F008820
    ldr r0, =0x1111
    str r0, [r1]

    ldr r1, =0x7F008824
    mov r0,#0xe
    str r0,[r1]
    mov pc, lr    

halt:
    b halt

//nand.c

#define MEM_SYS_CFG     (*((volatile unsigned long *)0x7E00F120))
#define NFCONF          (*((volatile unsigned long *)0x70200000))
#define NFCONT          (*((volatile unsigned long *)0x70200004))
#define NFCMMD          (*((volatile unsigned long *)0x70200008))
#define NFADDR          (*((volatile unsigned long *)0x7020000C))
#define NFDATA          (*((volatile unsigned char *)0x70200010))
#define NFSTAT          (*((volatile unsigned long *)0x70200028))

#define NAND_DISABLE_CE()    (NFCONT |= (1 << 1))
#define NAND_ENABLE_CE()    (NFCONT &= ~(1 << 1))
#define NF_TRANSRnB()        do { while(!(NFSTAT & (1 << 0))); } while(0)

#define NAND_CMD_RESET        0xff
#define NAND_CMD_READID        0x90
#define NAND_CMD_READ0        0
#define NAND_CMD_READSTART    0x30

void nand_select(void)
{
    NFCONT &= ~(1<<1);
}

void nand_deselect(void)
{
    NFCONT |= (1<<1);
}

void nand_cmd(unsigned char cmd)
{
    NFCMMD = cmd;
}

void nand_addr(unsigned char addr)
{
    NFADDR = addr;
}

unsigned char nand_get_data(void)
{
    return NFDATA;
}

void wait_ready(void)
{
    while ((NFSTAT & 0x1) == 0);
}

void nand_reset(void)
{
    /* Ñ¡ÖÐ */
    nand_select();

    /* ·¢³ö0xffÃüÁî */
    nand_cmd(0xff);

    /* µÈ´ý¾ÍÐ÷ */
    wait_ready();

    /* È¡ÏûÑ¡ÖÐ */
    nand_deselect();
}

void nand_init(void)
{
    /* ÈÃxm0csn2ÓÃ×÷nand flash cs0 ƬѡÒý½Å */
    MEM_SYS_CFG &= ~(1<<1);

    /* ÉèÖÃʱ¼ä²ÎÊý:hclk = 7.5ns */
#define TACLS     0
#define TWRPH0    3
#define TWRPH1    1
    NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));
    NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));

    /* ʹÄÜnand flash controller */
    NFCONT |= 1;

    nand_reset();
}

void nand_send_addr(unsigned int addr)
{
#if 0
    unsigned int page   = addr / 2048;
    unsigned int colunm = addr & (2048 - 1);

    /* ÕâÁ½¸öµØÖ·±íʾ´ÓÒ³ÄÚÄÄÀ↑ʼ */
    nand_addr(colunm & 0xff);
    nand_addr((colunm >> 8) & 0xff);

    /* ÏÂÃæÈý¸öµØÖ·±íʾÄÄÒ»Ò³ */
    nand_addr(page & 0xff);
    nand_addr((page >> 8) & 0xff);
    nand_addr((page >> 16) & 0xff);
#else
    nand_addr(addr & 0xff);         /* a0~a7 */
    nand_addr((addr >> 8) & 0x7);   /* ³ÌÐòµÄ½Ç¶È: a8~a10 */

    nand_addr((addr >> 11) & 0xff); /* ³ÌÐòµÄ½Ç¶È: a11~a18 */
    nand_addr((addr >> 19) & 0xff); /* ³ÌÐòµÄ½Ç¶È: a19~a26 */
    nand_addr((addr >> 27) & 0xff); /* ³ÌÐòµÄ½Ç¶È: a27   ~ */

#endif
}

int nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
    unsigned int addr = nand_start;
    int i, count = 0;
    unsigned char *dest = (unsigned char *)ddr_start;

    /* Ñ¡ÖÐоƬ */
    nand_select();

    while (count < len)
    {
        /* ·¢³öÃüÁî0x00 */
        nand_cmd(0x00);

        /* ·¢³öµØÖ· */
        nand_send_addr(addr);

        /* ·¢³öÃüÁî0x30 */
        nand_cmd(0x30);

        /* µÈ´ý¾ÍÐ÷ */
        wait_ready();

        /* ¶ÁÊý¾Ý */
        for (i = 0; i < 2048 && count < len; i++)
        {
            dest[count++] = nand_get_data();
        }

        addr += 2048;
    }

    /* È¡ÏûƬѡ */
    nand_deselect();
    return 0;
}

static int nandll_read_page (unsigned char *buf, unsigned long addr, int large_block)
{
    int i;
    int page_size = 512;

    if (large_block==2)
        page_size = 4096;

    NAND_ENABLE_CE();  // Ñ¡ÖÐnand

    NFCMMD = NAND_CMD_READ0;

    /* Write Address */
    NFADDR = 0;

    if (large_block)
        NFADDR = 0;

    NFADDR = (addr) & 0xff;
    NFADDR = (addr >> 8) & 0xff;
    NFADDR = (addr >> 16) & 0xff;

    if (large_block)
        NFCMMD = NAND_CMD_READSTART;

    NF_TRANSRnB();

    for(i=0; i < page_size; i++) {
        *buf++ = NFDATA;
    }

    NAND_DISABLE_CE();

    return 0;
}

int copy2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
    unsigned char *dest = (unsigned char *)ddr_start;
    int i;

    /* ³õʼ»¯nand flash controller */
    nand_init();

    /* ¶Ánand flash */
    /* Read pages */
    for (i = 0; i < 4; i++, dest+=2048){
        nandll_read_page(dest, i, 2);
    }

    /* Read pages */
    for (i = 4; i < ((len+4096)>>13); i++, dest+=8192) {
        nandll_read_page(dest, i, 2);
    }

    return 0;
}

//main.c

#define rGPMCON        (*(volatile unsigned *)(0x7F008820))
#define rGPMDAT        (*(volatile unsigned *)(0x7F008824))
#define rGPMPUD        (*(volatile unsigned *)(0x7F008828))

void msDelay(int time)
{
    volatile unsigned int i,j;
    for (i=0;i<20000;i++)
        for(j=0;j<time;j++);
}

void GPIO_Init(void)
{
    rGPMCON = 0x11111;
    rGPMPUD = 0x00;
    rGPMDAT = 0x1F;
}

void LedTest(void)
{
    volatile unsigned int i;
    while(1)
    {
        for(i=0;i<4;i++)
        {
            rGPMDAT =~(1<<i);
            msDelay(10);
        }
    }
}
int main()
{
    GPIO_Init();
    LedTest();

    return 0;
}

总结如下:

第一阶段启动代码主要完成此阶段所需硬件的初始化。初始化 c 语言运行环境,即初始化堆栈。进入 c 语言,跳到第二阶段。

时间: 2024-11-08 23:13:44

ok6410下的uboot分析与实现的相关文章

u-boot分析(九)----nand flash初始化|nand flash读写分析

u-boot分析(九) 上篇博文我们按照210的启动流程,分析到了初始化串口,由于接下来的取消存储保护不是很重要,所以我们今天按照u-boot的启动流程对nand flash初始化进行分析. 今天我们会用到的文档: 1.        2440芯片手册:http://download.csdn.net/detail/wrjvszq/8358949 2.        6410芯片手册:http://download.csdn.net/detail/wrjvszq/8358965 3.      

u-boot分析(八)----串口初始化

u-boot分析(八) 上篇博文我们按照210的启动流程,分析到了内存初始化,今天我们继续按照u-boot的启动流程对串口的初始化进行分析. 今天我们会用到的文档: 1.        2440芯片手册:http://download.csdn.net/detail/wrjvszq/8358949 2.        6410芯片手册:http://download.csdn.net/detail/wrjvszq/8358965 3.        210芯片手册:S5PV210_UM_REV1

u-boot分析(五)----I/D cache失效|关闭MMU和cache|关闭看门狗

u-boot分析(五) 上篇博文我们按照210的启动流程,对u-boot启动中的设置异常向量表,设置SVC模式进行了分析,今天我们继续按照u-boot的启动流程对以下内容进行分析. 今天我们会用到的文档: Arm9内核手册:http://download.csdn.net/detail/wrjvszq/8358867 Arm11内核手册:http://download.csdn.net/detail/wrjvszq/8358877 Arm a8内核手册:http://download.csdn.

u-boot分析(六)----时钟初始化

u-boot分析(六) 上篇博文我们按照210的启动流程,分析到了关闭看门狗,今天我们继续按照u-boot的启动流程进行分析,今天我们会主要分析时钟的初始化. 今天我们会用到的文档: 1.        Arm9内核手册:http://download.csdn.net/detail/wrjvszq/8358867 2.        Arm11内核手册:http://download.csdn.net/detail/wrjvszq/8358877 3.        Arm a8内核手册:ht

u-boot分析(十)----堆栈设置|代码拷贝|完成BL1阶段

u-boot分析(十) 上篇博文我们按照210的启动流程,分析到了初始化nand flash,由于接下来的关闭ABB比较简单所以跳过,所以我们今天按照u-boot的启动流程继续进行分析. 今天我们会用到的文档: 1.        2440芯片手册:http://download.csdn.net/detail/wrjvszq/8358949 2.        6410芯片手册:http://download.csdn.net/detail/wrjvszq/8358965 3.       

u-boot分析(四)---设置异常向量表|设置SVC模式

u-boot分析(四) 通过前三篇的分析,我们对u-boot已经有了整体的认识和掌握,但是我们仍然对于其部分硬件是如何初始化的不太清楚,所以接下来几篇博文我将会对我们在http://www.cnblogs.com/wrjvszq/archive/2015/01/10/4215627.html一文中总结出的u-boot的工作流程中的重要环节,结合文档加以分析. 今天我们会用到的文档: 1.        ARM Architecture Reference Manual:http://downlo

Linux3.6.7在OK6410下的移植

这是在本学期期末整项目时习得的,不知道以后会不会有用. 一个天天整js+css+html的,突然弄Linux C,学到的确实不少. 遗憾的是,虽然努力了,导师还是觉得我进度慢把这部分砍掉了,唉. 前言 对于我这个新手而言,第一次学习linux,面对庞大的代码,复杂的程序结构和自身对linux知识的严重缺乏,一下子还真不知道该做什么.想想开发板厂家提供的演示程序,其过程是这样:先运行bootloader,bootloade引导linux内核启动,启动后再运行UI程序.对应的程序也有三个分别为u-b

u-boot分析

4.Bootloader:u-boot.2009.08分析与移植 4.1:分析u-boot根目录下的Makefile,可以看到uboot编译的顺序如下,由此可知编译执行的第一个文件是cpu/$(CPU)/start.o,又由于是基于 arm920t架构的,所以去分析cpu/arm920t/start.S源文件. # U-Boot objects....order is important (i.e. start must be first) OBJS  = cpu/$(CPU)/start.o

18.13 Uboot分析与移植

18.13.1 使用JLink烧写Nor Flash JLink只支持烧写NOR Flash,不支持烧写Nand Flash. 1.准备工作:JLink的USB口接到电脑上,JLink的JTAG口用排线和开发板的JTAG口相连,开发板设为NorFlash启动并上电 2.启动J-Flash. 3.File>Open Project,找到s3c2440.jflash 4.Target>Connect:显示连接成功 5. File>Open data file:选择需要烧写的Uboot.bin