找回密码
 注册

微信扫码登录

使用验证码登录

只需一步,快速开始

胜天工科技销售各种数字电视信号调制卡胜天工科技销售各种数字电视信号码流卡

【游客、新手、注册会员的区别】 【积分策略和会员晋级说明】 【发帖和附件上传规则】 【如何下载感兴趣的资料】 【如何获取梦游币】 【侵权资料处理及免责说明】
查看: 2239|回复: 1

U-BOOT FOR S3C2410 NAND-BOOT

[复制链接]
  • TA的每日心情
    擦汗
    2012-7-22 22:21
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    发表于 2009-9-25 23:46:00 | 显示全部楼层 |阅读模式
    分享到:
    消息来自- 北京
    1 分析代码

    Bootloader 代码是芯片复位后进入操作系统之前执行的一段代码,主要用于完成由硬件启动到操作系统启动的过渡,从而为操作系统提供基本的运行环境,如初始化CPU、堆栈、存储器系统等。

    (1) start.S

    u-boot的stage1代码通常放在start.s文件中,它用汇编语言写成,其主要代码部分如下:

    ●定义入口 。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。

    ●设置异常向量(Exception Vector)。

    ●设置CPU的速度、时钟频率及中断控制寄存器。

    ●初始化内存控制器 。

    ●将ROM中的程序复制到RAM中。

    ●初始化堆栈 。

    ●转到RAM中执行,该工作可使用指令ldr pc来完成。

    (2)board.C 

    libarm/board.c中的start armboot是C语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数主要完成如下操作:

    ●调用一系列的初始化函数。

    ●初始化Flash设备。

    ●初始化系统内存分配函数。

    ●如果目标系统拥有NAND设备,则初始化NAND设备。

    ●如果目标系统有显示设备,则初始化该类设备。

    ●初始化相关网络设备,填写IP、MAC地址等。

    ●进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。


    开始移植

    第一步:建立开发环境

    工作环境:

    RedHat Linux 9

    交叉编译器:

    arm-linux-gcc 4.0.0

    U-BOOT版本:

    1.1.6

    目标板:

    ZJ2410A,NAND FLASH 64M,RAM 64M,CS8900A

    1、建立自己2410开发板的配置(我的是zj2410):

    (1)$ cp –r board/smdk2410 board/zj2410 

    (2)$ cp include/configs/smdk2410.h include/configs/zj2410.h 

    zj2410.h是开发板的配置文件,他包括开发板的CPU、系统时钟、RAM、FLASH系统及其他相关的配置信息!由于国内大多数2410开发板都是抄袭韩国三星的SMDK2410开发板,因此这里都直接拷贝SMDK2410的配置文件,做相应的修改即可!

    2、修改文件:

    (1)include/configs/zj2410.h:

    修改:

    # define CFG_PROMPT “SMDK2410#”

    为:

    # define CFG_PROMPT “ZJ2410#”

    (2)Makefile:

    参照SMDK2410配置

    smdk2410_config : unconfig

    @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0


    zj2410_config : unconfig

    @$(MKCONFIG) $(@:_config=) arm arm920t zj2410 NULL s3c24x0


    第二步:使U-BOOT能够启动起来

    2410的启动代码可以在外部的NAND FLASH上执行,启动时,NAND FLASH的前4KB(地址为0x00000000,OM[1:0]=0)将被装载到SDRAM中被称为Setppingstone的地址中,然后开始执行这段代码。启动以后,这4KB的空间可以做其他用途!

    添加的代码主要来自于VIVI。

    1。在cpu/arm920t/start.s中修改如下:

    ……

    #ifndef CONFIG_SKIP_RELOCATE_UBOOT

    relocate: /* relocate U-Boot to RAM */

    adr r0, _start&#160;/* r0 <- current position of code&#160;*/

    ldr r1, _TEXT_BASE&#160;/* test if we run from flash or RAM */

    cmp&#160;r0, r1&#160;/* don't reloc during debug&#160;*/

    beq&#160;stack_setup

    @&#160;ldr r2, _armboot_start

    @&#160;ldr r3, _bss_start

    @&#160;sub r2, r3, r2&#160;/* r2 <- size of armboot&#160;*/

    @&#160;add r2, r0, r2&#160;/* r2 <- source end address&#160;*/

    @copy_loop:

    @&#160;ldmia&#160;r0!, {r3-r10}&#160;/* copy from source address [r0]&#160;*/

    @&#160;stmia&#160;r1!, {r3-r10}&#160;/* copy to&#160;target address [r1]&#160;*/

    @&#160;cmp r0, r2&#160;/* until source end addreee [r2]&#160;*/

    @&#160;ble copy_loop


    #ifdef CONFIG_S3C2410_NAND_BOOT /*这个一定要放在堆栈设置之前*/

    bl&#160;copy_myself

    #endif /*CONFIG_S3C2410_NAND_BOOT*/


    #endif /*CONFIG_SKIP_RELOCATE_UBOOT*/

    ……

    ……

    ……

    /**************************************************************************

    *

    * copy u-boot&#160;to ram 放在start.S靠后的位置

    *

    *************************************************************************

    */

    #ifdef CONFIG_S3C2410_NAND_BOOT

    @

    @ copy_myself: copy u-boot to ram

    @

    copy_myself:

    mov&#160;r10, lr


    @ reset NAND

    mov r1, #NAND_CTL_BASE

    ldr r2, =0xf830&#160;@ initial value

    str r2, [r1, #oNFCONF]

    ldr r2, [r1, #oNFCONF]

    bic r2, r2, #0x800&#160;@ enable chip

    str r2, [r1, #oNFCONF]

    mov r2, #0xff&#160;@ RESET command

    strb&#160;r2, [r1, #oNFCMD]

    mov r3, #0&#160;@ wait

    1:&#160;add r3, r3, #0x1

    cmp r3, #0xa

    blt 1b

    2:&#160;ldr r2, [r1, #oNFSTAT]&#160;@ wait ready

    tst r2, #0x1

    beq 2b

    ldr r2, [r1, #oNFCONF]

    orr r2, r2, #0x800&#160;@ disable chip

    str r2, [r1, #oNFCONF]


    @ get read to call C functions

    ldr sp, DW_STACK_START&#160;@ setup stack pointer

    mov fp, #0&#160;@ no previous frame, so fp=0


    @ copy UBOOT to RAM

    ldr r0, _TEXT_BASE

    mov&#160;r1, #0x0

    mov r2, #0x20000

    bl&#160;nand_read_ll


    teq r0, #0x0

    beq ok_nand_read


    bad_nand_read:

    1:&#160;b&#160;1b&#160;@ infinite loop

    ok_nand_read:

    @ verify

    mov r0, #0

    ldr r1, _TEXT_BASE

    mov r2, #0x400&#160;@ 4 bytes * 1024 = 4K-bytes

    go_next:

    ldr r3, [r0], #4

    ldr r4, [r1], #4

    teq r3, r4

    bne notmatch

    subs&#160;r2, r2, #4

    beq done_nand_read&#160;

    bne go_next

    notmatch:

    1:&#160;b&#160;1b

    done_nand_read:

    mov&#160;pc, r10

    #endif&#160;

    @ CONFIG_S3C2440_NAND_BOOT

    DW_STACK_START:

    .word&#160;STACK_BASE+STACK_SIZE-4

    2. 修改include/configs/zj2410.h

    #ifndef __CONFIG_H

    #define __CONFIG_H

    /*

    * High Level Configuration Options

    * (easy to change)

    */

    #define CONFIG_ARM920T&#160;1&#160;/* This is an ARM920T Core */

    #define&#160;CONFIG_S3C2410&#160;1&#160;/* in a SAMSUNG S3C2410 SoC&#160;*/

    #define CONFIG_SMDK2410&#160;1&#160;/* on a SAMSUNG SMDK2410 Board&#160;*/

    ……

    ……

    ……

    /*-----------------------------------------------------------------------

    * FLASH and environment organization

    */

    #define CONFIG_AMD_LV400&#160;1&#160;/* uncomment this if you have a LV400 flash */

    #if 0

    #define CONFIG_AMD_LV800&#160;1&#160;/* uncomment this if you have a LV800 flash */

    #endif

    #define CFG_MAX_FLASH_BANKS&#160;1&#160;/* max number of memory banks */

    #ifdef CONFIG_AMD_LV800

    #define PHYS_FLASH_SIZE&#160;0x00100000 /* 1MB */

    #define CFG_MAX_FLASH_SECT&#160;(19) /* max number of sectors on one chip */

    #define CFG_ENV_ADDR&#160;(CFG_FLASH_BASE + 0x0F0000) /* addr of environment */

    #endif

    #ifdef CONFIG_AMD_LV400

    #define PHYS_FLASH_SIZE&#160;0x00080000 /* 512KB */

    #define CFG_MAX_FLASH_SECT&#160;(11) /* max number of sectors on one chip */

    #define CFG_ENV_ADDR&#160;(CFG_FLASH_BASE + 0x070000) /* addr of environment */

    #endif

    /* timeout values are in ticks */

    #define CFG_FLASH_ERASE_TOUT&#160;(5*CFG_HZ) /* Timeout for Flash Erase */

    #define CFG_FLASH_WRITE_TOUT&#160;(5*CFG_HZ) /* Timeout for Flash Write */

    #define&#160;CFG_ENV_IS_IN_FLASH&#160;1

    #define CFG_ENV_SIZE&#160;0x10000&#160;/* Total Size of Environment Sector */

    /*-----------------------------------------------------------------------

    *&#160;NAND FLASH BOOT

    */

    #define&#160;CONFIG_S3C2410_NAND_BOOT&#160;1

    #define&#160;STACK_BASE&#160;0x33f00000

    #define&#160;STACK_SIZE&#160;0x8000

    #define&#160;NAND_CTL_BASE&#160;0x4e000000

    #define&#160;bINT_CTL(Nb)&#160;_REG(INT_CTL_BASE+(Nb))

    #define&#160;oNFCONF&#160;0x00

    #define&#160;oNFCMD&#160;0x04

    #define&#160;oNFADDR&#160;0x08

    #define&#160;oNFDATA&#160;0x0c

    #define&#160;oNFSTAT&#160;0x10

    #define&#160;oNFECC&#160;0x14

    /*-----------------------------------------------------------------------

    * NAND flash settings

    */

    #define NAND_MAX_CHIPS&#160;1

    3. 在board/zj2410/中添加nand_read.c文件:

    #include <config.h>

    #include "linux/mtd/mtd.h"

    #include "linux/mtd/nand.h"

    //#define LARGEPAGE_FLASH

    #define __REGb(x)&#160;(*(volatile unsigned char *)(x))

    #define __REGi(x)&#160;(*(volatile unsigned int *)(x))

    #define NF_BASE&#160;0x4e000000

    #define NFCONF&#160;__REGi(NF_BASE + 0x0)

    #define NFCMD&#160;__REGb(NF_BASE + 0x4)

    #define NFADDR&#160;__REGb(NF_BASE + 0x8)

    #define NFDATA&#160;__REGb(NF_BASE + 0xc)

    #define NFSTAT&#160;__REGb(NF_BASE + 0x10)

    #define BUSY 1

    inline void wait_idle(void) {

    int i;

    while(!(NFSTAT & BUSY))

    for(i=0; i<10; i++);

    }

    #ifndef LARGEPAGE_FLASH

    #define NAND_SECTOR_SIZE&#160;512

    #else

    #define NAND_SECTOR_SIZE&#160;2048

    #endif

    #define NAND_BLOCK_MASK&#160;(NAND_SECTOR_SIZE - 1)

    /* low level nand read function */

    int

    nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)

    {

    int i, j;


    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)){

    //if ((start_addr & NAND_BLOCK_MASK) /*|| (size > SZ_1M)*/) {

    return -1;&#160;/* invalid alignment */

    }


    /* chip Enable */

    NFCONF &= ~0x800;

    for(i=0; i<10; i++);

    for(i=start_addr; i < (start_addr + size);) {

    /* READ0 */

    NFCMD = NAND_CMD_READ0;

    /* Write Address */

    #ifndef LARGEPAGE_FLASH

    NFADDR = i & 0xff;

    NFADDR = (i >> 9) & 0xff;

    NFADDR = (i >> 17) & 0xff;

    NFADDR = (i >> 25) & 0xff;

    #else

    NFADDR = i & 0xff;

    NFADDR = (i >> 8) & 0x07;

    NFADDR = (i >> 11) & 0xff;

    NFADDR = (i >> 19) & 0xff;

    NFADDR = (i >> 27) & 0x3;

    NFCMD = NAND_CMD_READSTART;

    #endif

    wait_idle();

    for(j=0; j < NAND_SECTOR_SIZE; j++) {

    *buf = (NFDATA & 0xff);

    buf++;

    }

    i += NAND_SECTOR_SIZE;

    }


    /* chip Disable */

    NFCONF |= 0x800;&#160;/* chip disable */

    return 0;

    }

    4. 修改board/zj2410/Makefile:

    COBJS&#160;:= smdk2410.o flash.o nand_read.o&#160;//添加nand_read.o

    OK,这边就编译一下,就可以烧到NAND FLASH运行了。
    踩过的脚印

    该用户从未签到

    发表于 2014-2-27 08:03:05 | 显示全部楼层
    消息来自- 美国
    不错,果断收藏!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|数字电视开发网 ( 京ICP备16008897号-5 )

    GMT+8, 2026-6-2 03:02 , Processed in 0.073818 second(s), 23 queries , Gzip On.

    Powered by Discuz! X3.5

    © 2001-2026 Discuz! Team.

    快速回复 返回顶部 返回列表