zoukankan      html  css  js  c++  java
  • ok6410 u-boot-2012.04.01移植六完善MLC NAND支持

    继ok6410 u-boot-2012.04.01移植四、五后,开发板基本已支持MLC NAND,支持DM9000.但是通过NAND命令更新u-boot到NAND,还存在问题,需要根据u-boot的nand命令继续修改,最终实现通过网卡tftp程序到内存,接着通过NAND命令写到NAND。

    开发环境:
    系统:ubuntu 10.04.4
    单板:ok6410
    NAND FLASH:K9GAG08U0D 2048MB
    NOR Flash:EN29LV160AB 2MB
    DDR:K4X1G163PCX2 256MB
    NET:DM9000AEP
    编译器:arm-linux-gcc-4.3.2
    搭建开发环境详见ubuntu 10.04.4开发环境配置。
    目标:
    1.板级初始化,支持单板ok6410
    2.修改u-boot,支持NAND启动
    3.增加菜单update功能
    4.增加MLC NAND支持
    5.支持DM9000,网卡下载程序
    6.修改环境变量以及mtdpart分区
    7.u-boot裁剪及制作补丁

    一、配置K9GAG08U0D,支持MLC NAND

    主要是在头文件中配置MLC NAND的PAGE_SIZE、BLOCK_SIZE、OOBSIZE等,这些在K9GAG08U0D的芯片手册中都能找到

    修改includeconfigssmdk6410.h 主要是修改/* NAND configuration */配置,从上往下开始

    #define CONFIG_SYS_NAND_U_BOOT_SIZE(512 * 1024)//(252 * 1024)/* Size of RAM U-Boot image   */

    #define CONFIG_SYS_NAND_PAGE_SIZE4096//2048

    #define CONFIG_SYS_NAND_BLOCK_SIZE(512 * 1024)

    #define CONFIG_SYS_NAND_PAGE_COUNT128

    #define CONFIG_SYS_NAND_OOBSIZE218//64

    二、根据nand命令修改

    上一节使用SMDK6410 # nand write 0x50000000 0 0x80000,写成功后重启发现u-boot跑步起来,那就根据这个命令一步步往下修改。从cmd_nand.c开始分析

    int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])//在这里面几乎实现了nand的所有命令,这里以分析nand write 为例

    if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {//nand write 0x50000000 0 0x80000 

    //在下面你会看到很多nand. write.e/write.jffs2之类的,以前总有人问这些命令区别,这里自己分析一下就知道了

    ret = nand_write_skip_bad(nand, off, &rwsize,  (u_char *)addr, 0);
    rval = nand_write (nand, offset, length, buffer);

    ret = nand_do_write_ops(mtd, to, &chip->ops);

    ret = chip->write_page(mtd, chip, wbuf, page, cached,
          (ops->mode == MTD_OOB_RAW));
    //chip->write_page = nand_write_page;

    static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
      const uint8_t *buf, int page, int cached, int raw)

    nand write大概流程就这样,下面重点修改代码。其实有个很重要的问题,在s3c6410手册有提到6410中nand里面的最开始的前4页,NAND pagesize刚好2K没关系,如果pagesize大于2K就需要注意,因为前4页不管pagesize多大,每页只能写头2K的数据,意识到这个问题就好改了。下面修改代码drivers/mtd/nand/nand_base.c

    在static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,struct mtd_oob_ops *ops)增加如下宏定义

    #if defined(CONFIG_NAND_BL1_8BIT_ECC) && (defined(CONFIG_S3C6410) || defined(CONFIG_S3C6430) || defined(CONFIG_S3C2450) || defined(CONFIG_S3C2416))
    if (page < 16) {
    s3c_nand_read_page_8bit(mtd, chip, bufpoi);
    } else {
    if (unlikely(ops->mode == MTD_OOB_RAW))
    ret = chip->ecc.read_page_raw(mtd, chip, bufpoi);
    else
    ret = chip->ecc.read_page(mtd, chip, bufpoi);
    }
    #else
    /* Now read the page into the buffer */
    if (unlikely(ops->mode == MTD_OOB_RAW))
    ret = chip->ecc.read_page_raw(mtd, chip,
         bufpoi, page);
    else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
    ret = chip->ecc.read_subpage(mtd, chip,
    col, bytes, bufpoi);
    else{
    //printf ("chip->ecc.read_page started:ret = %d page = %d bytes = %d ",ret,page,bytes);//add test
    ret = chip->ecc.read_page(mtd, chip, bufpoi,
     page);
    //printf ("chip->ecc.read_page finished ");//add test
    }
    //printf ("ret value:%d ",ret);//add test
    #endif

    同时在smdk6410.h38:增加

     #define CONFIG_S3C64101/* in a SAMSUNG S3C6400 SoC     */
     #define CONFIG_SMDK64101/* on a SAMSUNG SMDK6400 Board  */
    修改static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,  const uint8_t *buf, int page, int cached, int raw)//增加宏

    #if defined(CONFIG_NAND_BL1_8BIT_ECC) && (defined(CONFIG_S3C6410) || defined(CONFIG_S3C6430) || defined(CONFIG_S3C2450) || defined(CONFIG_S3C2416))
    memset(chip->oob_poi, 0xff, mtd->oobsize);


    if (page < 16) {
    s3c_nand_write_page_8bit(mtd, chip, buf);
    } else {
    if (unlikely(raw))
    chip->ecc.write_page_raw(mtd, chip, buf);
    else
    chip->ecc.write_page(mtd, chip, buf);
    }
    #else


    if (unlikely(raw))
    chip->ecc.write_page_raw(mtd, chip, buf);
    else
    chip->ecc.write_page(mtd, chip, buf);
    #endif

    接着重点来了修改static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,struct mtd_oob_ops *ops)

    if (!writelen)
    break; //在后面添加

    column = 0;
    //buf += bytes;
    if (page <4)
    {
    buf +=(bytes/2);
    printf("page = %d ",page);
    printf("buf = %d ",buf);
    }
    else
    buf += bytes;
    realpage++;
    //下面不变
    page = realpage & chip->pagemask;
    /* Check, if we cross a chip boundary */
    if (!page) {
    chipnr++;
    chip->select_chip(mtd, -1);
    chip->select_chip(mtd, chipnr);
    }
        

    先编译试试,不行再修改。

    三、编译、测试

    change@change:/si/OK6410/u-boot-2012.04.01$ make

    编译OK。下面测试程序,还是老方法烧·程序。将上面生成的u-boot.bin拷到sd卡,接着拨到sd卡启动

    U-Boot 1.1.6 (Dec 15 2010 - 09:02:39) for SMDK6410


    ****************************************
    **    u-boot 1.1.6                    **
    **    Updated for TE6410 Board        **
    **    Version 1.0 (10-01-15)          **
    **    OEM: Forlinx Embedded           **
    **    Web: http://www.witech.com.cn   **
    ****************************************


    CPU:     S3C6410 @532MHz
             Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode) 
    Board:   SMDK6410
    DRAM:    128 MB
    Flash:   0 kB
    NAND:    tmp = 29
    select s3c_nand_oob_mlc_128
    2048 MB 
    SD/MMC:  1904 MB 
    *** Warning - bad CRC or moviNAND, using default environment

    In:      serial
    Out:     serial
    Err:     serial
    Hit any key to stop autoboot:  0 

    NAND erase: device 0 whole chip
    Skipping bad block at  0x00800000                                            
    Skipping bad block at  0x0e400000                                            
    Skipping bad block at  0x0e780000                                            
    Skipping bad block at  0x13b80000                                            
    Skipping bad block at  0x27a80000                                            
    Skipping bad block at  0x7e280000                                            
    Erasing at 0x7ff80000 -- 100% complete.
    OK
    reading u-boot.bin

    228872 bytes read

    NAND write: device 0 offset 0x0, size 0x100000
     1032192 bytes written: OK
    reading zImage

    ** Unable to read "zImage" from mmc 0:1 **

    烧写OK,拨到NAND启动,输出如下:

    U-Boot 2012.04.01 (Jul 07 2013 - 22:54:07) for SMDK6400
    SMDK6410 # 


    CPU:     S3C6400@532MHz
             Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 
    Board:   SMDK6400
    DRAM:  128 MiB
    WARNING: Caches not enabled
    Flash: 0 KB
    NAND:  select s3c_nand_oob_mlc_64
    NAND_ECC_NONE selected by board driver. This is not recommended !!
    2048 MiB
    *** Warning - bad CRC, using default environment


    In:    serial
    Out:   serial
    Err:   serial
    Net:   dm9000
    Hit any key to stop autoboot:  0 


    ##### Update menu for ok6410 #####
    [g] get file, and write to nand flash 0 block
    [b] Boot the system
    [r] Reset the u-boot
    [q] Quit from menu
    Enter your selection: q
    SMDK6410 # ping 192.168.1.109
    dm9000 i/o: 0x18000000, id: 0x90000a46 
    DM9000: running in 16 bit mode
    MAC: 00:0c:29:4d:e4:f4
    could not establish link
    Using dm9000 device
    host 192.168.1.109 is alive
    SMDK6410 # tftp 0x50000000 u-boot.bin
    dm9000 i/o: 0x18000000, id: 0x90000a46 
    DM9000: running in 16 bit mode
    MAC: 00:0c:29:4d:e4:f4
    could not establish link
    Using dm9000 device
    TFTP from server 192.168.1.109; our IP address is 192.168.1.111
    Filename 'u-boot.bin'.
    Load address: 0x50000000
    Loading: T T T T T 
    Abort
    SMDK6410 # tftp 0x50000000 u-boot.bin
    dm9000 i/o: 0x18000000, id: 0x90000a46 
    DM9000: running in 16 bit mode
    MAC: 00:0c:29:4d:e4:f4
    operating at 100M full duplex mode
    Using dm9000 device
    TFTP from server 192.168.1.109; our IP address is 192.168.1.111
    Filename 'u-boot.bin'.
    Load address: 0x50000000
    Loading: ################
    done
    Bytes transferred = 228872 (37e08 hex)
    SMDK6410 # nand erase 0 0x80000


    NAND erase: device 0 offset 0x0, size 0x80000
    Erasing at 0x0 -- 100% complete.
    OK
    SMDK6410 # nand write 0x50000000 0 0x80000


    NAND write: device 0 offset 0x0, size 0x80000
    page = 0
    buf = 1342179328
    page = 1
    buf = 1342181376
    page = 2
    buf = 1342183424
    page = 3
    buf = 1342185472
     524288 bytes written: OK
    SMDK6410 # reset
    resetting ...


    U-Boot 2012.04.01 (Jul 07 2013 - 22:54:07) for SMDK6400




    CPU:     S3C6400@532MHz
             Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 
    Board:   SMDK6400
    DRAM:  128 MiB
    WARNING: Caches not enabled
    Flash: 0 KB
    NAND:  select s3c_nand_oob_mlc_64
    NAND_ECC_NONE selected by board driver. This is not recommended !!
    2048 MiB
    *** Warning - bad CRC, using default environment


    In:    serial
    Out:   serial
    Err:   serial
    Net:   dm9000
    Hit any key to stop autoboot:  0 


    ##### Update menu for ok6410 #####
    [g] get file, and write to nand flash 0 block
    [b] Boot the system
    [r] Reset the u-boot
    [q] Quit from menu
    Enter your selection: q
    SMDK6410 # 

    通过上面测试,将u-boot.bin通过tftp命令tftp 0x50000000 u-boot.bin放到内存,再用nand write 0x50000000 0 0x80000,烧写完毕重启,刚刚烧写的u-boot跑起来了。目的:通过网卡tftp程序到内存,接着通过NAND命令写到NAND实现。现在的u-boot还不够完善,下一步修改环境变量进一步完善移植的u-boot。



  • 相关阅读:
    uva11729
    1.RabbitMQ介绍
    4.RabbitMQ Linux安装
    3.RabbitMQ 第一个程序
    2.RabbitMQ Window环境安装
    hdu 1757 A Simple Math Problem 矩阵快速幂
    hdu2222 Keywords Search AC自动机
    hdu 2159 二维完全背包
    POJ 3449 Geometric Shapes 判断多边形相交
    POJ 2826 An Easy Problem? 判断线段相交
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3177690.html
Copyright © 2011-2022 走看看