3.移植uboot-使板卡支持nor、nand

2023-11-01

         

上面的Flash: *** failed *** 是属于uboot第二阶段函数board_init_r()里的代码, 代码如下所示(位于arch/arm/lib/board.c):

复制代码

/*第二阶段*/
void board_init_r(gd_t *id, ulong dest_addr)        //gd    uboot重定位地址
{
     ... ...
  puts("Flash: ");                        //打印flash:
  flash_size = flash_init();                    //初始化nor_flash
  if (flash_size > 0)
  {
       ... ...
       print_size(flash_size, "\n");            //打印nor_flash的大小
  }
  else
  {
    puts(failed);                //打印数组failed[]="*** failed ***\n";
    hang();                        //进入while中,并打印: ### ERROR ### Please RESET the board ###     
  }
#if defined(CONFIG_CMD_NAND)
       puts("NAND:  ");                                      //打印NAND:
       nand_init();                                               //初始化nand_flah
... ...
}

复制代码

从上面代码看出, board_init_r()会来初始化nor,由于新的uboot不支持nor,所以flash_init()初始失败,然后打印一串错误代码后,等待复位.

由于2440在nand启动时,会自动装载nand的前4k内容,所以不支持norflash,因为nor的前4k内容被nand占用.

所以修改上面代码,避免nand启动一直卡住,将:

else
{
  puts(failed);                //打印数组failed[]="*** failed ***\n";
  hang();                        //进入while中,并打印: ### ERROR ### Please RESET the board ###     
}

改为:

else
{
  puts("0  KB\r\n");                //打印0 KB
}

 


1.接下来,下章便来修改代码,使uboot支持读写norflash

1.1首先在include/common.h中添加:

#define DEBUG     //调试模式

然后使用nor启动新的uboot,打印出调试信息:

 

打印出norflash的厂家ID=0xC2,设备ID=0x2249,显然uboot匹配读出的ID没有成功.

搜索JEDEC PROBE字段,找到位于board_init_r()->flash_init()->flash_detect_legacy():

 

 

如上图所示,该函数会进入board_init_r()->flash_init()->flash_detect_legacy()->jedec_flash_match(),里面会通过两个ID来匹配jedec_table[].

 

1.2接下来向jedec_table[]里添加norflash:MT29LV160DB(位于drivers/mtd/jedec_flash.c)

代码如下:

复制代码

     /*MX29LV160DB*/
       {
       .mfr_id         = (u16)MX_MANUFACT,        //厂家ID0x00C200C2 (读nor,便是0xc2)
       .dev_id         = 0x2249,                          //设备ID
       .name           = "MXIC 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),
                          }
           },

复制代码

 

重新烧写看打印信息,出现这么一段ERROR:

ERROR:too many flash sectors

说flash的扇区太多了,搜索找到位于drivers/mtd/jedec_flash.c中:

 

显然是CONFIG_SYS_MAX_FLASH_SECT宏小于我们flash的扇区,所以打印ERROR。

所以修改CONFIG_SYS_MAX_FLASH_SECT宏定义(位于include/configs/smdk2440.h),并去掉之前定义的DEBUG调试宏(位于include/common.h)

1.3然后重新烧写

输入flinfo命令(flash info),就能查看flash的信息了:

 

然后通过uboot命令,检测nor的读写是否正确:

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

2.接下来继续修改代码,使uboot支持NandFlash

2410的NandFlash位于drivers/mtd/nand/s3c2410_nand.c

2.1 首先复制s3c2410_nand.c,改为s3c2440_nand.c

改Makefile,如下图所示:

 

 

2.2 在上一章分析过CONFIG_NAND_S3C2410宏,位于include/configs/smdk2440.h:

 

如上图所示,其中CONFIG_CMD_NAND宏:表示uboot是否支持nand,在上章里,我们把它屏蔽了,接下来便取消屏蔽CONFIG_CMD_NAND宏。

 

2.3继续添加对CONFIG_NAND_S3C2440宏的支持,将:

#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
#define CONFIG_SYS_MAX_NAND_DEVICE  1
#define CONFIG_SYS_NAND_BASE              0x4E000000
#endif

改为:

复制代码

#ifdef CONFIG_CMD_NAND

 
#ifdef CONFIG_S3C2410          
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
#else                                                                   // CONFIG_S3C2440      
#define CONFIG_NAND_S3C2440    
#define CONFIG_SYS_S3C2440_NAND_HWECC
#endif

#define CONFIG_SYS_MAX_NAND_DEVICE      1
#define CONFIG_SYS_NAND_BASE            0x4E000000
#endif

复制代码

由于smdk2410.h中定义的是CONFIG_S3C2410,而smdk2440.h中定义的是CONFIG_S3C2440,所以便会根据上面的#ifdef来动态定义宏

 

2.4 然后来看看nand的流程(和linux的nand驱动有很多相似的地方):

1)uboot重定位后进入第二阶段board_init_r():

复制代码

void board_init_r(gd_t *id, ulong dest_addr)        //gd    uboot重定位地址
{
  ... ...
#if defined(CONFIG_CMD_NAND)                      //需要定义CONFIG_CMD_NAND宏
       puts("NAND:  ");
       nand_init();            /* go init the NAND */
#endif
 ... ...
}

复制代码

 

2)进入nand_init():

复制代码

void nand_init(void)
{
... ...
for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)      //在2.3小节里,该宏为1
nand_init_chip(i);                     
printf("%lu MiB\n", total_nand_size / 1024);
... ...
}

复制代码

 

3)进入nand_init()->nand_init_chip(0):

复制代码

static void nand_init_chip(int i)
{
    struct mtd_info *mtd = &nand_info[i];      //mtd_info属于软件的一部分,实现用户层读写等操作
    struct nand_chip *nand = &nand_chip[i];     //属于底层,保存对nand的硬件相关操作,它是mtd_info结构体的priv私有成员
    ulong base_addr = base_address[i];           //获取nand寄存器基地址,等于0x4E000000
    int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;

    if (maxchips < 1)
           maxchips = 1;

    mtd->priv = nand;     //设置私有成员nand_chip
    ... ...
    if (board_nand_init(nand))                   //位于s3c2440_nand.c,该函数会设置nand_chip结构体的成员
           return;

    if (nand_scan(mtd, maxchips)) //通过mtd->priv来开启nand片选,来获取nand的型号,类型等.并填充mtd结构体下其它的成员.
           return;

    nand_register(i);     //注册nand,使uboot支持对nand的读写操作
}

复制代码

这个nand_chip结构体和我们之前学的linux下的nand驱动章节里的nand_chip一摸一样,流程也非常相似.

 由于在2.1小节里,该函数所在的文件s3c2440_nand.c是从s3c2410_nand.c复制过来的,所以接下来便修改s3c2440_nand.c (位于drivers/mtd/nand目录下)

 

2.5 修改s3c2440_nand.c(参考2410数据手册和2440数据手册)

1)首先将所有带2410字的变量都替换为2440

2)修改board_nand_init()

参考以前写的nand驱动,将

复制代码

   tacls = 4;
    twrph0 = 8;
    twrph1 = 8;
    cfg = S3C2440_NFCONF_EN;                       //启动nand控制器
    cfg |= S3C2440_NFCONF_TACLS(tacls - 1);
    cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
    cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
    writel(cfg, &nand_reg->nfconf); 

复制代码

改为:

    tacls = 0;                      //10ns    
    twrph0 = 1;                  //20ns
    twrph1 = 0;                  //10ns

    nand_reg->nfconf = (tacls<<12) | (twrph0<<8) | (twrph1<<4); //设置时序
    nand_reg->nfcont=(1<<1)|(1<<0); // bit1:关闭片选(),       bit0:开启nand flash 控制器

 

2)添加nand_chip结构体成员

nand->select_chip=s3c2440_select_chip;             //设置CE  

然后并写一个s3c2440_select_chip()函数

复制代码

/*nand flash  :CE */

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

}

复制代码

 

3)屏蔽带硬件ECC的相关操作

将:

复制代码

#ifdef CONFIG_S3C2410_NAND_HWECC
nand->ecc.hwctl = s3c2440_nand_enable_hwecc;
nand->ecc.calculate = s3c2440_nand_calculate_ecc;
nand->ecc.correct = s3c2440_nand_correct_data;
nand->ecc.mode = NAND_ECC_HW;
nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
#else
nand->ecc.mode = NAND_ECC_SOFT;
#endif

复制代码

改为:

nand->ecc.mode = NAND_ECC_SOFT;               //使用软件ECC 

 

2.6 修改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();   //获取nand寄存器地址
     
    if (ctrl & NAND_CLE)                 // 传输的是命令
        nand->nfcmd=cmd;  
    else                                // 传输的是地址
        nand->nfaddr=cmd;  
}

复制代码

 

s3c2440_hwcontrol()函数的ctrl是个标志位:

  • bit[1]==1: 表示要发送的dat是命令
  • bit[2]==1: 表示要发送的dat是地址
  • bit[0]==1:表示使能nand , ==0:表示禁止nand

(PS:具体可以参考内核的nand_command_lp()函数,它会调用这个cmd_crtl函数来实现功能 )

 

2.7编译烧写

如下图所示,可以看到已支持Nand Flash:

 

 

试验nand是否能读写:

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

如下图所示, 可以看到读写nand都没问题

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

3.移植uboot-使板卡支持nor、nand 的相关文章

  • JAVA实现图片质量压缩和加水印

    这个世界没有什么好畏惧的 反正我们只来一次 文章目录 前言 编写代码 1 编写工具类 2 编写接口 3 测试接口 总结 前言 主要实现了两个功能 加水印 质量压缩 编写代码 1 编写工具类 ImageUtil代码如下 package com
  • ceph中的Pools、PGs和OSDs介绍(tmp)

    2019独角兽企业重金招聘Python工程师标准 gt gt gt How are Placement Groups used A placement group PG aggregates objects within a pool be
  • Python-栈结构

    栈 stack 又名堆栈 它是一种运算受限的线性表 栈只能在一端进行插入和删除操作 它按照先进后出 FILO 的原则存储数据 先进入的数据被压入栈底 最后的数据在栈顶 栈也可以看成是 FILO 的队列 class Stack object
  • String类常用方法

    红色为常用的方法 1 和长度有关的方法 得到一个字符串的字符长度 String s abc s length 2 和数组有关的方法 返回类型 方法名 作用 byte getBytes 将一个字符串转换成字节数组 char toCharArr
  • mysql对表中列的操作_mysql对表基本操作

    一 对表的操作 1 添加新的字段 alter table 表名 add name varchar 20 2 删除表中已有的字段 alter table 表名 drop name 3 修改表中已有的字段 alter table 表名 chan

随机推荐

  • js 计算两个日期之间的相差的天数

    将两个日期都转换为毫秒相减后 将减下来的毫秒数转换为天数 就可以得到两个日期之间相差的天数了 接受的日期格式为 2023 1 31 2023 2 28 的日期字符串 const getDaysApart date val date vals
  • ubuntu下jmxtrans 安装

    JAVA 监控内容收集之 Jmxtrans 它是一个为应用程序 设备 系统等管理功能的框架 通常可以用来监控和管理Java应用系统 1 拷贝jmxtrans至LS1上 scp jmxtrans 251 deb LS1 2 安装jmxtran
  • Google Chrome在Windows7安装离线版

    前言 今天因为旧版chrome老是要报更新 所以安装了个新版 因为被墙原因 许多网友会遇到一些安装chrome的问题 所以今天分享一下安装教程 安装chrome 1 前往chrome官网 可以看到链接地址是http www google c
  • 如何构造测试数据

    前言 我这里只是专注于生成CSV等测试数据文件 每次构造测试数据的时候就很头疼 之前自己简单造个两三行还行 造多了就有些费脑细胞了 抽出些时间来专门找一下有没有相应工具 小数据量测试数据 小数据量测试数据使用在线的网站就行 10W以内的数据
  • 【Python】使用Python根据BV号爬取对应B站视频下的所有评论(包括评论下的回复)

    Python 使用Python根据BV号爬取对应B站视频下的所有评论 包括评论下的回复 本文写于2020 4 27 当你阅读到本文的时候如果因为下列原因导致本文代码无法正常工作 本人概不负责 B站的页面和API接口的变动 B站为页面和API
  • 操作系统笔记(手写)

    前言 这学期开始学习计算机网络 操作系统和Java程序设计 这些课的重要性不言而喻 对于我这种纯粹的小白来说 压力真得很大 自己水平有限 领悟能力较差 学习接受能力很慢 不知道怎样才能真真的学懂 学会这些东西 所以就先跟着学校安排的网课和配
  • 常见的数据结构与算法

    文章目录 前言 一 常见的数据结构 1 数组 2 链表 3 栈 4 队列 5 树 二 排序 1 基本的排序算法 2 常考的排序算法 3 其他排序算法 三 递归与回溯 1 递归 2 回溯 四 深度与广度优先搜索 1 深度优先搜索 2 广度优先
  • 伴随矩阵介绍及C++实现

    在线性代数中 一个方形矩阵的伴随矩阵是一个类似于逆矩阵的概念 如果矩阵可逆 那么它的逆矩阵和它的伴随矩阵之间只差一个系数 然而 伴随矩阵对不可逆的矩阵也有定义 并且不需要用到除法 设R是一个交换环 在抽象代数之分支环论中 一个交换环 com
  • 【vue】vue子孙组件传值(多级嵌套)attrs listeners

    如果vue开发遇到多层嵌套 子孙组件之间传值 可以使用 attrs listeners传值 示例如下 孙子组件
  • 装上这10个插件,PyCharm才是无敌的存在

    pycharm是一款强大的python集成开发环境 带有一整套python开发工具 今天就给大家介绍几款非常好用的插件 首先插件的下载方法 进入File gt Settings gt Plugins 根据需要搜索插件名称 记得是在Marke
  • db是哪个城市的缩写_全国所有城市拼音及缩写

    北京 BEIJING BJ 上海 SHANGHAI SH 天津 TIANJIN TJ 重庆 CHONGQING ZQ 阿克苏 AKESU AKS 安宁 ANNING AN 安庆 ANQING AQ 鞍山 ANSHAN AS 安顺 ANSHU
  • 分享一款开源堡垒机-jumpserver

    JumpServer是由FIT2CLOUD 飞致远 公司旗下一款开源的堡垒机 这款也是全球首款开源的堡垒机 使用 GNU GPL v2 0 开源协议 是符合 4A 规范的运维安全审计系统 使用 Python 开发 遵循 Web 2 0 规范
  • java basefont_itext 文本域 字体样式设置

    使用acroFields setFieldProperty nameField textfont baseFont null 的方式不能加粗 因为第三个参数必须是BaseFont类型 不能是Font类型 可以使用下面的方式加粗 BaseFo
  • 判断环形链表是否有环??返回环形链表的入口点!!

    上次笔者写了一篇大概有7个题的链表相关的题目 解析 感觉还不错 感兴趣的各位老铁 可以点一下链接进行欣赏 做几个与链表相关的题吧 https blog csdn net weixin 64308540 article details 128
  • 牧师与魔鬼 -- version2 动作分离

    目录 一 基本操作演练 1 下载 Fantasy Skybox FREE 构建自己的游戏场景 2 写一个简单的总结 总结游戏对象的使用 二 编程实践 1 牧师与魔鬼 动作分离版 面向对象的游戏编程 动作管理器的设计思想 动作管理器的设计类图
  • 【LeetCode算法系列题解】第21~25题

    CONTENTS LeetCode 21 合并两个有序链表 简单 LeetCode 22 括号生成 中等 LeetCode 23 合并K个升序链表 困难 LeetCode 24 两两交换链表中的节点 中等 LeetCode 25 K 个一组
  • 2018.1.22-2018.(几年前帖子,私密变公开后时间就变了)

    成为全职程序员 每天9点至17 50 中午11 30 13 00休息 不过我逐渐加班 第一天没加班 第二天加班一小时 第三天2小时 第4天3小时 编译了CGAL OPENCV PCL BOOST等 CGAL的LEDA库没法用 PCL读取点云
  • 【全文检索】sqlite-fts4和pgsql的全文检索对比

    sqlite fts4和pgsql的全文检索对比 一 sqlite fts4 建表语句 插入数据 全文检索 前缀查询 数据更新 二 postgreSQL 全文检索 建表语句 to tsvector 和to tsquery 构建索引 查询结果
  • 正则表达式常用参数

    正则表达式中常用的模式修正符有i g m s U x a D e 等 它们之间可以组合搭配使用 i 不区分 ignore 大小写 例如 abc i 可以匹配 abc aBC Abc g 全局 global 匹配 如果不带g 正则过程中字符串
  • 3.移植uboot-使板卡支持nor、nand

    在上一章 我们添加了nor nand启动后 uboot启动出如下图所示 上面的Flash failed 是属于uboot第二阶段函数board init r 里的代码 代码如下所示 位于arch arm lib board c 第二阶段 v