基于U-BOOT-2010.09移植OK6410开发版记录(三)

来源:互联网 发布:fgo卡牌美型 知乎 编辑:程序博客网 时间:2024/06/08 14:37

搬移BL2代码

在完成了BL1部分的初始化后,start.S会跳转到nand_spl/board/samsung/smdk6410/nand_boot.c 中的nand_boot函数,将NAND中BL2阶段的代码复制到RAM中。不过原版的nand_boot函数跟OK6410的NAND无法兼容,搬移功能不可用。本想修改一下的,但是没深入学习过NAND,ECC校检部分实在没看懂…所以就把OK6410原版中的搬移代码拿过来用好了。

添加nand_cp.c文件

在OK6410原版1.1.6uboot代码的\cpu\s3c64xx目录下找到nand_cp.c文件,拷贝到nand_spl/board/samsung/smdk6410/下。修改Makefile,添加新的编译目标:
COBJS = nand_boot.o nand_ecc.o s3c64xx.o nand_cp.o

这个原版的拷贝代码是直接写死了拷贝区域,需要进行修改使其达到可以按照NAND基地址,RAM基地址文件,拷贝大小三个参数进行传参的。代码如下:

#include <common.h>#include <asm/io.h>#include <linux/mtd/nand.h>#include <asm/arch/s3c6410.h>/* * address format *              17 16         9 8            0 * -------------------------------------------- * | block(12bit) | page(5bit) | offset(9bit) | * -------------------------------------------- */ #define NAND_DISABLE_CE()  (NFCONT_REG |= (1 << 1))#define NAND_ENABLE_CE()    (NFCONT_REG &= ~(1 << 1))#define NF_TRANSRnB()       do { while(!(NFSTAT_REG & (1 << 0))); } while(0)static int nandll_read_page (uchar *buf, ulong addr, int large_block){    int i;    int page_size = 512;    if (large_block==1)        page_size = 2048;    if (large_block==2)        page_size = 4096;    if(large_block==3)        page_size = 8192;    NAND_ENABLE_CE();    NFCMD_REG = NAND_CMD_READ0;    /* Write Address */    NFADDR_REG = 0;    if (large_block)        NFADDR_REG = 0;    NFADDR_REG = (addr) & 0xff;    NFADDR_REG = (addr >> 8) & 0xff;    NFADDR_REG = (addr >> 16) & 0xff;    if (large_block)        NFCMD_REG = NAND_CMD_READSTART;    NF_TRANSRnB();    /* for compatibility(2460). u32 cannot be used. by scsuh */    for(i=0; i < page_size; i++) {        *buf++ = NFDATA8_REG;    }    NAND_DISABLE_CE();    return 0;}/* * Read data from NAND. */static int nandll_read_blocks (ulong nand_addr, ulong dst_addr, ulong size, int large_block){    uchar *buf = (uchar *)dst_addr;    int i, nand_kb;    uint page_shift = 9;    if (large_block==1)        page_shift = 11;    if(large_block==2)        page_shift = 12;    if(large_block==3)        page_shift =13;   nand_kb= nand_addr / 1024;    if(large_block == 2)    {    if(nand_kb < 8) //要读取的NAND地址小于8K       {     /* Read pages */            for (i = nand_kb/2; i < 4; i++, buf+=(1<<(page_shift-1))) {                nandll_read_page(buf, i, large_block);            }        /* Read pages */            for (i = 4; i < (size>>page_shift); i++, buf+=(1<<page_shift)) {                nandll_read_page(buf, i, large_block);            }    }    else    {        /* Read pages */            for (i = 4+(nand_kb-8)/4; i < (size>>page_shift); i++, buf+=(1<<page_shift)) {                nandll_read_page(buf, i, large_block);            }    }    }else if(large_block == 3)  //K9GAG08U0E    {        /* Read pages */        for (i = 0; i < 4; i++, buf+=(1<<(page_shift-2))) {            nandll_read_page(buf, i, large_block);        }        /* Read pages */        for (i = 4; i < (size>>page_shift); i++, buf+=(1<<page_shift)) {            nandll_read_page(buf, i, large_block);        }    }    else    {        for (i = 0; i < (size>>page_shift); i++, buf+=(1<<page_shift)) {            nandll_read_page(buf, i, large_block);        }    }    return 0;}int copy_uboot_to_ram (unsigned int nand_start, unsigned int ddr_start, unsigned int len){    int large_block = 0;    int i;    vu_char id;    NAND_ENABLE_CE();    NFCMD_REG=NAND_CMD_RESET;    NF_TRANSRnB();    NFCMD_REG = NAND_CMD_READID;    NFADDR_REG =  0x00;    NF_TRANSRnB();    /* wait for a while */    for (i=0; i<200; i++);    int factory = NFDATA8_REG;    id = NFDATA8_REG;    int cellinfo=NFDATA8_REG;    int tmp= NFDATA8_REG;    //int childType=tmp & 0x03; //Page size    int childType=cellinfo; //Page size    if (id > 0x80)    {        large_block = 1;    }    if(id == 0xd5 && childType==0x94 )//K9GAG08U0D    {        large_block = 2;    }    if(id == 0xd5 && childType==0x14 )//K9GAG08U0M    {        large_block = 2;    }    if(id == 0xd5 && childType==0x84 )//K9GAG08U0E    {        large_block = 3;    }    if(id==0xd7)//K9LBG08U0D    {        large_block = 2;    }    if(factory==0x2c && id == 0x48) //MT29F16G08ABACAWP    {        large_block = 2;    }if(factory==0x2c && id == 0x38) //MT29F8G08ABABAWP    {        large_block = 2;    }   //smdk6410 1G+256M版本 large_block = 2;    /* read NAND Block. 0x3c000   */    return nandll_read_blocks(nand_start, ddr_start, len, large_block);}#if 1#define REG_GPFCON       (0x7F0080A0)#define REG_GPFDAT       (0x7F0080A4)void beep(void){    uint reg_f_cfg=readl(REG_GPFCON) & 0x3FFFFFFF | (1<<30);    writel(reg_f_cfg,REG_GPFCON);    uint reg_f_on=readl(REG_GPFDAT) & 0xFFFF7FFF | (1<<15);    uint reg_f_off=readl(REG_GPFDAT) & 0xFFFF7FFF;    writel(reg_f_on,REG_GPFDAT);}#elsevoid  beep(void){}#endif

修改nand_boot.c文件

修改完nand的拷贝函数后,将nand_boot.c文件中原来的启动代码:

ret = nand_load(&nand_info, CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE,     (uchar *)CONFIG_SYS_NAND_U_BOOT_DST);#ifdef CONFIG_NAND_ENV_DSTnand_load(&nand_info, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,          (uchar *)CONFIG_NAND_ENV_DST);#endif

替换为:

copy_uboot_to_ram(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_DST,        CONFIG_SYS_NAND_U_BOOT_SIZE);#ifdef CONFIG_NAND_ENV_DSTcopy_uboot_to_ram(CONFIG_ENV_OFFSET, CONFIG_NAND_ENV_DST,        CONFIG_ENV_SIZE);#endif

同时在lowleveinit.S和cpu_init.S中NAND初始化部分按照原版1.1.6的初始代码修改对应smdk6410.h中的宏。

重新编译后,烧录u-boot-nand.bin到开发版上,重启后就可以看见串口输出了。


存在缺陷

虽然串口终于有打印了,但还存在很多缺陷:

  • 默认是cs8900的网卡驱动,需要移植OK6410使用DM9000网卡驱动
  • nand虽然已能正常搬移,但是进入BL2后使用的仍是默认的NAND驱动,无法操作NAND,需要进一步修改
  • 暂未添加zImage支持,无法引导zImage的Linux镜像
0 0
原创粉丝点击