zoukankan      html  css  js  c++  java
  • 四,移植uboot-支持NOR,NAND 操作

    文档时间:2018-08-11

    交叉编译器:arm-linux-gcc-4.3.2

    Ubuntu版本:16.04

    uboot版本:2013.10

    1,修改代码支持 nor flash 操作

    前面章节已经实现NOR,NAND 启动,但是还不支持nor,nand flash 操作,如下图打印信息所示:

    Flash: ***  failed ***,搜索发现,此段错误信息在第二阶段 board_init_r 函数中,此函数位于 arch/arm/lib/board.c 文件中,代码如下所示:

    #if !defined(CONFIG_SYS_NO_FLASH)
        puts("Flash: ");
    
        flash_size = flash_init();
        if (flash_size > 0) {
    # ifdef CONFIG_SYS_FLASH_CHECKSUM
            print_size(flash_size, "");
            /*
             * Compute and print flash CRC if flashchecksum is set to 'y'
             *
             * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
             */
            if (getenv_yesno("flashchecksum") == 1) {
                printf("  CRC: %08X", crc32(0,
                    (const unsigned char *) CONFIG_SYS_FLASH_BASE,
                    flash_size));
            }
            putc('
    ');
    # else    /* !CONFIG_SYS_FLASH_CHECKSUM */
            print_size(flash_size, "
    ");
    # endif /* CONFIG_SYS_FLASH_CHECKSUM */
        } else {
            puts(failed);
            hang();
        }
    #endif

    从上面代码可以看出,如果nor flash 没有初始化成功,会执行红色部分代码,打印错误信息,陷入死循环,现更改代码,让其继续跑下去,代码更改如下(红色部分为修改代码):

    # endif /* CONFIG_SYS_FLASH_CHECKSUM */
        } else {
            //puts(failed);
            //hang();
            puts("0 KB 
    
    ");
        }

     1)在 jz2440.h 中添加 DEBUG 的定义,使串口打印更多信息

    #define DEBUG

    然后,编译,烧写,串口打印信息如下图所示:

    从图中可以看出已经读出厂家ID,设备ID了,但是不匹配,搜索 JEDEC PROBE 关键字,位于:

    打开 drivers/mtd/cfi_flash.c 文件,定位到1798行,发现该字段位于 flash_detect_legacy 函数中,flash_detect_legacy 函数的调用关系如下:

    board_init_r -> flash_init -> flash_detect_legacy,分析如下代码:

     该函数会进入到 jedec_flash_match(位于drivers/mtd/jedec_flash.c文件中) 函数,打开该文件,定位到jedec_flash_match 函数:

    该函数里会去匹配 jedec_table ,定位到 jedec_table 定义处,发现没有与我们所用nor flash 相匹配的定义,参照所用 nor flash(MT29LV160DB)手册,增加如下代码(红色部分为增加代码):

    static const struct amd_flash_info jedec_table[] = {
         /*MX29LV160DB*/
        {
            .mfr_id        = (u16)MX_MANUFACT,
            .dev_id        = AM29LV160DB,        //0x2249
            .name        = "MX29LV160DB",
            .uaddr        = {
                [1] = MTD_UADDR_0x0555_0x02AA /* 数组[1]表示是16位nor,解锁地址为:0x555,0x2AA */
            },
            .DevSize    = SIZE_2MiB,
            .CmdSet        = P_ID_AMD_STD,
            .NumEraseRegions= 4,                      //4种不同的扇区规格
            .regions    = {
                ERASEINFO(16*1024, 1),
                   ERASEINFO(8*1024, 2),
                   ERASEINFO(32*1024, 1),
                   ERASEINFO(64*1024, 31),
            }
        },

     注释掉 jz2440.h 中定义的 DEBUG 宏,然后编译,烧写到 nor flash,出现如下图所示错误:

    搜索这段字符串,发现该段字符串位于 drivers/mtd/jedec_flash.c 中,打开 jedec_flash.c 文件,定位到这里:

    显然是宏 CONFIG_SYS_MAX_FLASH_SECT 小于我们的扇区数量,才会打印这个错误,修改 CONFIG_SYS_MAX_FLASH_SECT (位于 include/configs/jz2440.h 中):

    #define CONFIG_SYS_MAX_FLASH_SECT    (128)

    重新编译烧写,打印如下信息:

    输入 flinfo 命令,查看 flash 信息,如下图所示:

    通过串口终端输入以下命令,来检查 nor flash 的读写是否满足我们的要求:

    protect off all 
    erase 10000 +7ffff              
    cp.b 30000000 10000 80000             //烧写在另一个位置
    cmp.b 30000000 10000 80000              //比较,是否读写正确

    如果正确,则会打印如下信息:

    2,修改代码,支持 nand flash 操作 

    在修改代码之前先把串口终端名称 SMDK2410 改为 JZ2440,在 include/configs/jz2440.h 中修改,修改代码如下:

    #define CONFIG_SYS_PROMPT    "JZ2440 # "

     在之前的章节中,我们把支持 nand 的宏 CONFIG_CMD_NAND 给屏蔽了,现在取消屏蔽(在 jz2440.h 中),然后添加对2440 nand 宏的支持,修改代码如下:

    #ifdef CONFIG_CMD_NAND
    //#define CONFIG_NAND_S3C2410
    //#define CONFIG_SYS_S3C2410_NAND_HWECC
    #define CONFIG_NAND_S3C2440
    #define CONFIG_SYS_S3C2440_NAND_HWECC

     2410对于nand flash 的支持位于 drivers/mtd/nand/s3c2410_nand.c 中,仿照此文件,编写对2440 nand flash 的支持

    在 Ubuntu 下,输入命令 cp drivers/mtd/nand/s3c2410_nand.c drivers/mtd/nand/s3c2440_nand.c 进行拷贝,然后修改Makefile,如下所示:

    COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
    COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o

     分析 nand 流程:board_init_r -> nand_init -> nand_init_chip -> board_nand_init 和 nand_scan

     1),进入 board_init_r 函数(arch/arm/lib/board.c里)

    2),进入 nand_init 函数(drivers/mtd/nand/nand.c里)

    3),进入 nand_init_chip 函数(drivers/mtd/nand/nand.c里)

     

    调用 board_nand_init 和 nand_scan 函数

    修改 drivers/mtd/nand/s3c2440_nand.c 支持我们所用的nand flash 芯片

    首先将所有带有 2410 的变量 替换为 2440

    然后参考以前裸机 nand 驱动程序或者S3C2440和所用nand 芯片手册修改 nand_board_init 函数,修改代码如下:

        cfg = S3C2440_NFCONF_EN;
        cfg |= S3C2440_NFCONF_TACLS(tacls - 1);
        cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
        cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
        writel(cfg, &nand_reg->nfconf);
        nand_reg->nfcont=(1<<1)|(1<<0); // bit1:关闭片选(),       bit0:开启nand flash 控制器
    
        /* initialize nand_chip data structure */
        nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
        nand->IO_ADDR_W = (void *)&nand_reg->nfdata;
    
        nand->select_chip=s3c2440_select_chip;

     编写 s3c2440_select_chip 函数,代码如下(这里可以参考别的单板的例程):

    static void s3c2440_select_chip(struct mtd_info *mtd, int chipnr)
    {
        struct s3c2440_nand *nand_reg = s3c2440_get_base_nand();
    
        if(chipnr==-1)          //CE Disable
       {
            nand_reg->nfcont|=(0x01<<1);               //bit1置1
       }
        else                         //CE Enable
       {
               nand_reg->nfcont&=~(0x01<<1);        //bit1置0 
       }           
    
    }

    修改  s3c2440_hwcontrol 函数,修改代码如下,(红色为修改部分):

    static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
    {
        struct nand_chip *chip = mtd->priv;
        struct s3c2440_nand *nand = s3c2440_get_base_nand();
    
    
        if (ctrl & NAND_CLE)                 // 传输的是命令
            nand->nfcmd=cmd;  
        else                                // 传输的是地址
            nand->nfaddr=cmd;  
    }

    代码修改完毕,编译,烧写,观察现象:

    nand flash已经识别出来,接下来测试 nand flash 读写是否正确,输入以下命令:

    nand erase 100000 1000                      //擦除
    mw.b 30000000 0x55 1000
    nand write 30000000 100000 1000        //将0x55写入nand
    nand dump 100000 1000        //打印

     如下图所示,读写都没问题

     

    到此为止,uboot 代码已经能够支持 jz2440 nor / nand flash 操作了,下一张移植 DM9000 网卡支持

  • 相关阅读:
    第十一节 1虚拟路径 简单
    第十一节 4Server对象 简单
    第十节 19验证码案例 简单
    第十节 19爆力注册 简单
    第十节 23行删除例子讲解请求处理响应 简单
    第十节 18暴力破解及机器人注册原理 简单
    第十一节 2Request对象 简单
    礼物
    笔记本电脑与漂亮老婆
    一场傻B的晚会
  • 原文地址:https://www.cnblogs.com/zhyy-mango/p/9452034.html
Copyright © 2011-2022 走看看